Skip to content

Commit dfb4801

Browse files
committed
Filter out more irrelevant classes and use StrinBuilder for complete generation
1 parent 4d90040 commit dfb4801

1 file changed

Lines changed: 40 additions & 30 deletions

File tree

src/AutoFilterer.Generators/FilterGenerator.cs

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
1919
{
2020
var classDeclarations = context.SyntaxProvider
2121
.CreateSyntaxProvider(
22-
predicate: static (s, _) => s is ClassDeclarationSyntax { AttributeLists.Count: > 0 },
22+
predicate: static (s, _) => IsSyntaxTargetForGeneration(s),
2323
transform: static (ctx, _) => GetSemanticTargetForGeneration(ctx))
2424
.Where(static m => m is not null);
2525

@@ -28,6 +28,17 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
2828
context.RegisterSourceOutput(compilationAndClasses, (spc, source) => Execute(source.Left, source.Right, spc));
2929
}
3030

31+
private static bool IsSyntaxTargetForGeneration(SyntaxNode node)
32+
{
33+
if (node is not ClassDeclarationSyntax classDeclaration || classDeclaration.AttributeLists.Count == 0) {
34+
return false;
35+
}
36+
37+
return classDeclaration.AttributeLists
38+
.SelectMany(al => al.Attributes)
39+
.Any(a => a.Name.ToString().EnsureEndsWith("Attribute").EndsWith(nameof(GenerateAutoFilterAttribute)));
40+
}
41+
3142
private static ClassDeclarationSyntax GetSemanticTargetForGeneration(GeneratorSyntaxContext context)
3243
{
3344
var classDeclaration = (ClassDeclarationSyntax)context.Node;
@@ -36,12 +47,8 @@ private static ClassDeclarationSyntax GetSemanticTargetForGeneration(GeneratorSy
3647
{
3748
foreach (var attribute in attributeList.Attributes)
3849
{
39-
var symbolInfo = context.SemanticModel.GetSymbolInfo(attribute);
40-
var attributeSymbol = symbolInfo.Symbol as IMethodSymbol;
41-
42-
var fullName = attributeSymbol?.ContainingType.ToDisplayString()
43-
?? attribute.Name.ToString();
44-
50+
var attributeSymbol = context.SemanticModel.GetSymbolInfo(attribute).Symbol as IMethodSymbol;
51+
var fullName = attributeSymbol?.ContainingType.ToDisplayString() ?? attribute.Name.ToString();
4552
if (fullName.EnsureEndsWith("Attribute").EndsWith(nameof(GenerateAutoFilterAttribute)))
4653
{
4754
return classDeclaration;
@@ -58,7 +65,7 @@ private static void Execute(Compilation compilation, ImmutableArray<ClassDeclara
5865
return;
5966
}
6067

61-
foreach (var classSyntax in classes)
68+
foreach (var classSyntax in classes.Distinct())
6269
{
6370
var model = compilation.GetSemanticModel(classSyntax.SyntaxTree);
6471
if (model.GetDeclaredSymbol(classSyntax) is not { } symbol)
@@ -68,13 +75,16 @@ private static void Execute(Compilation compilation, ImmutableArray<ClassDeclara
6875

6976
var attribute = symbol.GetAttributes()
7077
.FirstOrDefault(a => a.AttributeClass?.Name == nameof(GenerateAutoFilterAttribute));
71-
var namespaceParam = attribute?.ConstructorArguments.FirstOrDefault().Value?.ToString().Trim('\"'); // Temprorary... Attribute has only one argument for now.
72-
var realNamespace = GetNamespaceRecursively(symbol.ContainingNamespace);
78+
var targetNamespace = attribute?.ConstructorArguments.FirstOrDefault().Value?.ToString().Trim('\"'); // Temprorary... Attribute has only one argument for now.
79+
if (string.IsNullOrEmpty(targetNamespace)) {
80+
targetNamespace = GetNamespaceRecursively(symbol.ContainingNamespace);
81+
}
7382

74-
var properties = symbol.GetMembers().OfType<IPropertySymbol>()
75-
.Where(x => !x.IsStatic && !x.ContainingType.IsGenericType && x.Kind == SymbolKind.Property);
83+
var properties = symbol.GetMembers()
84+
.OfType<IPropertySymbol>()
85+
.Where(x => !x.IsStatic && !x.IsIndexer && x.Kind == SymbolKind.Property);
7686

77-
var sourceCode = GetFilterDtoCode(symbol.Name, properties, namespaceParam ?? realNamespace);
87+
var sourceCode = GetFilterDtoCode(symbol.Name, properties, targetNamespace);
7888

7989
context.AddSource($"{symbol.Name}FilterDto.g.cs", SourceText.From(sourceCode, Encoding.UTF8));
8090
}
@@ -83,19 +93,15 @@ private static void Execute(Compilation compilation, ImmutableArray<ClassDeclara
8393
private static string GetFilterDtoCode(string className, IEnumerable<IPropertySymbol> properties,
8494
string @namespace = null)
8595
{
86-
var start = $@"
87-
using System;
88-
using AutoFilterer;
89-
using AutoFilterer.Attributes;
90-
using AutoFilterer.Types;
91-
92-
namespace {@namespace ?? "AutoFilterer.Filters"}
93-
{{
94-
public partial class {className}Filter : PaginationFilterBase
95-
{{
96-
";
97-
98-
var body = new StringBuilder();
96+
var generatedCode = new StringBuilder();
97+
generatedCode.AppendLine("using System;");
98+
generatedCode.AppendLine("using AutoFilterer.Attributes;");
99+
generatedCode.AppendLine("using AutoFilterer.Types;");
100+
generatedCode.AppendLine();
101+
generatedCode.AppendLine($"namespace {@namespace}");
102+
generatedCode.AppendLine("{");
103+
generatedCode.AppendLine($"\tpublic partial class {className}Filter : PaginationFilterBase");
104+
generatedCode.AppendLine("\t{");
99105

100106
foreach (var property in properties)
101107
{
@@ -105,14 +111,18 @@ public partial class {className}Filter : PaginationFilterBase
105111
propertyType = mapped;
106112
}
107113

108-
if (propertyType.Equals(nameof(String), StringComparison.InvariantCultureIgnoreCase))
114+
if (property.Type.SpecialType == SpecialType.System_String)
109115
{
110-
body.AppendLine("\t\t[ToLowerContainsComparison]");
116+
generatedCode.AppendLine("\t\t[ToLowerContainsComparison]");
111117
}
112-
body.AppendLine($"\t\tpublic virtual {propertyType} {property.Name} {{ get; set; }}");
118+
119+
generatedCode.AppendLine($"\t\tpublic virtual {propertyType} {property.Name} {{ get; set; }}");
113120
}
114121

115-
return start + body + "\t}\n}";
122+
generatedCode.AppendLine("\t}");
123+
generatedCode.AppendLine("}");
124+
125+
return generatedCode.ToString();
116126
}
117127

118128
private static string GetNamespaceRecursively(INamespaceSymbol symbol)

0 commit comments

Comments
 (0)