From fbc65a02ca4af661c2f1f3f31080474fa66ffc7a Mon Sep 17 00:00:00 2001 From: "Shyam Gupta (DevDiv)" Date: Tue, 24 Feb 2026 15:33:23 -0800 Subject: [PATCH 1/3] Issue: Analyzer tests are running into OutOfMemory exceptions on x86 platform. This is because multiple Roslyn compilations are held into memory which causes memory usage to shoot up before GC gets a chance to collect the finalized objects. On x86 the memory space is 2 GB which runs into OOM. This issue doesn't repro on x64 or when these tests are executed locally in isolation. Fix: To run GC.Collect after every test iteration. --- .../TestUtilities/XUnit/ForceGCAttribute.cs | 23 + ...PassingTaskWithoutCancellationTokenTest.cs | 1 + ...ertySerializationDiagnosticAnalyzerTest.cs | 1 + .../WFO1001/ImplementITypedDataObjectTests.cs | 1 + .../ApplicationConfigurationGeneratorTests.cs | 1 + ...assingTaskWithoutCancellationTokenTests.vb | 259 +++++------ ...ySerializationConfigurationAnalyzerTest.vb | 427 +++++++++--------- .../WFO1001/ImplementITypedDataObjectTests.vb | 263 +++++------ 8 files changed, 503 insertions(+), 473 deletions(-) create mode 100644 src/Common/tests/TestUtilities/XUnit/ForceGCAttribute.cs diff --git a/src/Common/tests/TestUtilities/XUnit/ForceGCAttribute.cs b/src/Common/tests/TestUtilities/XUnit/ForceGCAttribute.cs new file mode 100644 index 00000000000..709d31f11a1 --- /dev/null +++ b/src/Common/tests/TestUtilities/XUnit/ForceGCAttribute.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Reflection; +using Xunit.v3; + +namespace Xunit; + +/// +/// Apply this attribute to a test class or method to force a full GC collection +/// after each test. This helps prevent in x86 +/// test runs where memory-intensive operations (e.g. Roslyn compilations) accumulate. +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] +public sealed class ForceGCAttribute : BeforeAfterTestAttribute +{ + public override void After(MethodInfo methodUnderTest, IXunitTest test) + { + GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true); + GC.WaitForPendingFinalizers(); + GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true); + } +} diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/AvoidPassingTaskWithoutCancellationToken/AvoidPassingTaskWithoutCancellationTokenTest.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/AvoidPassingTaskWithoutCancellationToken/AvoidPassingTaskWithoutCancellationTokenTest.cs index 0e11204107b..2296113f4a9 100644 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/AvoidPassingTaskWithoutCancellationToken/AvoidPassingTaskWithoutCancellationTokenTest.cs +++ b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/AvoidPassingTaskWithoutCancellationToken/AvoidPassingTaskWithoutCancellationTokenTest.cs @@ -9,6 +9,7 @@ namespace System.Windows.Forms.Analyzers.Tests; +[ForceGC] public sealed class AvoidPassingTaskWithoutCancellationTokenTests { private const string TestCode = """ diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/MissingPropertySerializationConfiguration/ControlPropertySerializationDiagnosticAnalyzerTest.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/MissingPropertySerializationConfiguration/ControlPropertySerializationDiagnosticAnalyzerTest.cs index 320640c4e83..604681cc162 100644 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/MissingPropertySerializationConfiguration/ControlPropertySerializationDiagnosticAnalyzerTest.cs +++ b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/MissingPropertySerializationConfiguration/ControlPropertySerializationDiagnosticAnalyzerTest.cs @@ -9,6 +9,7 @@ namespace System.Windows.Forms.Analyzers.Tests; +[ForceGC] public sealed class ControlPropertySerializationDiagnosticAnalyzerTest { private const string GlobalUsingCode = """ diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/WFO1001/ImplementITypedDataObjectTests.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/WFO1001/ImplementITypedDataObjectTests.cs index ff9d2f955f8..6db44bb1018 100644 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/WFO1001/ImplementITypedDataObjectTests.cs +++ b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Analyzers/WFO1001/ImplementITypedDataObjectTests.cs @@ -9,6 +9,7 @@ namespace System.Windows.Forms.Analyzers.Tests; +[ForceGC] public sealed class ImplementITypedDataObjectTests { private const string DiagnosticId = DiagnosticIDs.ImplementITypedDataObject; diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Generators/ApplicationConfigurationGenerator/ApplicationConfigurationGeneratorTests.cs b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Generators/ApplicationConfigurationGenerator/ApplicationConfigurationGeneratorTests.cs index f1ff92d13b6..89f615754f6 100644 --- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Generators/ApplicationConfigurationGenerator/ApplicationConfigurationGeneratorTests.cs +++ b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/Generators/ApplicationConfigurationGenerator/ApplicationConfigurationGeneratorTests.cs @@ -11,6 +11,7 @@ namespace System.Windows.Forms.Analyzers.Tests; +[ForceGC] public partial class ApplicationConfigurationGeneratorTests { private const string SourceCompilable = """ diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb index 257bd72a49a..e445a23cedb 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb @@ -1,129 +1,130 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Collections.Immutable -Imports System.IO -Imports System.Windows.Forms.Analyzers.Diagnostics -Imports System.Windows.Forms.VisualBasic.Analyzers.AvoidPassingTaskWithoutCancellationToken -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.Testing -Imports Microsoft.CodeAnalysis.VisualBasic.Testing -Imports Xunit - -Public Class AvoidPassingTaskWithoutCancellationTokenTests - - Private Const TestCode As String = " -Imports System -Imports System.Threading -Imports System.Threading.Tasks -Imports System.Windows.Forms - -Namespace VisualBasicControls - - Public Module Program - - Public Sub Main() - - Dim control As New Control() - - ' A sync Action delegate is always fine. - Dim okAction As New Action(Sub() control.Text = ""Hello, World!"") - - ' A sync Func delegate is also fine. - Dim okFunc As New Func(Of Integer)(Function() 42) - - ' Just a Task we will get in trouble since it's handled as a fire and forget. - Dim notOkAsyncFunc As New Func(Of Task)(Function() - control.Text = ""Hello, World!"" - Return Task.CompletedTask - End Function) - - ' A Task returning a value will also get us in trouble since it's handled as a fire and forget. - Dim notOkAsyncFunc2 As New Func(Of Task(Of Integer))(Function() - control.Text = ""Hello, World!"" - Return Task.FromResult(42) - End Function) - - ' OK. - Dim task1 = control.InvokeAsync(okAction) - - ' Also OK. - Dim task2 = control.InvokeAsync(okFunc) - - ' Concerning. - Most likely fire and forget by accident. We should warn about this. - Dim task3 = control.InvokeAsync(notOkAsyncFunc, System.Threading.CancellationToken.None) - - ' Again: Concerning. - Most likely fire and forget by accident. We should warn about this. - Dim task4 = control.InvokeAsync(notOkAsyncFunc, System.Threading.CancellationToken.None) - - ' And again concerning. - We should warn about this, too. - Dim task5 = control.InvokeAsync(notOkAsyncFunc2, System.Threading.CancellationToken.None) - - ' This is OK, since we're passing a cancellation token. - Dim okAsyncFunc = New Func(Of CancellationToken, ValueTask)(Function(cancellation) - control.Text = ""Hello, World!"" - Return ValueTask.CompletedTask - End Function) - - ' This is also OK, again, because we're passing a cancellation token. - Dim okAsyncFunc2 = New Func(Of CancellationToken, ValueTask(Of Integer))(Function(cancellation) - control.Text = ""Hello, World!"" - Return ValueTask.FromResult(42) - End Function) - - ' And let's test that, too: - Dim task6 = control.InvokeAsync(okAsyncFunc, System.Threading.CancellationToken.None) - - ' And that, too: - Dim task7 = control.InvokeAsync(okAsyncFunc2, System.Threading.CancellationToken.None) - - End Sub - - End Module - -End Namespace - -" - - Public Shared Iterator Function GetReferenceAssemblies() As IEnumerable(Of Object()) - Yield { - ReferenceAssemblies.Net.Net90.AddPackages( - ImmutableArray.Create(New PackageIdentity("Microsoft.WindowsDesktop.App.Ref", "9.0.0")) - ), "" - } - ' The latest public API surface area build from this repository. - Yield {CurrentReferences.NetCoreAppReferences, CurrentReferences.WinFormsRefPath} - End Function - - - - - Public Async Function VB_AvoidPassingFuncReturningTaskWithoutCancellationAnalyzer(referenceAssemblies As ReferenceAssemblies, pathToWinFormsAssembly As String) As Task - Assert.NotNull(referenceAssemblies) - Assert.NotNull(pathToWinFormsAssembly) - Assert.True(pathToWinFormsAssembly = "" Or File.Exists(pathToWinFormsAssembly)) - - Dim diagnosticId As String = DiagnosticIDs.AvoidPassingFuncReturningTaskWithoutCancellationToken - - Dim context As New VisualBasicAnalyzerTest(Of AvoidPassingTaskWithoutCancellationTokenAnalyzer, DefaultVerifier) With - { - .TestCode = TestCode, - .ReferenceAssemblies = referenceAssemblies - } - - context.TestState.OutputKind = OutputKind.WindowsApplication - context.TestState.ExpectedDiagnostics.AddRange( - { - DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(40, 25, 40, 101), - DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(43, 25, 43, 101), - DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(46, 25, 46, 102) - }) - - If pathToWinFormsAssembly <> "" Then - context.TestState.AdditionalReferences.Add(pathToWinFormsAssembly) - End If - - Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) - End Function - -End Class +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.Collections.Immutable +Imports System.IO +Imports System.Windows.Forms.Analyzers.Diagnostics +Imports System.Windows.Forms.VisualBasic.Analyzers.AvoidPassingTaskWithoutCancellationToken +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Testing +Imports Microsoft.CodeAnalysis.VisualBasic.Testing +Imports Xunit + + +Public Class AvoidPassingTaskWithoutCancellationTokenTests + + Private Const TestCode As String = " +Imports System +Imports System.Threading +Imports System.Threading.Tasks +Imports System.Windows.Forms + +Namespace VisualBasicControls + + Public Module Program + + Public Sub Main() + + Dim control As New Control() + + ' A sync Action delegate is always fine. + Dim okAction As New Action(Sub() control.Text = ""Hello, World!"") + + ' A sync Func delegate is also fine. + Dim okFunc As New Func(Of Integer)(Function() 42) + + ' Just a Task we will get in trouble since it's handled as a fire and forget. + Dim notOkAsyncFunc As New Func(Of Task)(Function() + control.Text = ""Hello, World!"" + Return Task.CompletedTask + End Function) + + ' A Task returning a value will also get us in trouble since it's handled as a fire and forget. + Dim notOkAsyncFunc2 As New Func(Of Task(Of Integer))(Function() + control.Text = ""Hello, World!"" + Return Task.FromResult(42) + End Function) + + ' OK. + Dim task1 = control.InvokeAsync(okAction) + + ' Also OK. + Dim task2 = control.InvokeAsync(okFunc) + + ' Concerning. - Most likely fire and forget by accident. We should warn about this. + Dim task3 = control.InvokeAsync(notOkAsyncFunc, System.Threading.CancellationToken.None) + + ' Again: Concerning. - Most likely fire and forget by accident. We should warn about this. + Dim task4 = control.InvokeAsync(notOkAsyncFunc, System.Threading.CancellationToken.None) + + ' And again concerning. - We should warn about this, too. + Dim task5 = control.InvokeAsync(notOkAsyncFunc2, System.Threading.CancellationToken.None) + + ' This is OK, since we're passing a cancellation token. + Dim okAsyncFunc = New Func(Of CancellationToken, ValueTask)(Function(cancellation) + control.Text = ""Hello, World!"" + Return ValueTask.CompletedTask + End Function) + + ' This is also OK, again, because we're passing a cancellation token. + Dim okAsyncFunc2 = New Func(Of CancellationToken, ValueTask(Of Integer))(Function(cancellation) + control.Text = ""Hello, World!"" + Return ValueTask.FromResult(42) + End Function) + + ' And let's test that, too: + Dim task6 = control.InvokeAsync(okAsyncFunc, System.Threading.CancellationToken.None) + + ' And that, too: + Dim task7 = control.InvokeAsync(okAsyncFunc2, System.Threading.CancellationToken.None) + + End Sub + + End Module + +End Namespace + +" + + Public Shared Iterator Function GetReferenceAssemblies() As IEnumerable(Of Object()) + Yield { + ReferenceAssemblies.Net.Net90.AddPackages( + ImmutableArray.Create(New PackageIdentity("Microsoft.WindowsDesktop.App.Ref", "9.0.0")) + ), "" + } + ' The latest public API surface area build from this repository. + Yield {CurrentReferences.NetCoreAppReferences, CurrentReferences.WinFormsRefPath} + End Function + + + + + Public Async Function VB_AvoidPassingFuncReturningTaskWithoutCancellationAnalyzer(referenceAssemblies As ReferenceAssemblies, pathToWinFormsAssembly As String) As Task + Assert.NotNull(referenceAssemblies) + Assert.NotNull(pathToWinFormsAssembly) + Assert.True(pathToWinFormsAssembly = "" Or File.Exists(pathToWinFormsAssembly)) + + Dim diagnosticId As String = DiagnosticIDs.AvoidPassingFuncReturningTaskWithoutCancellationToken + + Dim context As New VisualBasicAnalyzerTest(Of AvoidPassingTaskWithoutCancellationTokenAnalyzer, DefaultVerifier) With + { + .TestCode = TestCode, + .ReferenceAssemblies = referenceAssemblies + } + + context.TestState.OutputKind = OutputKind.WindowsApplication + context.TestState.ExpectedDiagnostics.AddRange( + { + DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(40, 25, 40, 101), + DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(43, 25, 43, 101), + DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(46, 25, 46, 102) + }) + + If pathToWinFormsAssembly <> "" Then + context.TestState.AdditionalReferences.Add(pathToWinFormsAssembly) + End If + + Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) + End Function + +End Class diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb index 8085ff56bff..50ffc0869f1 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb @@ -1,213 +1,214 @@ -Imports System.Windows.Forms.VisualBasic.Analyzers.MissingPropertySerializationConfiguration -Imports System.Windows.Forms.VisualBasic.CodeFixes.AddDesignerSerializationVisibility -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.Testing -Imports Microsoft.CodeAnalysis.VisualBasic.Testing -Imports Xunit - -Public Class ControlPropertySerializationDiagnosticAnalyzerTest - - Private Const ProblematicCode As String = -"Imports System.Drawing -Imports System.Windows.Forms - -Namespace VBControls - - Public Module Program - Public Sub Main() - Dim control As New ScalableControl() - - control.ScaleFactor = 1.5F - control.ScaledSize = New SizeF(100, 100) - control.ScaledLocation = New PointF(10, 10) - End Sub - End Module - - Public Class ScalableControl - Inherits System.Windows.Forms.Control - - private _scaledSize as SizeF - - Public Property [|ScaleFactor|] As Single = 1.0F - - ''' - ''' Sets or gets the scaled size of some foo bar thing. - ''' - - Public Property [|ScaledSize|] As SizeF - Get - Return _scaledSize - End Get - Set(value As SizeF) - _scaledSize = value - End Set - End Property - - ''' - ''' Sets or gets the scaled location of some foo bar thing. - ''' - Public Property [|ScaledLocation|] As PointF - End Class - -End Namespace -" - - Private Const CorrectCode As String = -"Imports System.ComponentModel -Imports System.Drawing -Imports System.Windows.Forms - -Namespace VBControls - - Public Module Program - Public Sub Main() - Dim control As New ScalableControl() - - control.ScaleFactor = 1.5F - control.ScaledSize = New SizeF(100, 100) - control.ScaledLocation = New PointF(10, 10) - End Sub - End Module - - Public Class ScalableControl - Inherits System.Windows.Forms.Control - - private _scaledSize as SizeF - - - Public Property ScaleFactor As Single = 1.0F - - ''' - ''' Sets or gets the scaled size of some foo bar thing. - ''' - - - Public Property ScaledSize As SizeF - Get - Return _scaledSize - End Get - Set(value As SizeF) - _scaledSize = value - End Set - End Property - - ''' - ''' Sets or gets the scaled location of some foo bar thing. - ''' - Public Property ScaledLocation As PointF - - Private Function ShouldSerializeScaledLocation as Boolean - Return False - End Function - End Class -End Namespace -" - - Private Const FixedCode As String = -"Imports System.Drawing -Imports System.Windows.Forms -Imports System.ComponentModel - -Namespace VBControls - - Public Module Program - Public Sub Main() - Dim control As New ScalableControl() - - control.ScaleFactor = 1.5F - control.ScaledSize = New SizeF(100, 100) - control.ScaledLocation = New PointF(10, 10) - End Sub - End Module - - Public Class ScalableControl - Inherits System.Windows.Forms.Control - - private _scaledSize as SizeF - - - Public Property ScaleFactor As Single = 1.0F - - ''' - ''' Sets or gets the scaled size of some foo bar thing. - ''' - - - Public Property ScaledSize As SizeF - Get - Return _scaledSize - End Get - Set(value As SizeF) - _scaledSize = value - End Set - End Property - - ''' - ''' Sets or gets the scaled location of some foo bar thing. - ''' - - Public Property ScaledLocation As PointF - End Class - -End Namespace -" - - ' We are testing the analyzer with all versions of the .NET SDK from 6.0 on. - Public Shared Iterator Function GetReferenceAssemblies() As IEnumerable(Of Object()) - Yield New Object() {ReferenceAssemblies.Net.Net60Windows} - Yield New Object() {ReferenceAssemblies.Net.Net70Windows} - Yield New Object() {ReferenceAssemblies.Net.Net80Windows} - Yield New Object() {ReferenceAssemblies.Net.Net90Windows} - End Function - - - - Public Async Function VB_MissingControlPropertySerializationConfigurationAnalyzer(referenceAssemblies As ReferenceAssemblies) As Task - Dim context = New VisualBasicAnalyzerTest(Of - MissingPropertySerializationConfigurationAnalyzer, - DefaultVerifier) With - { - .TestCode = ProblematicCode, - .ReferenceAssemblies = referenceAssemblies - } - - context.TestState.OutputKind = OutputKind.WindowsApplication - - Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) - End Function - - - - Public Async Function VB_ControlPropertySerializationConfigurationAnalyzer(referenceAssemblies As ReferenceAssemblies) As Task - Dim context = New VisualBasicAnalyzerTest(Of - MissingPropertySerializationConfigurationAnalyzer, - DefaultVerifier) With - { - .TestCode = CorrectCode, - .ReferenceAssemblies = referenceAssemblies - } - - context.TestState.OutputKind = OutputKind.WindowsApplication - - Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) - End Function - - - - Public Async Function VB_AddDesignerSerializationVisibilityCodeFix(referenceAssemblies As ReferenceAssemblies) As Task - Dim context = New VisualBasicCodeFixTest(Of - MissingPropertySerializationConfigurationAnalyzer, - AddDesignerSerializationVisibilityCodeFixProvider, - DefaultVerifier) With - { - .TestCode = ProblematicCode, - .FixedCode = FixedCode, - .ReferenceAssemblies = referenceAssemblies, - .NumberOfFixAllIterations = 2 - } - - context.TestState.OutputKind = OutputKind.WindowsApplication - - Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) - End Function -End Class +Imports System.Windows.Forms.VisualBasic.Analyzers.MissingPropertySerializationConfiguration +Imports System.Windows.Forms.VisualBasic.CodeFixes.AddDesignerSerializationVisibility +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Testing +Imports Microsoft.CodeAnalysis.VisualBasic.Testing +Imports Xunit + + +Public Class ControlPropertySerializationDiagnosticAnalyzerTest + + Private Const ProblematicCode As String = +"Imports System.Drawing +Imports System.Windows.Forms + +Namespace VBControls + + Public Module Program + Public Sub Main() + Dim control As New ScalableControl() + + control.ScaleFactor = 1.5F + control.ScaledSize = New SizeF(100, 100) + control.ScaledLocation = New PointF(10, 10) + End Sub + End Module + + Public Class ScalableControl + Inherits System.Windows.Forms.Control + + private _scaledSize as SizeF + + Public Property [|ScaleFactor|] As Single = 1.0F + + ''' + ''' Sets or gets the scaled size of some foo bar thing. + ''' + + Public Property [|ScaledSize|] As SizeF + Get + Return _scaledSize + End Get + Set(value As SizeF) + _scaledSize = value + End Set + End Property + + ''' + ''' Sets or gets the scaled location of some foo bar thing. + ''' + Public Property [|ScaledLocation|] As PointF + End Class + +End Namespace +" + + Private Const CorrectCode As String = +"Imports System.ComponentModel +Imports System.Drawing +Imports System.Windows.Forms + +Namespace VBControls + + Public Module Program + Public Sub Main() + Dim control As New ScalableControl() + + control.ScaleFactor = 1.5F + control.ScaledSize = New SizeF(100, 100) + control.ScaledLocation = New PointF(10, 10) + End Sub + End Module + + Public Class ScalableControl + Inherits System.Windows.Forms.Control + + private _scaledSize as SizeF + + + Public Property ScaleFactor As Single = 1.0F + + ''' + ''' Sets or gets the scaled size of some foo bar thing. + ''' + + + Public Property ScaledSize As SizeF + Get + Return _scaledSize + End Get + Set(value As SizeF) + _scaledSize = value + End Set + End Property + + ''' + ''' Sets or gets the scaled location of some foo bar thing. + ''' + Public Property ScaledLocation As PointF + + Private Function ShouldSerializeScaledLocation as Boolean + Return False + End Function + End Class +End Namespace +" + + Private Const FixedCode As String = +"Imports System.Drawing +Imports System.Windows.Forms +Imports System.ComponentModel + +Namespace VBControls + + Public Module Program + Public Sub Main() + Dim control As New ScalableControl() + + control.ScaleFactor = 1.5F + control.ScaledSize = New SizeF(100, 100) + control.ScaledLocation = New PointF(10, 10) + End Sub + End Module + + Public Class ScalableControl + Inherits System.Windows.Forms.Control + + private _scaledSize as SizeF + + + Public Property ScaleFactor As Single = 1.0F + + ''' + ''' Sets or gets the scaled size of some foo bar thing. + ''' + + + Public Property ScaledSize As SizeF + Get + Return _scaledSize + End Get + Set(value As SizeF) + _scaledSize = value + End Set + End Property + + ''' + ''' Sets or gets the scaled location of some foo bar thing. + ''' + + Public Property ScaledLocation As PointF + End Class + +End Namespace +" + + ' We are testing the analyzer with all versions of the .NET SDK from 6.0 on. + Public Shared Iterator Function GetReferenceAssemblies() As IEnumerable(Of Object()) + Yield New Object() {ReferenceAssemblies.Net.Net60Windows} + Yield New Object() {ReferenceAssemblies.Net.Net70Windows} + Yield New Object() {ReferenceAssemblies.Net.Net80Windows} + Yield New Object() {ReferenceAssemblies.Net.Net90Windows} + End Function + + + + Public Async Function VB_MissingControlPropertySerializationConfigurationAnalyzer(referenceAssemblies As ReferenceAssemblies) As Task + Dim context = New VisualBasicAnalyzerTest(Of + MissingPropertySerializationConfigurationAnalyzer, + DefaultVerifier) With + { + .TestCode = ProblematicCode, + .ReferenceAssemblies = referenceAssemblies + } + + context.TestState.OutputKind = OutputKind.WindowsApplication + + Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) + End Function + + + + Public Async Function VB_ControlPropertySerializationConfigurationAnalyzer(referenceAssemblies As ReferenceAssemblies) As Task + Dim context = New VisualBasicAnalyzerTest(Of + MissingPropertySerializationConfigurationAnalyzer, + DefaultVerifier) With + { + .TestCode = CorrectCode, + .ReferenceAssemblies = referenceAssemblies + } + + context.TestState.OutputKind = OutputKind.WindowsApplication + + Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) + End Function + + + + Public Async Function VB_AddDesignerSerializationVisibilityCodeFix(referenceAssemblies As ReferenceAssemblies) As Task + Dim context = New VisualBasicCodeFixTest(Of + MissingPropertySerializationConfigurationAnalyzer, + AddDesignerSerializationVisibilityCodeFixProvider, + DefaultVerifier) With + { + .TestCode = ProblematicCode, + .FixedCode = FixedCode, + .ReferenceAssemblies = referenceAssemblies, + .NumberOfFixAllIterations = 2 + } + + context.TestState.OutputKind = OutputKind.WindowsApplication + + Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) + End Function +End Class diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb index 16f08bb7d8f..9adbef021df 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb @@ -1,131 +1,132 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Windows.Forms.Analyzers.Diagnostics -Imports System.Windows.Forms.VisualBasic.Analyzers.ImplementITypedDataObjectInAdditionToIDataObject -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.Testing -Imports Microsoft.CodeAnalysis.VisualBasic.Testing -Imports Xunit - -Public NotInheritable Class ImplementITypedDataObjectTests - - Private Const DiagnosticId As String = DiagnosticIDs.ImplementITypedDataObject - - - Public Async Function UntypedInterface() As Task - ' internal class UntypedInterface :IDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { - DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedInterface).Length) _ - .WithArguments(NameOf(UntypedInterface)) - }) - End Function - - - Public Async Function DerivedFromUntyped() As Task - ' internal class DerivedFromUntyped : UntypedInterface - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { - DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 33, 8, 33 + NameOf(DerivedFromUntyped).Length) _ - .WithArguments(NameOf(DerivedFromUntyped)), - DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(15, 18, 15, 18 + NameOf(UntypedInterface).Length) _ - .WithArguments(NameOf(UntypedInterface)) - }) - End Function - - - Public Async Function UntypedWithAlias() As Task - ' internal class UntypedWithAlias : IManagedDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { - DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedWithAlias).Length) _ - .WithArguments(NameOf(UntypedWithAlias)) - }) - End Function - - - Public Async Function UntypedWithNamespace() As Task - ' internal class UntypedWithNamespace :Forms.IDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { - DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedWithNamespace).Length) _ - .WithArguments(NameOf(UntypedWithNamespace)) - }) - End Function - - - Public Async Function UntypedUnimplemented() As Task - ' internal class UntypedUnimplemented :IDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { - DiagnosticResult.CompilerWarning(DiagnosticId) _ - .WithSpan(9, 18, 9, 18 + NameOf(UntypedUnimplemented).Length) _ - .WithArguments(NameOf(UntypedUnimplemented)), - DiagnosticResult.CompilerError("BC30149").WithSpan(10, 20, 10, 31) _ - .WithArguments("Class", "UntypedUnimplemented", "Function GetData(format As String, autoConvert As Boolean) As Object", "IDataObject") - }) - End Function - - - Public Async Function TypedInterface() As Task - ' internal class TypedInterface :ITypedDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await NoWarning(input) - End Function - - - Public Async Function TypedWithNamespace() As Task - ' internal class TypedWithNamespace : Forms.ITypedDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await NoWarning(input) - End Function - - - Public Async Function TypedWithAlias() As Task - ' internal class TypedWithAlias : IManagedDataObject, System.Windows.Forms.IDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await NoWarning(input) - End Function - - - Public Async Function TwoInterfaces() As Task - ' internal class TwoInterfaces :IDataObject, ITypedDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await NoWarning(input) - End Function - - - Public Async Function UnrelatedIDataObject() As Task - ' Name collision, this analyzer is not applicable - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await NoWarning(input) - End Function - - Private Shared Async Function RaiseTheWarning(input As String, diagnostics As List(Of DiagnosticResult)) As Task - Dim context = CreateContext(input) - context.TestState.ExpectedDiagnostics.AddRange(diagnostics) - - Await context.RunAsync().ConfigureAwait(False) - End Function - - Private Shared Async Function NoWarning(input As String) As Task - Await CreateContext(input).RunAsync().ConfigureAwait(False) - End Function - - Private Shared Function CreateContext(input As String) As VisualBasicAnalyzerTest(Of ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer, DefaultVerifier) - Assert.NotNull(CurrentReferences.NetCoreAppReferences) - Assert.NotNull(CurrentReferences.WinFormsRefPath) - - Dim context As New VisualBasicAnalyzerTest(Of ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer, DefaultVerifier) With { - .TestCode = input, - .ReferenceAssemblies = CurrentReferences.NetCoreAppReferences - } - - context.TestState.OutputKind = OutputKind.DynamicallyLinkedLibrary - context.TestState.AdditionalReferences.Add(CurrentReferences.WinFormsRefPath) - - Return context - End Function - -End Class +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.Windows.Forms.Analyzers.Diagnostics +Imports System.Windows.Forms.VisualBasic.Analyzers.ImplementITypedDataObjectInAdditionToIDataObject +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Testing +Imports Microsoft.CodeAnalysis.VisualBasic.Testing +Imports Xunit + + +Public NotInheritable Class ImplementITypedDataObjectTests + + Private Const DiagnosticId As String = DiagnosticIDs.ImplementITypedDataObject + + + Public Async Function UntypedInterface() As Task + ' internal class UntypedInterface :IDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { + DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedInterface).Length) _ + .WithArguments(NameOf(UntypedInterface)) + }) + End Function + + + Public Async Function DerivedFromUntyped() As Task + ' internal class DerivedFromUntyped : UntypedInterface + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { + DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 33, 8, 33 + NameOf(DerivedFromUntyped).Length) _ + .WithArguments(NameOf(DerivedFromUntyped)), + DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(15, 18, 15, 18 + NameOf(UntypedInterface).Length) _ + .WithArguments(NameOf(UntypedInterface)) + }) + End Function + + + Public Async Function UntypedWithAlias() As Task + ' internal class UntypedWithAlias : IManagedDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { + DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedWithAlias).Length) _ + .WithArguments(NameOf(UntypedWithAlias)) + }) + End Function + + + Public Async Function UntypedWithNamespace() As Task + ' internal class UntypedWithNamespace :Forms.IDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { + DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedWithNamespace).Length) _ + .WithArguments(NameOf(UntypedWithNamespace)) + }) + End Function + + + Public Async Function UntypedUnimplemented() As Task + ' internal class UntypedUnimplemented :IDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { + DiagnosticResult.CompilerWarning(DiagnosticId) _ + .WithSpan(9, 18, 9, 18 + NameOf(UntypedUnimplemented).Length) _ + .WithArguments(NameOf(UntypedUnimplemented)), + DiagnosticResult.CompilerError("BC30149").WithSpan(10, 20, 10, 31) _ + .WithArguments("Class", "UntypedUnimplemented", "Function GetData(format As String, autoConvert As Boolean) As Object", "IDataObject") + }) + End Function + + + Public Async Function TypedInterface() As Task + ' internal class TypedInterface :ITypedDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await NoWarning(input) + End Function + + + Public Async Function TypedWithNamespace() As Task + ' internal class TypedWithNamespace : Forms.ITypedDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await NoWarning(input) + End Function + + + Public Async Function TypedWithAlias() As Task + ' internal class TypedWithAlias : IManagedDataObject, System.Windows.Forms.IDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await NoWarning(input) + End Function + + + Public Async Function TwoInterfaces() As Task + ' internal class TwoInterfaces :IDataObject, ITypedDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await NoWarning(input) + End Function + + + Public Async Function UnrelatedIDataObject() As Task + ' Name collision, this analyzer is not applicable + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await NoWarning(input) + End Function + + Private Shared Async Function RaiseTheWarning(input As String, diagnostics As List(Of DiagnosticResult)) As Task + Dim context = CreateContext(input) + context.TestState.ExpectedDiagnostics.AddRange(diagnostics) + + Await context.RunAsync().ConfigureAwait(False) + End Function + + Private Shared Async Function NoWarning(input As String) As Task + Await CreateContext(input).RunAsync().ConfigureAwait(False) + End Function + + Private Shared Function CreateContext(input As String) As VisualBasicAnalyzerTest(Of ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer, DefaultVerifier) + Assert.NotNull(CurrentReferences.NetCoreAppReferences) + Assert.NotNull(CurrentReferences.WinFormsRefPath) + + Dim context As New VisualBasicAnalyzerTest(Of ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer, DefaultVerifier) With { + .TestCode = input, + .ReferenceAssemblies = CurrentReferences.NetCoreAppReferences + } + + context.TestState.OutputKind = OutputKind.DynamicallyLinkedLibrary + context.TestState.AdditionalReferences.Add(CurrentReferences.WinFormsRefPath) + + Return context + End Function + +End Class From 6dc3b1a0053fbf309044e84bea334367a3193c56 Mon Sep 17 00:00:00 2001 From: "Shyam Gupta (DevDiv)" Date: Wed, 25 Feb 2026 11:36:51 -0800 Subject: [PATCH 2/3] Updated Line endings to CRLF --- ...assingTaskWithoutCancellationTokenTests.vb | 261 +++++------ ...ySerializationConfigurationAnalyzerTest.vb | 429 +++++++++--------- .../WFO1001/ImplementITypedDataObjectTests.vb | 265 +++++------ 3 files changed, 479 insertions(+), 476 deletions(-) diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb index e445a23cedb..d6182bc0bae 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb @@ -1,130 +1,131 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Collections.Immutable -Imports System.IO -Imports System.Windows.Forms.Analyzers.Diagnostics -Imports System.Windows.Forms.VisualBasic.Analyzers.AvoidPassingTaskWithoutCancellationToken -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.Testing -Imports Microsoft.CodeAnalysis.VisualBasic.Testing -Imports Xunit - - -Public Class AvoidPassingTaskWithoutCancellationTokenTests - - Private Const TestCode As String = " -Imports System -Imports System.Threading -Imports System.Threading.Tasks -Imports System.Windows.Forms - -Namespace VisualBasicControls - - Public Module Program - - Public Sub Main() - - Dim control As New Control() - - ' A sync Action delegate is always fine. - Dim okAction As New Action(Sub() control.Text = ""Hello, World!"") - - ' A sync Func delegate is also fine. - Dim okFunc As New Func(Of Integer)(Function() 42) - - ' Just a Task we will get in trouble since it's handled as a fire and forget. - Dim notOkAsyncFunc As New Func(Of Task)(Function() - control.Text = ""Hello, World!"" - Return Task.CompletedTask - End Function) - - ' A Task returning a value will also get us in trouble since it's handled as a fire and forget. - Dim notOkAsyncFunc2 As New Func(Of Task(Of Integer))(Function() - control.Text = ""Hello, World!"" - Return Task.FromResult(42) - End Function) - - ' OK. - Dim task1 = control.InvokeAsync(okAction) - - ' Also OK. - Dim task2 = control.InvokeAsync(okFunc) - - ' Concerning. - Most likely fire and forget by accident. We should warn about this. - Dim task3 = control.InvokeAsync(notOkAsyncFunc, System.Threading.CancellationToken.None) - - ' Again: Concerning. - Most likely fire and forget by accident. We should warn about this. - Dim task4 = control.InvokeAsync(notOkAsyncFunc, System.Threading.CancellationToken.None) - - ' And again concerning. - We should warn about this, too. - Dim task5 = control.InvokeAsync(notOkAsyncFunc2, System.Threading.CancellationToken.None) - - ' This is OK, since we're passing a cancellation token. - Dim okAsyncFunc = New Func(Of CancellationToken, ValueTask)(Function(cancellation) - control.Text = ""Hello, World!"" - Return ValueTask.CompletedTask - End Function) - - ' This is also OK, again, because we're passing a cancellation token. - Dim okAsyncFunc2 = New Func(Of CancellationToken, ValueTask(Of Integer))(Function(cancellation) - control.Text = ""Hello, World!"" - Return ValueTask.FromResult(42) - End Function) - - ' And let's test that, too: - Dim task6 = control.InvokeAsync(okAsyncFunc, System.Threading.CancellationToken.None) - - ' And that, too: - Dim task7 = control.InvokeAsync(okAsyncFunc2, System.Threading.CancellationToken.None) - - End Sub - - End Module - -End Namespace - -" - - Public Shared Iterator Function GetReferenceAssemblies() As IEnumerable(Of Object()) - Yield { - ReferenceAssemblies.Net.Net90.AddPackages( - ImmutableArray.Create(New PackageIdentity("Microsoft.WindowsDesktop.App.Ref", "9.0.0")) - ), "" - } - ' The latest public API surface area build from this repository. - Yield {CurrentReferences.NetCoreAppReferences, CurrentReferences.WinFormsRefPath} - End Function - - - - - Public Async Function VB_AvoidPassingFuncReturningTaskWithoutCancellationAnalyzer(referenceAssemblies As ReferenceAssemblies, pathToWinFormsAssembly As String) As Task - Assert.NotNull(referenceAssemblies) - Assert.NotNull(pathToWinFormsAssembly) - Assert.True(pathToWinFormsAssembly = "" Or File.Exists(pathToWinFormsAssembly)) - - Dim diagnosticId As String = DiagnosticIDs.AvoidPassingFuncReturningTaskWithoutCancellationToken - - Dim context As New VisualBasicAnalyzerTest(Of AvoidPassingTaskWithoutCancellationTokenAnalyzer, DefaultVerifier) With - { - .TestCode = TestCode, - .ReferenceAssemblies = referenceAssemblies - } - - context.TestState.OutputKind = OutputKind.WindowsApplication - context.TestState.ExpectedDiagnostics.AddRange( - { - DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(40, 25, 40, 101), - DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(43, 25, 43, 101), - DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(46, 25, 46, 102) - }) - - If pathToWinFormsAssembly <> "" Then - context.TestState.AdditionalReferences.Add(pathToWinFormsAssembly) - End If - - Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) - End Function - -End Class +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.Collections.Immutable +Imports System.IO +Imports System.Windows.Forms.Analyzers.Diagnostics +Imports System.Windows.Forms.VisualBasic.Analyzers.AvoidPassingTaskWithoutCancellationToken +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Testing +Imports Microsoft.CodeAnalysis.VisualBasic.Testing +Imports Xunit + + + +Public Class AvoidPassingTaskWithoutCancellationTokenTests + + Private Const TestCode As String = " +Imports System +Imports System.Threading +Imports System.Threading.Tasks +Imports System.Windows.Forms + +Namespace VisualBasicControls + + Public Module Program + + Public Sub Main() + + Dim control As New Control() + + ' A sync Action delegate is always fine. + Dim okAction As New Action(Sub() control.Text = ""Hello, World!"") + + ' A sync Func delegate is also fine. + Dim okFunc As New Func(Of Integer)(Function() 42) + + ' Just a Task we will get in trouble since it's handled as a fire and forget. + Dim notOkAsyncFunc As New Func(Of Task)(Function() + control.Text = ""Hello, World!"" + Return Task.CompletedTask + End Function) + + ' A Task returning a value will also get us in trouble since it's handled as a fire and forget. + Dim notOkAsyncFunc2 As New Func(Of Task(Of Integer))(Function() + control.Text = ""Hello, World!"" + Return Task.FromResult(42) + End Function) + + ' OK. + Dim task1 = control.InvokeAsync(okAction) + + ' Also OK. + Dim task2 = control.InvokeAsync(okFunc) + + ' Concerning. - Most likely fire and forget by accident. We should warn about this. + Dim task3 = control.InvokeAsync(notOkAsyncFunc, System.Threading.CancellationToken.None) + + ' Again: Concerning. - Most likely fire and forget by accident. We should warn about this. + Dim task4 = control.InvokeAsync(notOkAsyncFunc, System.Threading.CancellationToken.None) + + ' And again concerning. - We should warn about this, too. + Dim task5 = control.InvokeAsync(notOkAsyncFunc2, System.Threading.CancellationToken.None) + + ' This is OK, since we're passing a cancellation token. + Dim okAsyncFunc = New Func(Of CancellationToken, ValueTask)(Function(cancellation) + control.Text = ""Hello, World!"" + Return ValueTask.CompletedTask + End Function) + + ' This is also OK, again, because we're passing a cancellation token. + Dim okAsyncFunc2 = New Func(Of CancellationToken, ValueTask(Of Integer))(Function(cancellation) + control.Text = ""Hello, World!"" + Return ValueTask.FromResult(42) + End Function) + + ' And let's test that, too: + Dim task6 = control.InvokeAsync(okAsyncFunc, System.Threading.CancellationToken.None) + + ' And that, too: + Dim task7 = control.InvokeAsync(okAsyncFunc2, System.Threading.CancellationToken.None) + + End Sub + + End Module + +End Namespace + +" + + Public Shared Iterator Function GetReferenceAssemblies() As IEnumerable(Of Object()) + Yield { + ReferenceAssemblies.Net.Net90.AddPackages( + ImmutableArray.Create(New PackageIdentity("Microsoft.WindowsDesktop.App.Ref", "9.0.0")) + ), "" + } + ' The latest public API surface area build from this repository. + Yield {CurrentReferences.NetCoreAppReferences, CurrentReferences.WinFormsRefPath} + End Function + + + + + Public Async Function VB_AvoidPassingFuncReturningTaskWithoutCancellationAnalyzer(referenceAssemblies As ReferenceAssemblies, pathToWinFormsAssembly As String) As Task + Assert.NotNull(referenceAssemblies) + Assert.NotNull(pathToWinFormsAssembly) + Assert.True(pathToWinFormsAssembly = "" Or File.Exists(pathToWinFormsAssembly)) + + Dim diagnosticId As String = DiagnosticIDs.AvoidPassingFuncReturningTaskWithoutCancellationToken + + Dim context As New VisualBasicAnalyzerTest(Of AvoidPassingTaskWithoutCancellationTokenAnalyzer, DefaultVerifier) With + { + .TestCode = TestCode, + .ReferenceAssemblies = referenceAssemblies + } + + context.TestState.OutputKind = OutputKind.WindowsApplication + context.TestState.ExpectedDiagnostics.AddRange( + { + DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(40, 25, 40, 101), + DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(43, 25, 43, 101), + DiagnosticResult.CompilerWarning(diagnosticId).WithSpan(46, 25, 46, 102) + }) + + If pathToWinFormsAssembly <> "" Then + context.TestState.AdditionalReferences.Add(pathToWinFormsAssembly) + End If + + Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) + End Function + +End Class diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb index 50ffc0869f1..45acbae18bb 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb @@ -1,214 +1,215 @@ -Imports System.Windows.Forms.VisualBasic.Analyzers.MissingPropertySerializationConfiguration -Imports System.Windows.Forms.VisualBasic.CodeFixes.AddDesignerSerializationVisibility -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.Testing -Imports Microsoft.CodeAnalysis.VisualBasic.Testing -Imports Xunit - - -Public Class ControlPropertySerializationDiagnosticAnalyzerTest - - Private Const ProblematicCode As String = -"Imports System.Drawing -Imports System.Windows.Forms - -Namespace VBControls - - Public Module Program - Public Sub Main() - Dim control As New ScalableControl() - - control.ScaleFactor = 1.5F - control.ScaledSize = New SizeF(100, 100) - control.ScaledLocation = New PointF(10, 10) - End Sub - End Module - - Public Class ScalableControl - Inherits System.Windows.Forms.Control - - private _scaledSize as SizeF - - Public Property [|ScaleFactor|] As Single = 1.0F - - ''' - ''' Sets or gets the scaled size of some foo bar thing. - ''' - - Public Property [|ScaledSize|] As SizeF - Get - Return _scaledSize - End Get - Set(value As SizeF) - _scaledSize = value - End Set - End Property - - ''' - ''' Sets or gets the scaled location of some foo bar thing. - ''' - Public Property [|ScaledLocation|] As PointF - End Class - -End Namespace -" - - Private Const CorrectCode As String = -"Imports System.ComponentModel -Imports System.Drawing -Imports System.Windows.Forms - -Namespace VBControls - - Public Module Program - Public Sub Main() - Dim control As New ScalableControl() - - control.ScaleFactor = 1.5F - control.ScaledSize = New SizeF(100, 100) - control.ScaledLocation = New PointF(10, 10) - End Sub - End Module - - Public Class ScalableControl - Inherits System.Windows.Forms.Control - - private _scaledSize as SizeF - - - Public Property ScaleFactor As Single = 1.0F - - ''' - ''' Sets or gets the scaled size of some foo bar thing. - ''' - - - Public Property ScaledSize As SizeF - Get - Return _scaledSize - End Get - Set(value As SizeF) - _scaledSize = value - End Set - End Property - - ''' - ''' Sets or gets the scaled location of some foo bar thing. - ''' - Public Property ScaledLocation As PointF - - Private Function ShouldSerializeScaledLocation as Boolean - Return False - End Function - End Class -End Namespace -" - - Private Const FixedCode As String = -"Imports System.Drawing -Imports System.Windows.Forms -Imports System.ComponentModel - -Namespace VBControls - - Public Module Program - Public Sub Main() - Dim control As New ScalableControl() - - control.ScaleFactor = 1.5F - control.ScaledSize = New SizeF(100, 100) - control.ScaledLocation = New PointF(10, 10) - End Sub - End Module - - Public Class ScalableControl - Inherits System.Windows.Forms.Control - - private _scaledSize as SizeF - - - Public Property ScaleFactor As Single = 1.0F - - ''' - ''' Sets or gets the scaled size of some foo bar thing. - ''' - - - Public Property ScaledSize As SizeF - Get - Return _scaledSize - End Get - Set(value As SizeF) - _scaledSize = value - End Set - End Property - - ''' - ''' Sets or gets the scaled location of some foo bar thing. - ''' - - Public Property ScaledLocation As PointF - End Class - -End Namespace -" - - ' We are testing the analyzer with all versions of the .NET SDK from 6.0 on. - Public Shared Iterator Function GetReferenceAssemblies() As IEnumerable(Of Object()) - Yield New Object() {ReferenceAssemblies.Net.Net60Windows} - Yield New Object() {ReferenceAssemblies.Net.Net70Windows} - Yield New Object() {ReferenceAssemblies.Net.Net80Windows} - Yield New Object() {ReferenceAssemblies.Net.Net90Windows} - End Function - - - - Public Async Function VB_MissingControlPropertySerializationConfigurationAnalyzer(referenceAssemblies As ReferenceAssemblies) As Task - Dim context = New VisualBasicAnalyzerTest(Of - MissingPropertySerializationConfigurationAnalyzer, - DefaultVerifier) With - { - .TestCode = ProblematicCode, - .ReferenceAssemblies = referenceAssemblies - } - - context.TestState.OutputKind = OutputKind.WindowsApplication - - Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) - End Function - - - - Public Async Function VB_ControlPropertySerializationConfigurationAnalyzer(referenceAssemblies As ReferenceAssemblies) As Task - Dim context = New VisualBasicAnalyzerTest(Of - MissingPropertySerializationConfigurationAnalyzer, - DefaultVerifier) With - { - .TestCode = CorrectCode, - .ReferenceAssemblies = referenceAssemblies - } - - context.TestState.OutputKind = OutputKind.WindowsApplication - - Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) - End Function - - - - Public Async Function VB_AddDesignerSerializationVisibilityCodeFix(referenceAssemblies As ReferenceAssemblies) As Task - Dim context = New VisualBasicCodeFixTest(Of - MissingPropertySerializationConfigurationAnalyzer, - AddDesignerSerializationVisibilityCodeFixProvider, - DefaultVerifier) With - { - .TestCode = ProblematicCode, - .FixedCode = FixedCode, - .ReferenceAssemblies = referenceAssemblies, - .NumberOfFixAllIterations = 2 - } - - context.TestState.OutputKind = OutputKind.WindowsApplication - - Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) - End Function -End Class +Imports System.Windows.Forms.VisualBasic.Analyzers.MissingPropertySerializationConfiguration +Imports System.Windows.Forms.VisualBasic.CodeFixes.AddDesignerSerializationVisibility +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Testing +Imports Microsoft.CodeAnalysis.VisualBasic.Testing +Imports Xunit + + + +Public Class ControlPropertySerializationDiagnosticAnalyzerTest + + Private Const ProblematicCode As String = +"Imports System.Drawing +Imports System.Windows.Forms + +Namespace VBControls + + Public Module Program + Public Sub Main() + Dim control As New ScalableControl() + + control.ScaleFactor = 1.5F + control.ScaledSize = New SizeF(100, 100) + control.ScaledLocation = New PointF(10, 10) + End Sub + End Module + + Public Class ScalableControl + Inherits System.Windows.Forms.Control + + private _scaledSize as SizeF + + Public Property [|ScaleFactor|] As Single = 1.0F + + ''' + ''' Sets or gets the scaled size of some foo bar thing. + ''' + + Public Property [|ScaledSize|] As SizeF + Get + Return _scaledSize + End Get + Set(value As SizeF) + _scaledSize = value + End Set + End Property + + ''' + ''' Sets or gets the scaled location of some foo bar thing. + ''' + Public Property [|ScaledLocation|] As PointF + End Class + +End Namespace +" + + Private Const CorrectCode As String = +"Imports System.ComponentModel +Imports System.Drawing +Imports System.Windows.Forms + +Namespace VBControls + + Public Module Program + Public Sub Main() + Dim control As New ScalableControl() + + control.ScaleFactor = 1.5F + control.ScaledSize = New SizeF(100, 100) + control.ScaledLocation = New PointF(10, 10) + End Sub + End Module + + Public Class ScalableControl + Inherits System.Windows.Forms.Control + + private _scaledSize as SizeF + + + Public Property ScaleFactor As Single = 1.0F + + ''' + ''' Sets or gets the scaled size of some foo bar thing. + ''' + + + Public Property ScaledSize As SizeF + Get + Return _scaledSize + End Get + Set(value As SizeF) + _scaledSize = value + End Set + End Property + + ''' + ''' Sets or gets the scaled location of some foo bar thing. + ''' + Public Property ScaledLocation As PointF + + Private Function ShouldSerializeScaledLocation as Boolean + Return False + End Function + End Class +End Namespace +" + + Private Const FixedCode As String = +"Imports System.Drawing +Imports System.Windows.Forms +Imports System.ComponentModel + +Namespace VBControls + + Public Module Program + Public Sub Main() + Dim control As New ScalableControl() + + control.ScaleFactor = 1.5F + control.ScaledSize = New SizeF(100, 100) + control.ScaledLocation = New PointF(10, 10) + End Sub + End Module + + Public Class ScalableControl + Inherits System.Windows.Forms.Control + + private _scaledSize as SizeF + + + Public Property ScaleFactor As Single = 1.0F + + ''' + ''' Sets or gets the scaled size of some foo bar thing. + ''' + + + Public Property ScaledSize As SizeF + Get + Return _scaledSize + End Get + Set(value As SizeF) + _scaledSize = value + End Set + End Property + + ''' + ''' Sets or gets the scaled location of some foo bar thing. + ''' + + Public Property ScaledLocation As PointF + End Class + +End Namespace +" + + ' We are testing the analyzer with all versions of the .NET SDK from 6.0 on. + Public Shared Iterator Function GetReferenceAssemblies() As IEnumerable(Of Object()) + Yield New Object() {ReferenceAssemblies.Net.Net60Windows} + Yield New Object() {ReferenceAssemblies.Net.Net70Windows} + Yield New Object() {ReferenceAssemblies.Net.Net80Windows} + Yield New Object() {ReferenceAssemblies.Net.Net90Windows} + End Function + + + + Public Async Function VB_MissingControlPropertySerializationConfigurationAnalyzer(referenceAssemblies As ReferenceAssemblies) As Task + Dim context = New VisualBasicAnalyzerTest(Of + MissingPropertySerializationConfigurationAnalyzer, + DefaultVerifier) With + { + .TestCode = ProblematicCode, + .ReferenceAssemblies = referenceAssemblies + } + + context.TestState.OutputKind = OutputKind.WindowsApplication + + Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) + End Function + + + + Public Async Function VB_ControlPropertySerializationConfigurationAnalyzer(referenceAssemblies As ReferenceAssemblies) As Task + Dim context = New VisualBasicAnalyzerTest(Of + MissingPropertySerializationConfigurationAnalyzer, + DefaultVerifier) With + { + .TestCode = CorrectCode, + .ReferenceAssemblies = referenceAssemblies + } + + context.TestState.OutputKind = OutputKind.WindowsApplication + + Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) + End Function + + + + Public Async Function VB_AddDesignerSerializationVisibilityCodeFix(referenceAssemblies As ReferenceAssemblies) As Task + Dim context = New VisualBasicCodeFixTest(Of + MissingPropertySerializationConfigurationAnalyzer, + AddDesignerSerializationVisibilityCodeFixProvider, + DefaultVerifier) With + { + .TestCode = ProblematicCode, + .FixedCode = FixedCode, + .ReferenceAssemblies = referenceAssemblies, + .NumberOfFixAllIterations = 2 + } + + context.TestState.OutputKind = OutputKind.WindowsApplication + + Await context.RunAsync().ConfigureAwait(continueOnCapturedContext:=True) + End Function +End Class diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb index 9adbef021df..004800b1bc5 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb @@ -1,132 +1,133 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Windows.Forms.Analyzers.Diagnostics -Imports System.Windows.Forms.VisualBasic.Analyzers.ImplementITypedDataObjectInAdditionToIDataObject -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.Testing -Imports Microsoft.CodeAnalysis.VisualBasic.Testing -Imports Xunit - - -Public NotInheritable Class ImplementITypedDataObjectTests - - Private Const DiagnosticId As String = DiagnosticIDs.ImplementITypedDataObject - - - Public Async Function UntypedInterface() As Task - ' internal class UntypedInterface :IDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { - DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedInterface).Length) _ - .WithArguments(NameOf(UntypedInterface)) - }) - End Function - - - Public Async Function DerivedFromUntyped() As Task - ' internal class DerivedFromUntyped : UntypedInterface - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { - DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 33, 8, 33 + NameOf(DerivedFromUntyped).Length) _ - .WithArguments(NameOf(DerivedFromUntyped)), - DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(15, 18, 15, 18 + NameOf(UntypedInterface).Length) _ - .WithArguments(NameOf(UntypedInterface)) - }) - End Function - - - Public Async Function UntypedWithAlias() As Task - ' internal class UntypedWithAlias : IManagedDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { - DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedWithAlias).Length) _ - .WithArguments(NameOf(UntypedWithAlias)) - }) - End Function - - - Public Async Function UntypedWithNamespace() As Task - ' internal class UntypedWithNamespace :Forms.IDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { - DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedWithNamespace).Length) _ - .WithArguments(NameOf(UntypedWithNamespace)) - }) - End Function - - - Public Async Function UntypedUnimplemented() As Task - ' internal class UntypedUnimplemented :IDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { - DiagnosticResult.CompilerWarning(DiagnosticId) _ - .WithSpan(9, 18, 9, 18 + NameOf(UntypedUnimplemented).Length) _ - .WithArguments(NameOf(UntypedUnimplemented)), - DiagnosticResult.CompilerError("BC30149").WithSpan(10, 20, 10, 31) _ - .WithArguments("Class", "UntypedUnimplemented", "Function GetData(format As String, autoConvert As Boolean) As Object", "IDataObject") - }) - End Function - - - Public Async Function TypedInterface() As Task - ' internal class TypedInterface :ITypedDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await NoWarning(input) - End Function - - - Public Async Function TypedWithNamespace() As Task - ' internal class TypedWithNamespace : Forms.ITypedDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await NoWarning(input) - End Function - - - Public Async Function TypedWithAlias() As Task - ' internal class TypedWithAlias : IManagedDataObject, System.Windows.Forms.IDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await NoWarning(input) - End Function - - - Public Async Function TwoInterfaces() As Task - ' internal class TwoInterfaces :IDataObject, ITypedDataObject - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await NoWarning(input) - End Function - - - Public Async Function UnrelatedIDataObject() As Task - ' Name collision, this analyzer is not applicable - Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() - Await NoWarning(input) - End Function - - Private Shared Async Function RaiseTheWarning(input As String, diagnostics As List(Of DiagnosticResult)) As Task - Dim context = CreateContext(input) - context.TestState.ExpectedDiagnostics.AddRange(diagnostics) - - Await context.RunAsync().ConfigureAwait(False) - End Function - - Private Shared Async Function NoWarning(input As String) As Task - Await CreateContext(input).RunAsync().ConfigureAwait(False) - End Function - - Private Shared Function CreateContext(input As String) As VisualBasicAnalyzerTest(Of ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer, DefaultVerifier) - Assert.NotNull(CurrentReferences.NetCoreAppReferences) - Assert.NotNull(CurrentReferences.WinFormsRefPath) - - Dim context As New VisualBasicAnalyzerTest(Of ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer, DefaultVerifier) With { - .TestCode = input, - .ReferenceAssemblies = CurrentReferences.NetCoreAppReferences - } - - context.TestState.OutputKind = OutputKind.DynamicallyLinkedLibrary - context.TestState.AdditionalReferences.Add(CurrentReferences.WinFormsRefPath) - - Return context - End Function - -End Class +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.Windows.Forms.Analyzers.Diagnostics +Imports System.Windows.Forms.VisualBasic.Analyzers.ImplementITypedDataObjectInAdditionToIDataObject +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Testing +Imports Microsoft.CodeAnalysis.VisualBasic.Testing +Imports Xunit + + + +Public NotInheritable Class ImplementITypedDataObjectTests + + Private Const DiagnosticId As String = DiagnosticIDs.ImplementITypedDataObject + + + Public Async Function UntypedInterface() As Task + ' internal class UntypedInterface :IDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { + DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedInterface).Length) _ + .WithArguments(NameOf(UntypedInterface)) + }) + End Function + + + Public Async Function DerivedFromUntyped() As Task + ' internal class DerivedFromUntyped : UntypedInterface + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { + DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 33, 8, 33 + NameOf(DerivedFromUntyped).Length) _ + .WithArguments(NameOf(DerivedFromUntyped)), + DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(15, 18, 15, 18 + NameOf(UntypedInterface).Length) _ + .WithArguments(NameOf(UntypedInterface)) + }) + End Function + + + Public Async Function UntypedWithAlias() As Task + ' internal class UntypedWithAlias : IManagedDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { + DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedWithAlias).Length) _ + .WithArguments(NameOf(UntypedWithAlias)) + }) + End Function + + + Public Async Function UntypedWithNamespace() As Task + ' internal class UntypedWithNamespace :Forms.IDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { + DiagnosticResult.CompilerWarning(DiagnosticId).WithSpan(8, 18, 8, 18 + NameOf(UntypedWithNamespace).Length) _ + .WithArguments(NameOf(UntypedWithNamespace)) + }) + End Function + + + Public Async Function UntypedUnimplemented() As Task + ' internal class UntypedUnimplemented :IDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await RaiseTheWarning(input, New List(Of DiagnosticResult) From { + DiagnosticResult.CompilerWarning(DiagnosticId) _ + .WithSpan(9, 18, 9, 18 + NameOf(UntypedUnimplemented).Length) _ + .WithArguments(NameOf(UntypedUnimplemented)), + DiagnosticResult.CompilerError("BC30149").WithSpan(10, 20, 10, 31) _ + .WithArguments("Class", "UntypedUnimplemented", "Function GetData(format As String, autoConvert As Boolean) As Object", "IDataObject") + }) + End Function + + + Public Async Function TypedInterface() As Task + ' internal class TypedInterface :ITypedDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await NoWarning(input) + End Function + + + Public Async Function TypedWithNamespace() As Task + ' internal class TypedWithNamespace : Forms.ITypedDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await NoWarning(input) + End Function + + + Public Async Function TypedWithAlias() As Task + ' internal class TypedWithAlias : IManagedDataObject, System.Windows.Forms.IDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await NoWarning(input) + End Function + + + Public Async Function TwoInterfaces() As Task + ' internal class TwoInterfaces :IDataObject, ITypedDataObject + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await NoWarning(input) + End Function + + + Public Async Function UnrelatedIDataObject() As Task + ' Name collision, this analyzer is not applicable + Dim input As String = Await TestFileLoader.GetVBAnalyzerTestCodeAsync() + Await NoWarning(input) + End Function + + Private Shared Async Function RaiseTheWarning(input As String, diagnostics As List(Of DiagnosticResult)) As Task + Dim context = CreateContext(input) + context.TestState.ExpectedDiagnostics.AddRange(diagnostics) + + Await context.RunAsync().ConfigureAwait(False) + End Function + + Private Shared Async Function NoWarning(input As String) As Task + Await CreateContext(input).RunAsync().ConfigureAwait(False) + End Function + + Private Shared Function CreateContext(input As String) As VisualBasicAnalyzerTest(Of ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer, DefaultVerifier) + Assert.NotNull(CurrentReferences.NetCoreAppReferences) + Assert.NotNull(CurrentReferences.WinFormsRefPath) + + Dim context As New VisualBasicAnalyzerTest(Of ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer, DefaultVerifier) With { + .TestCode = input, + .ReferenceAssemblies = CurrentReferences.NetCoreAppReferences + } + + context.TestState.OutputKind = OutputKind.DynamicallyLinkedLibrary + context.TestState.AdditionalReferences.Add(CurrentReferences.WinFormsRefPath) + + Return context + End Function + +End Class From 5500d63bda66bf0f554550a296e8395e1e399665 Mon Sep 17 00:00:00 2001 From: "Shyam Gupta (DevDiv)" Date: Wed, 25 Feb 2026 11:41:58 -0800 Subject: [PATCH 3/3] Removed an extra line. --- .../Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb | 1 - .../MissingPropertySerializationConfigurationAnalyzerTest.vb | 1 - .../Analyzers/WFO1001/ImplementITypedDataObjectTests.vb | 1 - 3 files changed, 3 deletions(-) diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb index d6182bc0bae..181be097b39 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/AvoidPassingTaskWithoutCancellationTokenTests.vb @@ -10,7 +10,6 @@ Imports Microsoft.CodeAnalysis.Testing Imports Microsoft.CodeAnalysis.VisualBasic.Testing Imports Xunit - Public Class AvoidPassingTaskWithoutCancellationTokenTests diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb index 45acbae18bb..ad79665e108 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/MissingPropertySerializationConfigurationAnalyzerTest.vb @@ -5,7 +5,6 @@ Imports Microsoft.CodeAnalysis.Testing Imports Microsoft.CodeAnalysis.VisualBasic.Testing Imports Xunit - Public Class ControlPropertySerializationDiagnosticAnalyzerTest diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb index 004800b1bc5..61886d8c69d 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/tests/UnitTests/System.Windows.Forms.Analyzers.VisualBasic.Tests/Analyzers/WFO1001/ImplementITypedDataObjectTests.vb @@ -8,7 +8,6 @@ Imports Microsoft.CodeAnalysis.Testing Imports Microsoft.CodeAnalysis.VisualBasic.Testing Imports Xunit - Public NotInheritable Class ImplementITypedDataObjectTests