提交 9c97fcf7 编写于 作者: M Manish Vasani

Merge pull request #911 from mavasani/Issue592

Fix couple of issues in CSharpDeclarationComputer (issue #592): 

1.Add declaration info for ArrowExpressionClauseSyntax: For properties and indexers, this node declares the getter method symbol whose IsImplicitlyDeclared flag is false and hence the analyzer symbol actions need to be invoked for this getter.

2.Previously executable code block actions for nodes within ArrowExpressionClauseSyntax were executed with parenting property symbol as the owning symbol. This change fixes it to have the declared getter method symbol as the owner of executable block for ArrowExpressionClauseSyntax.

I have added IDE and compiler driver tests for symbol analyzer, syntax node analyzer and executable code block analyzer for expression bodied members.
......@@ -125,6 +125,18 @@ private static bool InvalidLevel(int? level)
return;
}
case SyntaxKind.ArrowExpressionClause:
{
// Arrow expression clause declares getter symbol for properties and indexers.
var parentProperty = node.Parent as BasePropertyDeclarationSyntax;
if (parentProperty != null)
{
builder.Add(GetExpressionBodyDeclarationInfo(parentProperty, (ArrowExpressionClauseSyntax)node, model, getSymbol, cancellationToken));
}
return;
}
case SyntaxKind.PropertyDeclaration:
{
var t = (PropertyDeclarationSyntax)node;
......@@ -133,7 +145,12 @@ private static bool InvalidLevel(int? level)
foreach (var decl in t.AccessorList.Accessors) ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken);
}
builder.Add(GetDeclarationInfo(model, node, getSymbol, cancellationToken, t.Initializer, t.ExpressionBody));
if (t.ExpressionBody != null)
{
ComputeDeclarations(model, t.ExpressionBody, shouldSkip, getSymbol, builder, levelsToCompute, cancellationToken);
}
builder.Add(GetDeclarationInfo(model, node, getSymbol, cancellationToken, t.Initializer));
return;
}
......@@ -148,12 +165,13 @@ private static bool InvalidLevel(int? level)
}
}
var codeBlocks = t.ParameterList != null ? t.ParameterList.Parameters.Select(p => p.Default) : SpecializedCollections.EmptyEnumerable<SyntaxNode>();
if (t.ExpressionBody != null)
{
codeBlocks = codeBlocks.Concat(t.ExpressionBody);
ComputeDeclarations(model, t.ExpressionBody, shouldSkip, getSymbol, builder, levelsToCompute, cancellationToken);
}
var codeBlocks = t.ParameterList != null ? t.ParameterList.Parameters.Select(p => p.Default) : SpecializedCollections.EmptyEnumerable<SyntaxNode>();
builder.Add(GetDeclarationInfo(model, node, getSymbol, codeBlocks, cancellationToken));
return;
}
......@@ -206,6 +224,22 @@ private static bool InvalidLevel(int? level)
}
}
private static DeclarationInfo GetExpressionBodyDeclarationInfo(
BasePropertyDeclarationSyntax declarationWithExpressionBody,
ArrowExpressionClauseSyntax expressionBody,
SemanticModel model,
bool getSymbol,
CancellationToken cancellationToken)
{
// TODO: use 'model.GetDeclaredSymbol(expressionBody)' when compiler is fixed to return the getter symbol for it.
var declaredAccessor = getSymbol ? (model.GetDeclaredSymbol(declarationWithExpressionBody, cancellationToken) as IPropertySymbol)?.GetMethod : null;
return new DeclarationInfo(
declaredNode: expressionBody,
executableCodeBlocks: ImmutableArray.Create<SyntaxNode>(expressionBody),
declaredSymbol: declaredAccessor);
}
/// <summary>
/// Gets the expression-body syntax from an expression-bodied member. The
/// given syntax must be for a member which could contain an expression-body.
......
......@@ -615,8 +615,8 @@ public override void Initialize(AnalysisContext context)
SymbolKind.Namespace, SymbolKind.NamedType, SymbolKind.Event, SymbolKind.Field, SymbolKind.Method, SymbolKind.Property);
}
}
[Fact]
[Fact]
private void TestDisabledAnalyzers()
{
var fullyDisabledAnalyzer = new FullyDisabledAnalyzer();
......@@ -635,79 +635,7 @@ private void TestDisabledAnalyzers()
Assert.True(partiallyDisabledAnalyzer.IsDiagnosticAnalyzerSuppressed(options));
}
private class CodeBlockAnalyzer : DiagnosticAnalyzer
{
public static DiagnosticDescriptor Desciptor1 = new TriggerDiagnosticDescriptor("CodeBlockDiagnostic");
public static DiagnosticDescriptor Desciptor2 = new TriggerDiagnosticDescriptor("EqualsValueDiagnostic");
public static DiagnosticDescriptor Desciptor3 = new TriggerDiagnosticDescriptor("ConstructorInitializerDiagnostic");
public static DiagnosticDescriptor Desciptor4 = new TriggerDiagnosticDescriptor("PropertyExpressionBodyDiagnostic");
public static DiagnosticDescriptor Desciptor5 = new TriggerDiagnosticDescriptor("IndexerExpressionBodyDiagnostic");
public static DiagnosticDescriptor Desciptor6 = new TriggerDiagnosticDescriptor("MethodExpressionBodyDiagnostic");
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
get
{
return ImmutableArray.Create(Desciptor1, Desciptor2, Desciptor3, Desciptor4, Desciptor5, Desciptor6);
}
}
public override void Initialize(AnalysisContext context)
{
context.RegisterCodeBlockStartAction<SyntaxKind>(new NodeAnalyzer().Initialize);
context.RegisterCodeBlockEndAction(OnCodeBlockEnded);
}
public static void OnCodeBlockEnded(CodeBlockEndAnalysisContext context)
{
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor1, Location.None));
}
protected class NodeAnalyzer
{
public void Initialize(CodeBlockStartAnalysisContext<CSharp.SyntaxKind> analysisContext)
{
analysisContext.RegisterSyntaxNodeAction(
(context) =>
{
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor2, Location.None));
},
CSharp.SyntaxKind.EqualsValueClause);
analysisContext.RegisterSyntaxNodeAction(
(context) =>
{
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor3, Location.None));
},
CSharp.SyntaxKind.BaseConstructorInitializer);
analysisContext.RegisterSyntaxNodeAction(
(context) =>
{
DiagnosticDescriptor descriptor;
switch (context.Node.Parent.Kind())
{
case SyntaxKind.PropertyDeclaration:
descriptor = Desciptor4;
break;
case SyntaxKind.IndexerDeclaration:
descriptor = Desciptor5;
break;
default:
descriptor = Desciptor6;
break;
}
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(descriptor, Location.None));
},
CSharp.SyntaxKind.ArrowExpressionClause);
}
}
}
[Fact, WorkItem(1008059)]
private void TestCodeBlockAnalyzersForNoExecutableCode()
{
string noExecutableCodeSource = @"
......@@ -717,14 +645,14 @@ public abstract class C
public int field;
public abstract int Method();
}";
var analyzers = new DiagnosticAnalyzer[] { new CodeBlockAnalyzer() };
var analyzers = new DiagnosticAnalyzer[] { new CodeBlockOrSyntaxNodeAnalyzer(isCodeBlockAnalyzer: true) };
CreateCompilationWithMscorlib45(noExecutableCodeSource)
.VerifyDiagnostics()
.VerifyAnalyzerDiagnostics(analyzers);
}
[Fact, WorkItem(1008059)]
[Fact, WorkItem(1008059)]
private void TestCodeBlockAnalyzersForBaseConstructorInitializer()
{
string baseCtorSource = @"
......@@ -737,7 +665,7 @@ public class C : B
{
public C() : base(x: 10) {}
}";
var analyzers = new DiagnosticAnalyzer[] { new CodeBlockAnalyzer() };
var analyzers = new DiagnosticAnalyzer[] { new CodeBlockOrSyntaxNodeAnalyzer(isCodeBlockAnalyzer: true)};
CreateCompilationWithMscorlib45(baseCtorSource)
.VerifyDiagnostics()
......@@ -746,8 +674,8 @@ public class C : B
Diagnostic("CodeBlockDiagnostic"),
Diagnostic("CodeBlockDiagnostic"));
}
[Fact, WorkItem(1067286)]
[Fact, WorkItem(1067286)]
private void TestCodeBlockAnalyzersForExpressionBody()
{
string source = @"
......@@ -757,7 +685,7 @@ public class B
public int Method() => 0;
public int this[int i] => 0;
}";
var analyzers = new DiagnosticAnalyzer[] { new CodeBlockAnalyzer() };
var analyzers = new DiagnosticAnalyzer[] { new CodeBlockOrSyntaxNodeAnalyzer(isCodeBlockAnalyzer: true) };
CreateCompilationWithMscorlib45(source)
.VerifyDiagnostics()
......@@ -770,6 +698,46 @@ public class B
Diagnostic("MethodExpressionBodyDiagnostic"));
}
[Fact, WorkItem(592)]
private void TestSyntaxNodeAnalyzersForExpressionBody()
{
string source = @"
public class B
{
public int Property => 0;
public int Method() => 0;
public int this[int i] => 0;
}";
var analyzers = new DiagnosticAnalyzer[] { new CodeBlockOrSyntaxNodeAnalyzer(isCodeBlockAnalyzer: false) };
CreateCompilationWithMscorlib45(source)
.VerifyDiagnostics()
.VerifyAnalyzerDiagnostics(analyzers, null, null,
Diagnostic("PropertyExpressionBodyDiagnostic"),
Diagnostic("IndexerExpressionBodyDiagnostic"),
Diagnostic("MethodExpressionBodyDiagnostic"));
}
[Fact, WorkItem(592)]
private void TestMethodSymbolAnalyzersForExpressionBody()
{
string source = @"
public class B
{
public int Property => 0;
public int Method() => 0;
public int this[int i] => 0;
}";
var analyzers = new DiagnosticAnalyzer[] { new MethodSymbolAnalyzer() };
CreateCompilationWithMscorlib45(source)
.VerifyDiagnostics()
.VerifyAnalyzerDiagnostics(analyzers, null, null,
Diagnostic("MethodSymbolDiagnostic", "0").WithArguments("B.Property.get").WithLocation(4, 28),
Diagnostic("MethodSymbolDiagnostic", "Method").WithArguments("B.Method()").WithLocation(5, 16),
Diagnostic("MethodSymbolDiagnostic", "0").WithArguments("B.this[int].get").WithLocation(6, 31));
}
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class FieldDeclarationAnalyzer : DiagnosticAnalyzer
{
......@@ -868,5 +836,107 @@ private void TestDescriptorForConfigurableCompilerDiagnostics()
}
}
}
public class CodeBlockOrSyntaxNodeAnalyzer : DiagnosticAnalyzer
{
private readonly bool _isCodeBlockAnalyzer;
public static DiagnosticDescriptor Desciptor1 = new TriggerDiagnosticDescriptor("CodeBlockDiagnostic");
public static DiagnosticDescriptor Desciptor2 = new TriggerDiagnosticDescriptor("EqualsValueDiagnostic");
public static DiagnosticDescriptor Desciptor3 = new TriggerDiagnosticDescriptor("ConstructorInitializerDiagnostic");
public static DiagnosticDescriptor Desciptor4 = new TriggerDiagnosticDescriptor("PropertyExpressionBodyDiagnostic");
public static DiagnosticDescriptor Desciptor5 = new TriggerDiagnosticDescriptor("IndexerExpressionBodyDiagnostic");
public static DiagnosticDescriptor Desciptor6 = new TriggerDiagnosticDescriptor("MethodExpressionBodyDiagnostic");
public CodeBlockOrSyntaxNodeAnalyzer(bool isCodeBlockAnalyzer)
{
_isCodeBlockAnalyzer = isCodeBlockAnalyzer;
}
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
get { return ImmutableArray.Create(Desciptor1, Desciptor2, Desciptor3, Desciptor4, Desciptor5, Desciptor6); }
}
public override void Initialize(AnalysisContext context)
{
if (_isCodeBlockAnalyzer)
{
context.RegisterCodeBlockStartAction<SyntaxKind>(OnCodeBlockStarted);
context.RegisterCodeBlockEndAction(OnCodeBlockEnded);
}
else
{
Action<Action<SyntaxNodeAnalysisContext>, ImmutableArray<SyntaxKind>> registerMethod =
(action, Kinds) => context.RegisterSyntaxNodeAction(action, Kinds);
var analyzer = new NodeAnalyzer();
analyzer.Initialize(registerMethod);
}
}
public static void OnCodeBlockEnded(CodeBlockEndAnalysisContext context)
{
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor1, Location.None));
}
public static void OnCodeBlockStarted(CodeBlockStartAnalysisContext<SyntaxKind> context)
{
Action<Action<SyntaxNodeAnalysisContext>, ImmutableArray<SyntaxKind>> registerMethod =
(action, Kinds) => context.RegisterSyntaxNodeAction(action, Kinds);
var analyzer = new NodeAnalyzer();
analyzer.Initialize(registerMethod);
}
protected class NodeAnalyzer
{
public void Initialize(Action<Action<SyntaxNodeAnalysisContext>, ImmutableArray<SyntaxKind>> registerSyntaxNodeAction)
{
registerSyntaxNodeAction(context => { context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor2, Location.None)); },
ImmutableArray.Create(SyntaxKind.EqualsValueClause));
registerSyntaxNodeAction(context => { context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor3, Location.None)); },
ImmutableArray.Create(SyntaxKind.BaseConstructorInitializer));
registerSyntaxNodeAction(context =>
{
var descriptor = default(DiagnosticDescriptor);
switch (CSharpExtensions.Kind(context.Node.Parent))
{
case SyntaxKind.PropertyDeclaration:
descriptor = Desciptor4;
break;
case SyntaxKind.IndexerDeclaration:
descriptor = Desciptor5;
break;
default:
descriptor = Desciptor6;
break;
}
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(descriptor, Location.None));
}, ImmutableArray.Create(SyntaxKind.ArrowExpressionClause));
}
}
}
public class MethodSymbolAnalyzer : DiagnosticAnalyzer
{
public static DiagnosticDescriptor Desciptor1 = new DiagnosticDescriptor("MethodSymbolDiagnostic", "MethodSymbolDiagnostic", "{0}", "MethodSymbolDiagnostic", DiagnosticSeverity.Warning, isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
get { return ImmutableArray.Create(Desciptor1); }
}
public override void Initialize(AnalysisContext context)
{
context.RegisterSymbolAction(ctxt =>
{
var method = ((IMethodSymbol)ctxt.Symbol);
ctxt.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor1, method.Locations[0], method.ToDisplayString()));
}, SymbolKind.Method);
}
}
}
}
......@@ -720,8 +720,10 @@ public class B
Using workspace = TestWorkspaceFactory.CreateWorkspace(test)
Dim project = workspace.CurrentSolution.Projects.Single()
Dim analyzer = New CodeBlockAnalyzer()
Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer))
' Test code block analyzer
Dim analyzer As DiagnosticAnalyzer = New CodeBlockOrSyntaxNodeAnalyzer(isCodeBlockAnalyzer:=True)
Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(analyzer))
project = project.AddAnalyzerReference(analyzerReference)
Dim diagnosticService = New DiagnosticAnalyzerService()
......@@ -735,10 +737,96 @@ public class B
Dim incrementalAnalyzer = diagnosticService.CreateIncrementalAnalyzer(workspace)
Dim diagnostics = diagnosticService.GetDiagnosticsForSpanAsync(document, fullSpan, CancellationToken.None).WaitAndGetResult(CancellationToken.None)
Assert.Equal(6, diagnostics.Count())
Assert.Equal(3, diagnostics.Where(Function(d) d.Id = CodeBlockAnalyzer.Desciptor1.Id).Count)
Assert.Equal(1, diagnostics.Where(Function(d) d.Id = CodeBlockAnalyzer.Desciptor4.Id).Count)
Assert.Equal(1, diagnostics.Where(Function(d) d.Id = CodeBlockAnalyzer.Desciptor5.Id).Count)
Assert.Equal(1, diagnostics.Where(Function(d) d.Id = CodeBlockAnalyzer.Desciptor6.Id).Count)
Assert.Equal(3, diagnostics.Where(Function(d) d.Id = CodeBlockOrSyntaxNodeAnalyzer.Desciptor1.Id).Count)
Assert.Equal(1, diagnostics.Where(Function(d) d.Id = CodeBlockOrSyntaxNodeAnalyzer.Desciptor4.Id).Count)
Assert.Equal(1, diagnostics.Where(Function(d) d.Id = CodeBlockOrSyntaxNodeAnalyzer.Desciptor5.Id).Count)
Assert.Equal(1, diagnostics.Where(Function(d) d.Id = CodeBlockOrSyntaxNodeAnalyzer.Desciptor6.Id).Count)
End Using
End Sub
<Fact, WorkItem(592)>
Private Sub TestSyntaxNodeAnalyzersForExpressionBody()
Dim test = <Workspace>
<Project Language="C#" CommonReferences="true">
<Document>
public class B
{
public int Property => 0;
public int Method() => 0;
public int this[int i] => 0;
}
</Document>
</Project>
</Workspace>
Using workspace = TestWorkspaceFactory.CreateWorkspace(test)
Dim project = workspace.CurrentSolution.Projects.Single()
' Test syntax node analyzer
Dim analyzer As DiagnosticAnalyzer = New CodeBlockOrSyntaxNodeAnalyzer(isCodeBlockAnalyzer:=False)
Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(analyzer))
project = project.AddAnalyzerReference(analyzerReference)
Dim diagnosticService = New DiagnosticAnalyzerService()
Dim descriptorsMap = diagnosticService.GetDiagnosticDescriptors(project)
Assert.Equal(1, descriptorsMap.Count)
Dim document = project.Documents.Single()
Dim fullSpan = document.GetSyntaxRootAsync().WaitAndGetResult(CancellationToken.None).FullSpan
Dim incrementalAnalyzer = diagnosticService.CreateIncrementalAnalyzer(workspace)
Dim diagnostics = diagnosticService.GetDiagnosticsForSpanAsync(document, fullSpan, CancellationToken.None).WaitAndGetResult(CancellationToken.None)
Assert.Equal(3, diagnostics.Count())
Assert.Equal(1, diagnostics.Where(Function(d) d.Id = CodeBlockOrSyntaxNodeAnalyzer.Desciptor4.Id).Count)
Assert.Equal(1, diagnostics.Where(Function(d) d.Id = CodeBlockOrSyntaxNodeAnalyzer.Desciptor5.Id).Count)
Assert.Equal(1, diagnostics.Where(Function(d) d.Id = CodeBlockOrSyntaxNodeAnalyzer.Desciptor6.Id).Count)
End Using
End Sub
<Fact, WorkItem(592)>
Private Sub TestMethodSymbolAnalyzersForExpressionBody()
Dim test = <Workspace>
<Project Language="C#" CommonReferences="true">
<Document>
public class B
{
public int Property => 0;
public int Method() => 0;
public int this[int i] => 0;
}
</Document>
</Project>
</Workspace>
Using workspace = TestWorkspaceFactory.CreateWorkspace(test)
Dim project = workspace.CurrentSolution.Projects.Single()
' Test method symbol analyzer
Dim analyzer As DiagnosticAnalyzer = New MethodSymbolAnalyzer
Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(analyzer))
project = project.AddAnalyzerReference(analyzerReference)
Dim diagnosticService = New DiagnosticAnalyzerService()
Dim descriptorsMap = diagnosticService.GetDiagnosticDescriptors(project)
Assert.Equal(1, descriptorsMap.Count)
Dim document = project.Documents.Single()
Dim fullSpan = document.GetSyntaxRootAsync().WaitAndGetResult(CancellationToken.None).FullSpan
Dim incrementalAnalyzer = diagnosticService.CreateIncrementalAnalyzer(workspace)
Dim diagnostics = diagnosticService.GetDiagnosticsForSpanAsync(document, fullSpan, CancellationToken.None).
WaitAndGetResult(CancellationToken.None).
OrderBy(Function(d) d.TextSpan.Start).ToArray
Assert.Equal(3, diagnostics.Count)
Assert.True(diagnostics.All(Function(d) d.Id = MethodSymbolAnalyzer.Desciptor1.Id))
Assert.Equal("B.Property.get", diagnostics(0).Message)
Assert.Equal("B.Method()", diagnostics(1).Message)
Assert.Equal("B.this[int].get", diagnostics(2).Message)
End Using
End Sub
......@@ -1135,9 +1223,11 @@ public class B
End Class
End Class
Private Class CodeBlockAnalyzer
Private Class CodeBlockOrSyntaxNodeAnalyzer
Inherits DiagnosticAnalyzer
Private ReadOnly _isCodeBlockAnalyzer As Boolean
Public Shared Desciptor1 As DiagnosticDescriptor = New TriggerDiagnosticDescriptor("CodeBlockDiagnostic")
Public Shared Desciptor2 As DiagnosticDescriptor = New TriggerDiagnosticDescriptor("EqualsValueDiagnostic")
Public Shared Desciptor3 As DiagnosticDescriptor = New TriggerDiagnosticDescriptor("ConstructorInitializerDiagnostic")
......@@ -1145,6 +1235,10 @@ public class B
Public Shared Desciptor5 As DiagnosticDescriptor = New TriggerDiagnosticDescriptor("IndexerExpressionBodyDiagnostic")
Public Shared Desciptor6 As DiagnosticDescriptor = New TriggerDiagnosticDescriptor("MethodExpressionBodyDiagnostic")
Public Sub New(isCodeBlockAnalyzer As Boolean)
_isCodeBlockAnalyzer = isCodeBlockAnalyzer
End Sub
Public Overrides ReadOnly Property SupportedDiagnostics() As ImmutableArray(Of DiagnosticDescriptor)
Get
Return ImmutableArray.Create(Desciptor1, Desciptor2, Desciptor3, Desciptor4, Desciptor5, Desciptor6)
......@@ -1152,45 +1246,79 @@ public class B
End Property
Public Overrides Sub Initialize(context As AnalysisContext)
context.RegisterCodeBlockStartAction(Of CodeAnalysis.CSharp.SyntaxKind)(AddressOf New NodeAnalyzer().Initialize)
context.RegisterCodeBlockEndAction(AddressOf OnCodeBlockEnded)
If _isCodeBlockAnalyzer Then
context.RegisterCodeBlockStartAction(Of CodeAnalysis.CSharp.SyntaxKind)(AddressOf OnCodeBlockStarted)
context.RegisterCodeBlockEndAction(AddressOf OnCodeBlockEnded)
Else
Dim analyzer = New NodeAnalyzer
analyzer.Initialize(Sub(action, Kinds) context.RegisterSyntaxNodeAction(action, Kinds))
End If
End Sub
Public Shared Sub OnCodeBlockEnded(context As CodeBlockEndAnalysisContext)
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor1, Location.None))
End Sub
Public Shared Sub OnCodeBlockStarted(context As CodeBlockStartAnalysisContext(Of CodeAnalysis.CSharp.SyntaxKind))
Dim analyzer = New NodeAnalyzer
analyzer.Initialize(Sub(action, Kinds) context.RegisterSyntaxNodeAction(action, Kinds))
End Sub
Protected Class NodeAnalyzer
Public Sub Initialize(analysisContext As CodeBlockStartAnalysisContext(Of CodeAnalysis.CSharp.SyntaxKind))
analysisContext.RegisterSyntaxNodeAction(Sub(context)
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor2, Location.None))
End Sub, CodeAnalysis.CSharp.SyntaxKind.EqualsValueClause)
analysisContext.RegisterSyntaxNodeAction(Sub(context)
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor3, Location.None))
End Sub, CodeAnalysis.CSharp.SyntaxKind.BaseConstructorInitializer)
analysisContext.RegisterSyntaxNodeAction(Sub(context)
Dim descriptor As DiagnosticDescriptor
Select Case CodeAnalysis.CSharp.CSharpExtensions.Kind(context.Node.Parent)
Case CodeAnalysis.CSharp.SyntaxKind.PropertyDeclaration
descriptor = Desciptor4
Exit Select
Case CodeAnalysis.CSharp.SyntaxKind.IndexerDeclaration
descriptor = Desciptor5
Exit Select
Case Else
descriptor = Desciptor6
Exit Select
End Select
context.ReportDiagnostic(Diagnostic.Create(descriptor, Location.None))
End Sub, CodeAnalysis.CSharp.SyntaxKind.ArrowExpressionClause)
Public Sub Initialize(registerSyntaxNodeAction As Action(Of Action(Of SyntaxNodeAnalysisContext), ImmutableArray(Of CodeAnalysis.CSharp.SyntaxKind)))
registerSyntaxNodeAction(Sub(context)
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor2, Location.None))
End Sub, ImmutableArray.Create(CodeAnalysis.CSharp.SyntaxKind.EqualsValueClause))
registerSyntaxNodeAction(Sub(context)
context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(Desciptor3, Location.None))
End Sub, ImmutableArray.Create(CodeAnalysis.CSharp.SyntaxKind.BaseConstructorInitializer))
registerSyntaxNodeAction(Sub(context)
Dim descriptor As DiagnosticDescriptor
Select Case CodeAnalysis.CSharp.CSharpExtensions.Kind(context.Node.Parent)
Case CodeAnalysis.CSharp.SyntaxKind.PropertyDeclaration
descriptor = Desciptor4
Exit Select
Case CodeAnalysis.CSharp.SyntaxKind.IndexerDeclaration
descriptor = Desciptor5
Exit Select
Case Else
descriptor = Desciptor6
Exit Select
End Select
context.ReportDiagnostic(Diagnostic.Create(descriptor, context.Node.GetLocation))
End Sub, ImmutableArray.Create(CodeAnalysis.CSharp.SyntaxKind.ArrowExpressionClause))
End Sub
End Class
End Class
Private Class MethodSymbolAnalyzer
Inherits DiagnosticAnalyzer
Public Shared Desciptor1 As DiagnosticDescriptor = New DiagnosticDescriptor("MethodSymbolDiagnostic",
"MethodSymbolDiagnostic",
"{0}",
"MethodSymbolDiagnostic",
DiagnosticSeverity.Warning,
isEnabledByDefault:=True)
Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
Get
Return ImmutableArray.Create(Desciptor1)
End Get
End Property
Public Overrides Sub Initialize(context As AnalysisContext)
context.RegisterSymbolAction(Sub(ctxt)
Dim method = (DirectCast(ctxt.Symbol, IMethodSymbol))
ctxt.ReportDiagnostic(Diagnostic.Create(Desciptor1, method.Locations(0), method.ToDisplayString))
End Sub, SymbolKind.Method)
End Sub
End Class
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册