Skip to content

Commit bc2e420

Browse files
linkdotnetegil
authored andcommitted
collect everything - then generate
1 parent a599146 commit bc2e420

1 file changed

Lines changed: 42 additions & 27 deletions

File tree

src/bunit.generators/Web.Stubs/StubGenerator.cs

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Immutable;
12
using System.Linq;
23
using System.Text;
34
using Microsoft.CodeAnalysis;
@@ -18,7 +19,8 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
1819
.CreateSyntaxProvider(
1920
predicate: static (s, _) => s is InvocationExpressionSyntax,
2021
transform: static (ctx, _) => GetStubClassInfo(ctx))
21-
.Where(static m => m is not null);
22+
.Where(static m => m is not null)
23+
.Collect();
2224

2325
context.RegisterSourceOutput(
2426
classesToStub,
@@ -78,17 +80,21 @@ static string GetInterceptorFilePath(SyntaxTree tree, Compilation compilation)
7880
}
7981
}
8082

81-
private static void Execute(StubClassInfo classInfo, SourceProductionContext context)
83+
private static void Execute(ImmutableArray<StubClassInfo> classInfos, SourceProductionContext context)
8284
{
83-
var didStubComponent = GenerateStubComponent(classInfo, context);
84-
if (didStubComponent is false)
85+
foreach (var stubClassGrouped in classInfos.GroupBy(c => c.UniqueQualifier))
8586
{
86-
return;
87-
}
87+
var stubbedComponentGroup = stubClassGrouped.First();
88+
var didStubComponent = GenerateStubComponent(stubbedComponentGroup, context);
89+
if (didStubComponent is false)
90+
{
91+
return;
92+
}
8893

89-
// Generate the attribute
90-
const string attribute = @"namespace System.Runtime.CompilerServices
94+
// Generate the attribute
95+
const string attribute = @"namespace System.Runtime.CompilerServices
9196
{
97+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
9298
sealed file class InterceptsLocationAttribute : Attribute
9399
{
94100
public InterceptsLocationAttribute(string filePath, int line, int column)
@@ -100,25 +106,33 @@ public InterceptsLocationAttribute(string filePath, int line, int column)
100106
}
101107
}";
102108

103-
// Generate the interceptor
104-
var interceptorSource = new StringBuilder();
105-
interceptorSource.AppendLine(attribute);
106-
interceptorSource.AppendLine();
107-
interceptorSource.AppendLine("namespace Bunit");
108-
interceptorSource.AppendLine("{");
109-
interceptorSource.AppendLine($"\tstatic class Interceptor{classInfo.StubClassName}");
110-
interceptorSource.AppendLine("\t{");
111-
interceptorSource.AppendLine(
112-
$"\t\t[System.Runtime.CompilerServices.InterceptsLocationAttribute(\"{classInfo.Path}\", {classInfo.Line}, {classInfo.Column})]");
113-
interceptorSource.AppendLine("\t\tpublic static global::Bunit.ComponentFactoryCollection AddGeneratedStubInterceptor<TComponent>(this global::Bunit.ComponentFactoryCollection factories)");
114-
interceptorSource.AppendLine("\t\t\twhere TComponent : Microsoft.AspNetCore.Components.IComponent");
115-
interceptorSource.AppendLine("\t\t{");
116-
interceptorSource.AppendLine($"\t\t\treturn factories.Add<global::{classInfo.TargetType.ToDisplayString()}, {classInfo.TargetTypeNamespace}.{classInfo.StubClassName}>();");
117-
interceptorSource.AppendLine("\t\t}");
118-
interceptorSource.AppendLine("\t}");
119-
interceptorSource.AppendLine("}");
120-
121-
context.AddSource($"Interceptor{classInfo.StubClassName}.g.cs", interceptorSource.ToString());
109+
// Generate the interceptor
110+
var interceptorSource = new StringBuilder();
111+
interceptorSource.AppendLine(attribute);
112+
interceptorSource.AppendLine();
113+
interceptorSource.AppendLine("namespace Bunit");
114+
interceptorSource.AppendLine("{");
115+
interceptorSource.AppendLine($"\tstatic class Interceptor{stubbedComponentGroup.StubClassName}");
116+
interceptorSource.AppendLine("\t{");
117+
118+
foreach (var hit in stubClassGrouped)
119+
{
120+
interceptorSource.AppendLine(
121+
$"\t\t[System.Runtime.CompilerServices.InterceptsLocationAttribute(\"{hit.Path}\", {hit.Line}, {hit.Column})]");
122+
}
123+
124+
interceptorSource.AppendLine(
125+
"\t\tpublic static global::Bunit.ComponentFactoryCollection AddGeneratedStubInterceptor<TComponent>(this global::Bunit.ComponentFactoryCollection factories)");
126+
interceptorSource.AppendLine("\t\t\twhere TComponent : Microsoft.AspNetCore.Components.IComponent");
127+
interceptorSource.AppendLine("\t\t{");
128+
interceptorSource.AppendLine(
129+
$"\t\t\treturn factories.Add<global::{stubbedComponentGroup.TargetType.ToDisplayString()}, {stubbedComponentGroup.TargetTypeNamespace}.{stubbedComponentGroup.StubClassName}>();");
130+
interceptorSource.AppendLine("\t\t}");
131+
interceptorSource.AppendLine("\t}");
132+
interceptorSource.AppendLine("}");
133+
134+
context.AddSource($"Interceptor{stubbedComponentGroup.StubClassName}.g.cs", interceptorSource.ToString());
135+
}
122136
}
123137

124138
private static bool GenerateStubComponent(StubClassInfo classInfo, SourceProductionContext context)
@@ -172,6 +186,7 @@ internal sealed class StubClassInfo
172186
{
173187
public string StubClassName { get; set; }
174188
public string TargetTypeNamespace { get; set; }
189+
public string UniqueQualifier => $"{TargetTypeNamespace}.{StubClassName}";
175190
public ITypeSymbol TargetType { get; set; }
176191
public string Path { get; set; }
177192
public int Line { get; set; }

0 commit comments

Comments
 (0)