@@ -19,7 +19,7 @@ namespace StyleCop.Analyzers.CodeGeneration
19
19
using Microsoft . CodeAnalysis . Text ;
20
20
21
21
[ Generator ]
22
- internal sealed class SyntaxLightupGenerator : ISourceGenerator
22
+ internal sealed class SyntaxLightupGenerator : IIncrementalGenerator
23
23
{
24
24
private enum NodeKind
25
25
{
@@ -28,33 +28,37 @@ private enum NodeKind
28
28
Concrete ,
29
29
}
30
30
31
- public void Initialize ( GeneratorInitializationContext context )
31
+ public void Initialize ( IncrementalGeneratorInitializationContext context )
32
32
{
33
+ var compilation = context . CompilationProvider ;
34
+ var syntaxFiles = context . AdditionalTextsProvider . Where ( static x => Path . GetFileName ( x . Path ) == "Syntax.xml" ) ;
35
+ context . RegisterSourceOutput (
36
+ syntaxFiles . Combine ( compilation ) ,
37
+ ( context , value ) => this . Execute ( in context , value . Right , value . Left ) ) ;
33
38
}
34
39
35
- public void Execute ( GeneratorExecutionContext context )
40
+ private void Execute ( in SourceProductionContext context , Compilation compilation , AdditionalText syntaxFile )
36
41
{
37
- var syntaxFile = context . AdditionalFiles . Single ( x => Path . GetFileName ( x . Path ) == "Syntax.xml" ) ;
38
42
var syntaxText = syntaxFile . GetText ( context . CancellationToken ) ;
39
43
if ( syntaxText is null )
40
44
{
41
45
throw new InvalidOperationException ( "Failed to read Syntax.xml" ) ;
42
46
}
43
47
44
- var syntaxData = new SyntaxData ( in context , XDocument . Parse ( syntaxText . ToString ( ) ) ) ;
48
+ var syntaxData = new SyntaxData ( compilation , XDocument . Parse ( syntaxText . ToString ( ) ) ) ;
45
49
this . GenerateSyntaxWrappers ( in context , syntaxData ) ;
46
50
this . GenerateSyntaxWrapperHelper ( in context , syntaxData . Nodes ) ;
47
51
}
48
52
49
- private void GenerateSyntaxWrappers ( in GeneratorExecutionContext context , SyntaxData syntaxData )
53
+ private void GenerateSyntaxWrappers ( in SourceProductionContext context , SyntaxData syntaxData )
50
54
{
51
55
foreach ( var node in syntaxData . Nodes )
52
56
{
53
57
this . GenerateSyntaxWrapper ( in context , syntaxData , node ) ;
54
58
}
55
59
}
56
60
57
- private void GenerateSyntaxWrapper ( in GeneratorExecutionContext context , SyntaxData syntaxData , NodeData nodeData )
61
+ private void GenerateSyntaxWrapper ( in SourceProductionContext context , SyntaxData syntaxData , NodeData nodeData )
58
62
{
59
63
if ( nodeData . WrapperName is null )
60
64
{
@@ -806,7 +810,7 @@ private void GenerateSyntaxWrapper(in GeneratorExecutionContext context, SyntaxD
806
810
context . AddSource ( nodeData . WrapperName + ".g.cs" , SourceText . From ( wrapperNamespace . ToFullString ( ) , Encoding . UTF8 ) ) ;
807
811
}
808
812
809
- private void GenerateSyntaxWrapperHelper ( in GeneratorExecutionContext context , ImmutableArray < NodeData > wrapperTypes )
813
+ private void GenerateSyntaxWrapperHelper ( in SourceProductionContext context , ImmutableArray < NodeData > wrapperTypes )
810
814
{
811
815
// private static readonly ImmutableDictionary<Type, Type> WrappedTypes;
812
816
var wrappedTypes = SyntaxFactory . FieldDeclaration (
@@ -982,6 +986,65 @@ private void GenerateSyntaxWrapperHelper(in GeneratorExecutionContext context, I
982
986
continue ;
983
987
}
984
988
989
+ if ( node . Name == nameof ( BaseNamespaceDeclarationSyntax ) )
990
+ {
991
+ // Prior to C# 10, NamespaceDeclarationSyntax was the base type for all namespace declarations.
992
+ // If the BaseNamespaceDeclarationSyntax type isn't found at runtime, we fall back
993
+ // to using this type instead.
994
+ //
995
+ // var baseNamespaceDeclarationSyntaxType = csharpCodeAnalysisAssembly.GetType(BaseNamespaceDeclarationSyntaxWrapper.WrappedTypeName)
996
+ // ?? csharpCodeAnalysisAssembly.GetType(BaseNamespaceDeclarationSyntaxWrapper.WrappedTypeName);
997
+ LocalDeclarationStatementSyntax localStatement =
998
+ SyntaxFactory . LocalDeclarationStatement ( SyntaxFactory . VariableDeclaration (
999
+ type : SyntaxFactory . IdentifierName ( "var" ) ,
1000
+ variables : SyntaxFactory . SingletonSeparatedList ( SyntaxFactory . VariableDeclarator (
1001
+ identifier : SyntaxFactory . Identifier ( "baseNamespaceDeclarationSyntaxType" ) ,
1002
+ argumentList : null ,
1003
+ initializer : SyntaxFactory . EqualsValueClause (
1004
+ SyntaxFactory . BinaryExpression (
1005
+ SyntaxKind . CoalesceExpression ,
1006
+ left : SyntaxFactory . InvocationExpression (
1007
+ expression : SyntaxFactory . MemberAccessExpression (
1008
+ SyntaxKind . SimpleMemberAccessExpression ,
1009
+ expression : SyntaxFactory . IdentifierName ( "csharpCodeAnalysisAssembly" ) ,
1010
+ name : SyntaxFactory . IdentifierName ( "GetType" ) ) ,
1011
+ argumentList : SyntaxFactory . ArgumentList ( SyntaxFactory . SingletonSeparatedList ( SyntaxFactory . Argument (
1012
+ SyntaxFactory . MemberAccessExpression (
1013
+ SyntaxKind . SimpleMemberAccessExpression ,
1014
+ expression : SyntaxFactory . IdentifierName ( node . WrapperName ) ,
1015
+ name : SyntaxFactory . IdentifierName ( "WrappedTypeName" ) ) ) ) ) ) ,
1016
+ right : SyntaxFactory . InvocationExpression (
1017
+ expression : SyntaxFactory . MemberAccessExpression (
1018
+ SyntaxKind . SimpleMemberAccessExpression ,
1019
+ expression : SyntaxFactory . IdentifierName ( "csharpCodeAnalysisAssembly" ) ,
1020
+ name : SyntaxFactory . IdentifierName ( "GetType" ) ) ,
1021
+ argumentList : SyntaxFactory . ArgumentList ( SyntaxFactory . SingletonSeparatedList ( SyntaxFactory . Argument (
1022
+ SyntaxFactory . MemberAccessExpression (
1023
+ SyntaxKind . SimpleMemberAccessExpression ,
1024
+ expression : SyntaxFactory . IdentifierName ( node . WrapperName ) ,
1025
+ name : SyntaxFactory . IdentifierName ( "FallbackWrappedTypeName" ) ) ) ) ) ) ) ) ) ) ) ) ;
1026
+
1027
+ // This is the first line of the statements that initialize 'builder', so start it with a blank line
1028
+ staticCtorStatements = staticCtorStatements . Add ( localStatement . WithLeadingBlankLine ( ) ) ;
1029
+
1030
+ // builder.Add(typeof(BaseNamespaceDeclarationSyntaxWrapper), baseNamespaceDeclarationSyntaxType);
1031
+ staticCtorStatements = staticCtorStatements . Add ( SyntaxFactory . ExpressionStatement (
1032
+ SyntaxFactory . InvocationExpression (
1033
+ expression : SyntaxFactory . MemberAccessExpression (
1034
+ SyntaxKind . SimpleMemberAccessExpression ,
1035
+ expression : SyntaxFactory . IdentifierName ( "builder" ) ,
1036
+ name : SyntaxFactory . IdentifierName ( "Add" ) ) ,
1037
+ argumentList : SyntaxFactory . ArgumentList (
1038
+ SyntaxFactory . SeparatedList (
1039
+ new [ ]
1040
+ {
1041
+ SyntaxFactory . Argument ( SyntaxFactory . TypeOfExpression ( SyntaxFactory . IdentifierName ( node . WrapperName ) ) ) ,
1042
+ SyntaxFactory . Argument ( SyntaxFactory . IdentifierName ( "baseNamespaceDeclarationSyntaxType" ) ) ,
1043
+ } ) ) ) ) ) ;
1044
+
1045
+ continue ;
1046
+ }
1047
+
985
1048
// builder.Add(typeof(ConstantPatternSyntaxWrapper), csharpCodeAnalysisAssembly.GetType(ConstantPatternSyntaxWrapper.WrappedTypeName));
986
1049
staticCtorStatements = staticCtorStatements . Add ( SyntaxFactory . ExpressionStatement (
987
1050
SyntaxFactory . InvocationExpression (
@@ -1138,12 +1201,12 @@ private sealed class SyntaxData
1138
1201
{
1139
1202
private readonly Dictionary < string , NodeData > nameToNode ;
1140
1203
1141
- public SyntaxData ( in GeneratorExecutionContext context , XDocument document )
1204
+ public SyntaxData ( Compilation compilation , XDocument document )
1142
1205
{
1143
1206
var nodesBuilder = ImmutableArray . CreateBuilder < NodeData > ( ) ;
1144
1207
foreach ( var element in document . XPathSelectElement ( "/Tree[@Root='SyntaxNode']" ) . XPathSelectElements ( "PredefinedNode|AbstractNode|Node" ) )
1145
1208
{
1146
- nodesBuilder . Add ( new NodeData ( in context , element ) ) ;
1209
+ nodesBuilder . Add ( new NodeData ( compilation , element ) ) ;
1147
1210
}
1148
1211
1149
1212
this . Nodes = nodesBuilder . ToImmutable ( ) ;
@@ -1180,7 +1243,7 @@ public SyntaxData(in GeneratorExecutionContext context, XDocument document)
1180
1243
1181
1244
private sealed class NodeData
1182
1245
{
1183
- public NodeData ( in GeneratorExecutionContext context , XElement element )
1246
+ public NodeData ( Compilation compilation , XElement element )
1184
1247
{
1185
1248
this . Kind = element . Name . LocalName switch
1186
1249
{
@@ -1192,9 +1255,9 @@ public NodeData(in GeneratorExecutionContext context, XElement element)
1192
1255
1193
1256
this . Name = element . Attribute ( "Name" ) . Value ;
1194
1257
1195
- this . ExistingType = context . Compilation . GetTypeByMetadataName ( $ "Microsoft.CodeAnalysis.CSharp.Syntax.{ this . Name } ")
1196
- ?? context . Compilation . GetTypeByMetadataName ( $ "Microsoft.CodeAnalysis.CSharp.{ this . Name } ")
1197
- ?? context . Compilation . GetTypeByMetadataName ( $ "Microsoft.CodeAnalysis.{ this . Name } ") ;
1258
+ this . ExistingType = compilation . GetTypeByMetadataName ( $ "Microsoft.CodeAnalysis.CSharp.Syntax.{ this . Name } ")
1259
+ ?? compilation . GetTypeByMetadataName ( $ "Microsoft.CodeAnalysis.CSharp.{ this . Name } ")
1260
+ ?? compilation . GetTypeByMetadataName ( $ "Microsoft.CodeAnalysis.{ this . Name } ") ;
1198
1261
if ( this . ExistingType ? . DeclaredAccessibility == Accessibility . Public )
1199
1262
{
1200
1263
this . WrapperName = null ;
0 commit comments