66using Microsoft . CodeAnalysis ;
77using Microsoft . CodeAnalysis . CSharp . Syntax ;
88
9- namespace Bunit . Web . Stubs ;
9+ namespace Bunit . Web . Stubs . AddStubMethodStubGenerator ;
1010
1111/// <summary>
1212/// Generator that creates a stub that mimics the public surface of a Component.
1313/// </summary>
1414[ Generator ]
15- public class StubGenerator : IIncrementalGenerator
15+ public class AddStubGenerator : IIncrementalGenerator
1616{
17- private const string CascadingParameterAttributeQualifier = "Microsoft.AspNetCore.Components.CascadingParameterAttribute" ;
18- private const string ParameterAttributeQualifier = "Microsoft.AspNetCore.Components.ParameterAttribute" ;
19-
2017 /// <inheritdoc/>
2118 public void Initialize ( IncrementalGeneratorInitializationContext context )
2219 {
@@ -32,7 +29,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
3229 static ( spc , source ) => Execute ( source , spc ) ) ;
3330 }
3431
35- private static StubClassInfo GetStubClassInfo ( GeneratorSyntaxContext context )
32+ private static AddStubClassInfo GetStubClassInfo ( GeneratorSyntaxContext context )
3633 {
3734 var invocation = context . Node as InvocationExpressionSyntax ;
3835 if ( ! IsComponentFactoryStubMethod ( invocation , context . SemanticModel ) )
@@ -50,7 +47,7 @@ private static StubClassInfo GetStubClassInfo(GeneratorSyntaxContext context)
5047 var line = lineSpan . StartLinePosition . Line + 1 ;
5148 var column = lineSpan . Span . Start . Character + context . Node . ToString ( ) . IndexOf ( "AddStub" , StringComparison . Ordinal ) + 1 ;
5249
53- return new StubClassInfo
50+ return new AddStubClassInfo
5451 {
5552 StubClassName = $ "{ symbol . Name } Stub",
5653 TargetTypeNamespace = symbol . ContainingNamespace . ToDisplayString ( ) ,
@@ -86,12 +83,12 @@ static string GetInterceptorFilePath(SyntaxTree tree, Compilation compilation)
8683 }
8784 }
8885
89- private static void Execute ( ImmutableArray < StubClassInfo > classInfos , SourceProductionContext context )
86+ private static void Execute ( ImmutableArray < AddStubClassInfo > classInfos , SourceProductionContext context )
9087 {
9188 foreach ( var stubClassGrouped in classInfos . GroupBy ( c => c . UniqueQualifier ) )
9289 {
9390 var stubbedComponentGroup = stubClassGrouped . First ( ) ;
94- var didStubComponent = GenerateStubComponent ( stubbedComponentGroup , context ) ;
91+ var didStubComponent = StubComponentBuilder . GenerateStubComponent ( stubbedComponentGroup , context ) ;
9592 if ( didStubComponent is false )
9693 {
9794 return ;
@@ -101,82 +98,9 @@ private static void Execute(ImmutableArray<StubClassInfo> classInfos, SourceProd
10198 }
10299 }
103100
104- private static bool GenerateStubComponent ( StubClassInfo classInfo , SourceProductionContext context )
105- {
106- var hasSomethingToStub = false ;
107- var targetTypeSymbol = ( INamedTypeSymbol ) classInfo ! . TargetType ;
108- var sourceBuilder = new StringBuilder ( ) ;
109-
110- sourceBuilder . AppendLine ( $ "namespace { classInfo . TargetTypeNamespace } ;") ;
111- sourceBuilder . AppendLine ( ) ;
112- sourceBuilder . AppendLine ( $ "internal partial class { classInfo . StubClassName } : global::Microsoft.AspNetCore.Components.ComponentBase") ;
113- sourceBuilder . Append ( "{" ) ;
114-
115- foreach ( var member in targetTypeSymbol
116- . GetMembers ( )
117- . OfType < IPropertySymbol > ( )
118- . Where ( p => p . GetAttributes ( )
119- . Any ( attr =>
120- attr . AttributeClass ? . ToDisplayString ( ) ==
121- ParameterAttributeQualifier ||
122- attr . AttributeClass ? . ToDisplayString ( ) ==
123- CascadingParameterAttributeQualifier ) ) )
124- {
125- sourceBuilder . AppendLine ( ) ;
126-
127- hasSomethingToStub = true ;
128- var propertyType = member . Type . ToDisplayString ( ) ;
129- var propertyName = member . Name ;
130-
131- var attributeLine = GetAttributeLine ( member ) ;
132- sourceBuilder . AppendLine ( attributeLine ) ;
133-
134- sourceBuilder . AppendLine ( $ "\t public { propertyType } { propertyName } {{ get; set; }}") ;
135- }
136-
137- sourceBuilder . AppendLine ( "}" ) ;
138-
139- if ( hasSomethingToStub )
140- {
141- context . AddSource ( $ "{ classInfo . StubClassName } .g.cs", sourceBuilder . ToString ( ) ) ;
142- }
143-
144- return hasSomethingToStub ;
145101
146- string GetAttributeLine ( ISymbol member )
147- {
148- var attribute = member . GetAttributes ( ) . First ( attr =>
149- attr . AttributeClass ? . ToDisplayString ( ) == ParameterAttributeQualifier ||
150- attr . AttributeClass ? . ToDisplayString ( ) == CascadingParameterAttributeQualifier ) ;
151-
152- var attributeLine = new StringBuilder ( "\t [" ) ;
153- if ( attribute . AttributeClass ? . ToDisplayString ( ) == ParameterAttributeQualifier )
154- {
155- attributeLine . Append ( $ "global::{ ParameterAttributeQualifier } ") ;
156- var captureUnmatchedValuesArg = attribute . NamedArguments
157- . FirstOrDefault ( arg => arg . Key == "CaptureUnmatchedValues" ) . Value ;
158- if ( captureUnmatchedValuesArg . Value is bool captureUnmatchedValues )
159- {
160- var captureString = captureUnmatchedValues ? "true" : "false" ;
161- attributeLine . Append ( $ "(CaptureUnmatchedValues = { captureString } )") ;
162- }
163- }
164- else if ( attribute . AttributeClass ? . ToDisplayString ( ) == CascadingParameterAttributeQualifier )
165- {
166- attributeLine . Append ( $ "global::{ CascadingParameterAttributeQualifier } ") ;
167- var nameArg = attribute . NamedArguments . FirstOrDefault ( arg => arg . Key == "Name" ) . Value ;
168- if ( ! nameArg . IsNull )
169- {
170- attributeLine . Append ( $ "(Name = \" { nameArg . Value } \" )") ;
171- }
172- }
173-
174- attributeLine . Append ( "]" ) ;
175- return attributeLine . ToString ( ) ;
176- }
177- }
178102
179- private static void GenerateInterceptorCode ( StubClassInfo stubbedComponentGroup , IEnumerable < StubClassInfo > stubClassGrouped , SourceProductionContext context )
103+ private static void GenerateInterceptorCode ( AddStubClassInfo stubbedComponentGroup , IEnumerable < AddStubClassInfo > stubClassGrouped , SourceProductionContext context )
180104 {
181105 // Generate the attribute
182106 const string attribute = @"namespace System.Runtime.CompilerServices
@@ -222,7 +146,7 @@ public InterceptsLocationAttribute(string filePath, int line, int column)
222146 }
223147}
224148
225- internal sealed class StubClassInfo
149+ internal sealed class AddStubClassInfo
226150{
227151 public string StubClassName { get ; set ; }
228152 public string TargetTypeNamespace { get ; set ; }
0 commit comments