| File: Analyzers\Designer\InitializeComponentAnalyzer.vb | Web Access |
| Project: ..\..\..\src\winforms\src\System.Windows.Forms.Analyzers.VisualBasic\src\System.Windows.Forms.Analyzers.VisualBasic.vbproj (System.Windows.Forms.Analyzers.VisualBasic) |
' 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.Windows.Forms.Analyzers Imports System.Windows.Forms.Analyzers.Diagnostics Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Diagnostics Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Global.System.Windows.Forms.VisualBasic.Analyzers.Designer ''' <summary> ''' Reports control flow that should not be emitted in <c>InitializeComponent</c>. ''' </summary> <DiagnosticAnalyzer(LanguageNames.VisualBasic)> Public NotInheritable Class InitializeComponentAnalyzer Inherits DiagnosticAnalyzer ''' <inheritdoc/> Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor) Get Return ImmutableArray.Create( SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode, SharedDiagnosticDescriptors.s_unsupportedNameOfExpression, SharedDiagnosticDescriptors.s_unsupportedConditionalExpression, SharedDiagnosticDescriptors.s_unsupportedNullCoalescingExpression, SharedDiagnosticDescriptors.s_unsupportedNullConditionalExpression, SharedDiagnosticDescriptors.s_unsupportedInterpolatedString, SharedDiagnosticDescriptors.s_visualBasicUnsupportedAnonymousFunction) End Get End Property ''' <inheritdoc/> Public Overrides Sub Initialize(context As AnalysisContext) context.EnableConcurrentExecution() context.ConfigureGeneratedCodeAnalysis( GeneratedCodeAnalysisFlags.Analyze Or GeneratedCodeAnalysisFlags.ReportDiagnostics) context.RegisterCompilationStartAction( Sub(startContext) Dim facts As New DesignerTypeFacts(startContext.Compilation) startContext.RegisterSyntaxNodeAction( Sub(nodeContext) AnalyzeInitializeComponent(nodeContext, facts), SyntaxKind.SubBlock) End Sub) End Sub Private Shared Sub AnalyzeInitializeComponent(context As SyntaxNodeAnalysisContext, facts As DesignerTypeFacts) Dim method = DirectCast(context.Node, MethodBlockSyntax) Dim statement As MethodStatementSyntax = method.SubOrFunctionStatement If Not DesignerTypeFacts.IsDesignerFile(method.SyntaxTree) _ OrElse Not String.Equals(statement.Identifier.ValueText, "InitializeComponent", StringComparison.OrdinalIgnoreCase) Then Return End If Dim methodSymbol = TryCast( context.SemanticModel.GetDeclaredSymbol( statement, context.CancellationToken), IMethodSymbol) If methodSymbol Is Nothing _ OrElse Not DesignerTypeFacts.IsInitializeComponent(methodSymbol) _ OrElse Not facts.IsDesignerDeclaration( methodSymbol.ContainingType, method.SyntaxTree) Then Return End If For Each node As SyntaxNode In method.Statements.SelectMany( Function(item) item.DescendantNodesAndSelf( descendIntoChildren:=Function(child) Not TypeOf child Is LambdaExpressionSyntax)) context.CancellationToken.ThrowIfCancellationRequested() Dim token As SyntaxToken Dim descriptor As DiagnosticDescriptor = Nothing Dim construct As String = Nothing If TypeOf node Is ForBlockSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "For loop" ElseIf TypeOf node Is ForEachBlockSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "For Each loop" ElseIf TypeOf node Is WhileBlockSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "While loop" ElseIf TypeOf node Is DoLoopBlockSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "Do loop" ElseIf TypeOf node Is MultiLineIfBlockSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "If statement" ElseIf TypeOf node Is SingleLineIfStatementSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "If statement" ElseIf TypeOf node Is SelectBlockSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "Select statement" ElseIf TypeOf node Is GoToStatementSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "GoTo statement" ElseIf TypeOf node Is NameOfExpressionSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedNameOfExpression ElseIf TypeOf node Is TernaryConditionalExpressionSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedConditionalExpression ElseIf TypeOf node Is BinaryConditionalExpressionSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedNullCoalescingExpression ElseIf TypeOf node Is ConditionalAccessExpressionSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedNullConditionalExpression ElseIf TypeOf node Is InterpolatedStringExpressionSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInterpolatedString ElseIf TypeOf node Is LambdaExpressionSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_visualBasicUnsupportedAnonymousFunction ElseIf TypeOf node Is TryBlockSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "Try statement" ElseIf TypeOf node Is SyncLockBlockSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "SyncLock statement" ElseIf TypeOf node Is UsingBlockSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "Using statement" ElseIf TypeOf node Is AwaitExpressionSyntax Then token = node.GetFirstToken() descriptor = SharedDiagnosticDescriptors.s_unsupportedInitializeComponentCode construct = "Await expression" End If If descriptor IsNot Nothing Then Dim diagnostic As Diagnostic = If( construct Is Nothing, Diagnostic.Create(descriptor, token.GetLocation()), Diagnostic.Create(descriptor, token.GetLocation(), construct)) context.ReportDiagnostic(diagnostic) End If Next End Sub End Class End Namespace