1- using System . Linq ;
1+ using System . Linq ;
22using Microsoft . CodeAnalysis ;
3+ using Microsoft . CodeAnalysis . CSharp ;
34using Microsoft . CodeAnalysis . CSharp . Syntax ;
45using static Cleipnir . Flows . SourceGenerator . Utils ;
56
@@ -12,75 +13,67 @@ public class FlowsSourceGenerator : IIncrementalGenerator
1213 private const string UnitFlowType = "Cleipnir.Flows.Flow`1" ;
1314 private const string ResultFlowType = "Cleipnir.Flows.Flow`2" ;
1415 private const string IgnoreAttribute = "Cleipnir.Flows.SourceGeneration.Ignore" ;
15-
16- private volatile INamedTypeSymbol ? _paramlessFlowTypeSymbol ;
17- private volatile INamedTypeSymbol ? _unitFlowTypeSymbol ;
18- private volatile INamedTypeSymbol ? _resultFlowTypeSymbol ;
19- private volatile INamedTypeSymbol ? _ignoreAttribute ;
20-
16+
2117 public void Initialize ( IncrementalGeneratorInitializationContext context )
2218 {
23- // Initialization logic
2419 var provider = context . SyntaxProvider . ForAttributeWithMetadataName (
2520 "Cleipnir.Flows.GenerateFlowsAttribute" ,
2621 ( node , ctx ) => node is ClassDeclarationSyntax ,
2722 transform : ( ctx , _ ) => Transform ( ctx )
2823 ) . Where ( flowInformation => flowInformation is not null ) ;
29-
24+
3025 context . RegisterSourceOutput (
3126 provider ,
3227 ( ctx , generatedFlowInformation ) =>
3328 ctx . AddSource ( generatedFlowInformation ! . FileName , generatedFlowInformation . GeneratedCode )
3429 ) ;
3530 }
3631
37- public GeneratedFlowInformation ? Transform ( GeneratorAttributeSyntaxContext context )
32+ private static GeneratedFlowInformation ? Transform ( GeneratorAttributeSyntaxContext context )
3833 {
39-
40- if ( _paramlessFlowTypeSymbol == null )
41- {
42- var complication = context . SemanticModel . Compilation ;
43- _unitFlowTypeSymbol = complication . GetTypeByMetadataName ( UnitFlowType ) ;
44- _resultFlowTypeSymbol = complication . GetTypeByMetadataName ( ResultFlowType ) ;
45- _ignoreAttribute = complication . GetTypeByMetadataName ( IgnoreAttribute ) ;
46- _paramlessFlowTypeSymbol = complication . GetTypeByMetadataName ( ParamlessFlowType ) ;
47- }
34+ var compilation = context . SemanticModel . Compilation ;
35+ var paramlessFlowTypeSymbol = compilation . GetTypeByMetadataName ( ParamlessFlowType ) ;
36+ var unitFlowTypeSymbol = compilation . GetTypeByMetadataName ( UnitFlowType ) ;
37+ var resultFlowTypeSymbol = compilation . GetTypeByMetadataName ( ResultFlowType ) ;
38+ var ignoreAttributeSymbol = compilation . GetTypeByMetadataName ( IgnoreAttribute ) ;
4839
49- if ( _paramlessFlowTypeSymbol == null || _unitFlowTypeSymbol == null || _resultFlowTypeSymbol == null )
40+ if ( paramlessFlowTypeSymbol == null || unitFlowTypeSymbol == null || resultFlowTypeSymbol == null )
5041 return null ;
5142
5243 var classDeclaration = ( ClassDeclarationSyntax ) context . TargetNode ;
53- if ( classDeclaration . Modifiers . Any ( m => m . Value is "private" ) )
44+ if ( classDeclaration . Modifiers . Any ( m => m . IsKind ( SyntaxKind . PrivateKeyword ) ) )
5445 return null ;
5546
56- var accessibilityModifier = classDeclaration . Modifiers . Any ( m => m . Value is "public" )
47+ var accessibilityModifier = classDeclaration . Modifiers . Any ( m => m . IsKind ( SyntaxKind . PublicKeyword ) )
5748 ? "public"
5849 : "internal" ;
5950
6051 var semanticModel = context . SemanticModel ;
6152 var flowType = ( INamedTypeSymbol ? ) semanticModel . GetDeclaredSymbol ( classDeclaration ) ;
62-
63- if (
64- flowType == null ||
65- ! InheritsFromParamlessFlowType ( flowType , _paramlessFlowTypeSymbol ) &&
66- ! InheritsFromFlowType ( flowType , _unitFlowTypeSymbol ) &&
67- ! InheritsFromFlowType ( flowType , _resultFlowTypeSymbol )
68- ) return null ;
6953
70- if ( flowType . ContainingType != null || flowType . IsFileLocal )
54+ if ( flowType == null ||
55+ ( ! InheritsFromParamlessFlowType ( flowType , paramlessFlowTypeSymbol ) &&
56+ ! InheritsFromFlowType ( flowType , unitFlowTypeSymbol ) &&
57+ ! InheritsFromFlowType ( flowType , resultFlowTypeSymbol ) ) )
7158 return null ;
7259
73- var hasIgnoreAttribute = flowType
74- . GetAttributes ( )
75- . Any ( a => SymbolEqualityComparer . Default . Equals ( a . AttributeClass , _ignoreAttribute ) ) ;
76- if ( hasIgnoreAttribute )
60+ if ( flowType . ContainingType != null || flowType . IsFileLocal )
7761 return null ;
78-
62+
63+ if ( ignoreAttributeSymbol != null )
64+ {
65+ var hasIgnoreAttribute = flowType
66+ . GetAttributes ( )
67+ . Any ( a => SymbolEqualityComparer . Default . Equals ( a . AttributeClass , ignoreAttributeSymbol ) ) ;
68+ if ( hasIgnoreAttribute )
69+ return null ;
70+ }
71+
7972 var baseType = flowType . BaseType ;
8073 if ( baseType == null )
8174 return null ;
82-
83- if ( InheritsFromParamlessFlowType ( flowType , _paramlessFlowTypeSymbol ) )
75+
76+ if ( InheritsFromParamlessFlowType ( flowType , paramlessFlowTypeSymbol ) )
8477 return GenerateCode (
8578 new FlowInformation (
8679 flowType ,
@@ -93,13 +86,21 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
9386 ) ;
9487
9588 var baseTypeTypeArguments = baseType . TypeArguments ;
96- var paramType = ( INamedTypeSymbol ? ) ( baseTypeTypeArguments . Length > 0 ? baseTypeTypeArguments [ 0 ] : null ) ;
97- var resultType = ( INamedTypeSymbol ? ) ( baseTypeTypeArguments . Length == 2 ? baseTypeTypeArguments [ 1 ] : null ) ;
89+ var paramType = baseTypeTypeArguments . Length > 0
90+ ? baseTypeTypeArguments [ 0 ] as INamedTypeSymbol
91+ : null ;
92+ var resultType = baseTypeTypeArguments . Length == 2
93+ ? baseTypeTypeArguments [ 1 ] as INamedTypeSymbol
94+ : null ;
9895
9996 var runMethod = flowType . GetMembers ( )
10097 . OfType < IMethodSymbol > ( )
101- . Single ( m => m . Name == "Run" && m . IsOverride ) ;
102- var parameterName = runMethod . Parameters . Single ( ) . Name ;
98+ . FirstOrDefault ( m => m . Name == "Run" && m . IsOverride ) ;
99+
100+ if ( runMethod == null || runMethod . Parameters . Length == 0 )
101+ return null ;
102+
103+ var parameterName = runMethod . Parameters [ 0 ] . Name ;
103104
104105 return
105106 GenerateCode (
@@ -114,55 +115,55 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
114115 ) ;
115116 }
116117
117- private GeneratedFlowInformation GenerateCode ( FlowInformation flowInformation )
118+ private static GeneratedFlowInformation GenerateCode ( FlowInformation flowInformation )
118119 {
119120 var flowsName = $ "{ flowInformation . FlowTypeSymbol . Name } s";
120121 var flowsNamespace = GetNamespace ( flowInformation . FlowTypeSymbol ) ;
121122 var flowType = GetFullyQualifiedName ( flowInformation . FlowTypeSymbol ) ;
122123 var flowName = flowInformation . FlowTypeSymbol . Name ;
123- var paramType = flowInformation . ParamTypeSymbol == null
124- ? null
124+ var paramType = flowInformation . ParamTypeSymbol == null
125+ ? null
125126 : GetFullyQualifiedName ( flowInformation . ParamTypeSymbol ) ;
126- var resultType = flowInformation . ResultTypeSymbol != null
127+ var resultType = flowInformation . ResultTypeSymbol != null
127128 ? GetFullyQualifiedName ( flowInformation . ResultTypeSymbol )
128129 : null ;
129130
130131 var accessibilityModifier = flowInformation . AccessibilityModifier ;
131-
132+
132133 string generatedCode ;
133134 if ( flowInformation . Paramless )
134135 {
135- generatedCode =
136+ generatedCode =
136137$@ "namespace { flowsNamespace }
137138{{
138139 #nullable enable
139140 [Cleipnir.Flows.SourceGeneration.SourceGeneratedFlowsAttribute]
140141 { accessibilityModifier } class { flowsName } : Cleipnir.Flows.Flows<{ flowType } >
141- {{
142+ {{
142143 public { flowsName } (Cleipnir.Flows.FlowsContainer flowsContainer, string flowName = ""{ flowName } "", Cleipnir.Flows.FlowOptions? options = null)
143- : base(flowName, flowsContainer, options) {{ }}
144+ : base(flowName, flowsContainer, options) {{ }}
144145 }}
145- #nullable disable
146- }}" ;
146+ #nullable restore
147+ }}" ;
147148 }
148149 else if ( resultType == null )
149150 {
150- generatedCode =
151+ generatedCode =
151152$@ "namespace { flowsNamespace }
152153{{
153154 #nullable enable
154155 [Cleipnir.Flows.SourceGeneration.SourceGeneratedFlowsAttribute]
155156 { accessibilityModifier } class { flowsName } : Cleipnir.Flows.Flows<{ flowType } , { paramType } >
156157 {{
157158 public { flowsName } (Cleipnir.Flows.FlowsContainer flowsContainer, string flowName = ""{ flowName } "", Cleipnir.Flows.FlowOptions? options = null)
158- : base(flowName, flowsContainer, options) {{ }}
159+ : base(flowName, flowsContainer, options) {{ }}
159160 }}
160- #nullable disable
161+ #nullable restore
161162}}" ;
162163 }
163164 else
164165 {
165- generatedCode =
166+ generatedCode =
166167$@ "namespace { flowsNamespace }
167168{{
168169 #nullable enable
@@ -172,11 +173,11 @@ private GeneratedFlowInformation GenerateCode(FlowInformation flowInformation)
172173 public { flowsName } (Cleipnir.Flows.FlowsContainer flowsContainer, string flowName = ""{ flowName } "", Cleipnir.Flows.FlowOptions? options = null)
173174 : base(flowName, flowsContainer, options) {{ }}
174175 }}
175- #nullable disable
176+ #nullable restore
176177}}" ;
177178 }
178-
179+
179180 return new GeneratedFlowInformation ( generatedCode , GetFileName ( flowInformation ) ) ;
180181 }
181182 }
182- }
183+ }
0 commit comments