|
5 | 5 |
|
6 | 6 | using System; |
7 | 7 | using System.Collections; |
| 8 | +using System.Collections.Concurrent; |
8 | 9 | using System.Collections.Generic; |
| 10 | +using System.Collections.Immutable; |
9 | 11 | using System.Linq; |
10 | 12 | using Microsoft.CodeAnalysis.CSharp.Symbols; |
11 | 13 | using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; |
12 | 14 | using Microsoft.CodeAnalysis.CSharp.Syntax; |
13 | 15 | using Microsoft.CodeAnalysis.CSharp.Test.Utilities; |
| 16 | +using Microsoft.CodeAnalysis.Diagnostics; |
14 | 17 | using Microsoft.CodeAnalysis.Emit; |
15 | 18 | using Microsoft.CodeAnalysis.Test.Utilities; |
16 | 19 | using Microsoft.CodeAnalysis.VisualBasic; |
@@ -36055,4 +36058,166 @@ .method public hidebysig specialname static int32 get_P2 ( int32 '' ) cil manage |
36055 | 36058 | var comp = CreateCompilationWithIL(source, ilSrc); |
36056 | 36059 | comp.VerifyEmitDiagnostics(); |
36057 | 36060 | } |
| 36061 | + |
| 36062 | + [Fact] |
| 36063 | + public void AnalyzerActions_01() |
| 36064 | + { |
| 36065 | + var src = """ |
| 36066 | +static class E |
| 36067 | +{ |
| 36068 | + extension<T>([Attr] T t) |
| 36069 | + { |
| 36070 | + [Attr2] |
| 36071 | + public void M() { } |
| 36072 | + |
| 36073 | + [Attr3] |
| 36074 | + public int P => 0; |
| 36075 | + } |
| 36076 | +} |
| 36077 | +"""; |
| 36078 | + |
| 36079 | + var analyzer = new AnalyzerActions_01_Analyzer(); |
| 36080 | + var comp = CreateCompilation(src); |
| 36081 | + comp.GetAnalyzerDiagnostics([analyzer], null).Verify(); |
| 36082 | + |
| 36083 | + AssertEx.SetEqual([ |
| 36084 | + "Attr2 -> void E.<>E__0<T>.M()", |
| 36085 | + "M -> void E.<>E__0<T>.M()", |
| 36086 | + "Attr3 -> System.Int32 E.<>E__0<T>.P { get; }", |
| 36087 | + "P -> System.Int32 E.<>E__0<T>.P { get; }", |
| 36088 | + "T -> E.<>E__0<T>", |
| 36089 | + "Attr -> E.<>E__0<T>", |
| 36090 | + "extension -> E.<>E__0<T>"], |
| 36091 | + analyzer._results.ToArray()); |
| 36092 | + } |
| 36093 | + |
| 36094 | + private class AnalyzerActions_01_Analyzer : DiagnosticAnalyzer |
| 36095 | + { |
| 36096 | + public ConcurrentQueue<string> _results = new ConcurrentQueue<string>(); |
| 36097 | + |
| 36098 | + private static readonly DiagnosticDescriptor Descriptor = |
| 36099 | + new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); |
| 36100 | + |
| 36101 | + public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [Descriptor]; |
| 36102 | + |
| 36103 | + public override void Initialize(AnalysisContext context) |
| 36104 | + { |
| 36105 | + context.RegisterSyntaxNodeAction(handle, SyntaxKind.ExtensionDeclaration); |
| 36106 | + context.RegisterSyntaxNodeAction(handle, SyntaxKind.IdentifierName); |
| 36107 | + context.RegisterSyntaxNodeAction(handle, SyntaxKind.MethodDeclaration); |
| 36108 | + context.RegisterSyntaxNodeAction(handle, SyntaxKind.PropertyDeclaration); |
| 36109 | + |
| 36110 | + void handle(SyntaxNodeAnalysisContext context) |
| 36111 | + { |
| 36112 | + _results.Enqueue(print(context)); |
| 36113 | + Assert.Same(context.Node.SyntaxTree, context.ContainingSymbol!.DeclaringSyntaxReferences.Single().SyntaxTree); |
| 36114 | + } |
| 36115 | + |
| 36116 | + static string print(SyntaxNodeAnalysisContext context) |
| 36117 | + { |
| 36118 | + var syntaxString = context.Node switch |
| 36119 | + { |
| 36120 | + ExtensionDeclarationSyntax => "extension", |
| 36121 | + MethodDeclarationSyntax method => method.Identifier.ValueText, |
| 36122 | + PropertyDeclarationSyntax property => property.Identifier.ValueText, |
| 36123 | + _ => context.Node.ToString() |
| 36124 | + }; |
| 36125 | + |
| 36126 | + return $"{syntaxString} -> {context.ContainingSymbol.ToTestDisplayString()}"; |
| 36127 | + } |
| 36128 | + } |
| 36129 | + } |
| 36130 | + |
| 36131 | + [Fact] |
| 36132 | + public void AnalyzerActions_02() |
| 36133 | + { |
| 36134 | + var src = """ |
| 36135 | +static class E |
| 36136 | +{ |
| 36137 | + extension<T>(T t) |
| 36138 | + { |
| 36139 | + public void M() { } |
| 36140 | + public int P => 0; |
| 36141 | + } |
| 36142 | +} |
| 36143 | +"""; |
| 36144 | + |
| 36145 | + var analyzer = new AnalyzerActions_02_Analyzer(); |
| 36146 | + var comp = CreateCompilation(src); |
| 36147 | + comp.GetAnalyzerDiagnostics([analyzer], null).Verify(); |
| 36148 | + |
| 36149 | + AssertEx.SetEqual([ |
| 36150 | + "System.Int32 E.<>E__0<T>.P.get", |
| 36151 | + "void E.<>E__0<T>.M()", |
| 36152 | + "E.<>E__0<T>", |
| 36153 | + "System.Int32 E.<>E__0<T>.P { get; }", |
| 36154 | + "E"], |
| 36155 | + analyzer._results.ToArray()); |
| 36156 | + } |
| 36157 | + |
| 36158 | + private class AnalyzerActions_02_Analyzer : DiagnosticAnalyzer |
| 36159 | + { |
| 36160 | + public ConcurrentQueue<string> _results = new ConcurrentQueue<string>(); |
| 36161 | + |
| 36162 | + private static readonly DiagnosticDescriptor Descriptor = |
| 36163 | + new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); |
| 36164 | + |
| 36165 | + public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [Descriptor]; |
| 36166 | + |
| 36167 | + public override void Initialize(AnalysisContext context) |
| 36168 | + { |
| 36169 | + context.RegisterSymbolAction(handle, SymbolKind.NamedType); |
| 36170 | + context.RegisterSymbolAction(handle, SymbolKind.Method); |
| 36171 | + context.RegisterSymbolAction(handle, SymbolKind.Property); |
| 36172 | + |
| 36173 | + void handle(SymbolAnalysisContext context) |
| 36174 | + { |
| 36175 | + _results.Enqueue(context.Symbol.ToTestDisplayString()); |
| 36176 | + } |
| 36177 | + } |
| 36178 | + } |
| 36179 | + |
| 36180 | + [Fact] |
| 36181 | + public void AnalyzerActions_03() |
| 36182 | + { |
| 36183 | + var src = """ |
| 36184 | +static class E |
| 36185 | +{ |
| 36186 | + extension<T>(T t) |
| 36187 | + { |
| 36188 | + public void M() { } |
| 36189 | + public int P { get { return 0; } } |
| 36190 | + } |
| 36191 | +} |
| 36192 | +"""; |
| 36193 | + |
| 36194 | + var analyzer = new AnalyzerActions_03_Analyzer(); |
| 36195 | + var comp = CreateCompilation(src); |
| 36196 | + comp.GetAnalyzerDiagnostics([analyzer], null).Verify(); |
| 36197 | + |
| 36198 | + AssertEx.SetEqual([ |
| 36199 | + "public void M() { } -> void E.<>E__0<T>.M()", |
| 36200 | + "get { return 0; } -> System.Int32 E.<>E__0<T>.P.get"], |
| 36201 | + analyzer._results.ToArray()); |
| 36202 | + } |
| 36203 | + |
| 36204 | + private class AnalyzerActions_03_Analyzer : DiagnosticAnalyzer |
| 36205 | + { |
| 36206 | + public ConcurrentQueue<string> _results = new ConcurrentQueue<string>(); |
| 36207 | + |
| 36208 | + private static readonly DiagnosticDescriptor Descriptor = |
| 36209 | + new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); |
| 36210 | + |
| 36211 | + public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [Descriptor]; |
| 36212 | + |
| 36213 | + public override void Initialize(AnalysisContext context) |
| 36214 | + { |
| 36215 | + context.RegisterOperationAction(handle, OperationKind.MethodBody); |
| 36216 | + |
| 36217 | + void handle(OperationAnalysisContext context) |
| 36218 | + { |
| 36219 | + _results.Enqueue($"{context.Operation.Syntax.ToString()} -> {context.ContainingSymbol.ToTestDisplayString()}"); |
| 36220 | + } |
| 36221 | + } |
| 36222 | + } |
36058 | 36223 | } |
0 commit comments