Skip to content

Commit e704aa1

Browse files
feat: Implement IIncrementalGenerator instead of ISourceGenerator
Resolve #52
1 parent 44ca619 commit e704aa1

15 files changed

+188
-89
lines changed

Src/StackMemoryCollections/AttributeProcessor.cs

Lines changed: 34 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
using Microsoft.CodeAnalysis;
2+
using Microsoft.CodeAnalysis.CSharp;
3+
using Microsoft.CodeAnalysis.CSharp.Syntax;
24
using StackMemoryCollections.Generators.Primitive;
35
using StackMemoryCollections.Helpers;
46
using System;
57
using System.Collections.Generic;
8+
using System.Collections.Immutable;
69
using System.Linq;
710

811
namespace StackMemoryCollections
@@ -34,72 +37,49 @@ internal class AttributeProcessor
3437
private readonly Dictionary<string, Model.TypeInfo> _typeInfos = new Dictionary<string, Model.TypeInfo>();
3538

3639
public void FillAllTypes(
37-
INamespaceOrTypeSymbol symbol
40+
Compilation compilation,
41+
ImmutableArray<TypeDeclarationSyntax> types
3842
)
3943
{
40-
var queue = new Queue<INamespaceOrTypeSymbol>();
41-
queue.Enqueue(symbol);
42-
43-
while (queue.Count != 0)
44+
foreach (var typeDeclaration in types )
4445
{
45-
var current = queue.Dequeue();
46-
if (current is INamedTypeSymbol type &&
47-
!type.IsAbstract &&
48-
!type.IsGenericType &&
49-
!type.IsStatic &&
50-
(type.IsValueType || type.IsReferenceType))
51-
{
52-
var attributes = type.GetAttributes();
53-
var hasHelper = attributes.Any(wh => wh.AttributeClass.Name == "GenerateHelperAttribute");
54-
var hasStack = attributes.Any(wh => wh.AttributeClass.Name == "GenerateStackAttribute");
55-
var hasQueue = attributes.Any(wh => wh.AttributeClass.Name == "GenerateQueueAttribute");
56-
var hasList = attributes.Any(wh => wh.AttributeClass.Name == "GenerateListAttribute");
57-
var hasDictionary = attributes.Any(wh => wh.AttributeClass.Name == "GenerateDictionaryAttribute");
58-
var hasWrapper = attributes.Any(wh => wh.AttributeClass.Name == "GenerateWrapperAttribute");
59-
60-
if (hasHelper || hasStack || hasQueue || hasList || hasDictionary || hasWrapper)
61-
{
62-
_typeHelpers.Add(type);
46+
var type = compilation.GetSemanticModel(typeDeclaration.SyntaxTree).GetDeclaredSymbol(typeDeclaration);
6347

64-
if (hasStack)
65-
{
66-
_typeGeneratedStack.Add(type);
67-
}
48+
var attributes = type.GetAttributes();
49+
var hasHelper = attributes.Any(wh => wh.AttributeClass.Name == "GenerateHelperAttribute");
50+
var hasStack = attributes.Any(wh => wh.AttributeClass.Name == "GenerateStackAttribute");
51+
var hasQueue = attributes.Any(wh => wh.AttributeClass.Name == "GenerateQueueAttribute");
52+
var hasList = attributes.Any(wh => wh.AttributeClass.Name == "GenerateListAttribute");
53+
var hasDictionary = attributes.Any(wh => wh.AttributeClass.Name == "GenerateDictionaryAttribute");
54+
var hasWrapper = attributes.Any(wh => wh.AttributeClass.Name == "GenerateWrapperAttribute");
6855

69-
if (hasList)
70-
{
71-
_typeGeneratedList.Add(type);
72-
}
56+
if (hasHelper || hasStack || hasQueue || hasList || hasDictionary || hasWrapper)
57+
{
58+
_typeHelpers.Add(type);
7359

74-
if (hasQueue)
75-
{
76-
_typeGeneratedQueue.Add(type);
77-
}
60+
if (hasStack)
61+
{
62+
_typeGeneratedStack.Add(type);
63+
}
7864

79-
if (hasDictionary)
80-
{
81-
_typeGeneratedDictionary.Add(type);
82-
}
65+
if (hasList)
66+
{
67+
_typeGeneratedList.Add(type);
68+
}
8369

84-
if (hasWrapper)
85-
{
86-
_typeWrappers.Add(type);
87-
}
70+
if (hasQueue)
71+
{
72+
_typeGeneratedQueue.Add(type);
8873
}
89-
}
90-
else if (current is INamespaceSymbol namespaceSymbol)
91-
{
92-
if (!_containCollections && namespaceSymbol.Name == "StackMemoryCollections")
74+
75+
if (hasDictionary)
9376
{
94-
_containCollections = true;
77+
_typeGeneratedDictionary.Add(type);
9578
}
96-
}
9779

98-
foreach (var child in current.GetMembers())
99-
{
100-
if (child is INamespaceOrTypeSymbol symbolChild)
80+
if (hasWrapper)
10181
{
102-
queue.Enqueue(symbolChild);
82+
_typeWrappers.Add(type);
10383
}
10484
}
10585
}
@@ -413,7 +393,7 @@ private bool HelperMustGenerated(in System.Collections.Immutable.ImmutableArray<
413393
);
414394
}
415395

416-
public void Generate(GeneratorExecutionContext context)
396+
public void Generate(SourceProductionContext context)
417397
{
418398
if (!_containCollections)
419399
{
Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,102 @@
11
using Microsoft.CodeAnalysis;
22
using Microsoft.CodeAnalysis.CSharp;
3+
using Microsoft.CodeAnalysis.CSharp.Syntax;
4+
using StackMemoryCollections.Helpers;
5+
using System.Collections.Immutable;
6+
using System.Linq;
37

48
namespace StackMemoryCollections
59
{
610
[Generator]
7-
public partial class Generator : ISourceGenerator
11+
public partial class Generator : IIncrementalGenerator
812
{
9-
public void Execute(GeneratorExecutionContext context)
13+
public void Initialize(IncrementalGeneratorInitializationContext context)
1014
{
11-
var c = (CSharpCompilation)context.Compilation;
12-
var processor = new AttributeProcessor();
13-
processor.FillAllTypes(c.Assembly.GlobalNamespace);
14-
processor.Generate(context);
15+
//System.Diagnostics.Debugger.Launch();
16+
var classDeclarations = context.SyntaxProvider
17+
.CreateSyntaxProvider(
18+
predicate: (s, _) => IsSyntaxTargetForGeneration(s),
19+
transform: (ctx, _) => GetSemanticTargetForGeneration(ctx))
20+
.Where(m => m != null);
21+
22+
var compilationAndClasses = context.CompilationProvider.Combine(classDeclarations.Collect());
23+
24+
context.RegisterSourceOutput(compilationAndClasses,
25+
(spc, source) => Execute(source.Item1, source.Item2, spc));
26+
}
27+
28+
static bool IsSyntaxTargetForGeneration(SyntaxNode node)
29+
{
30+
if(!(node is ClassDeclarationSyntax) && !(node is StructDeclarationSyntax))
31+
{
32+
return false;
33+
}
34+
35+
var typeDeclar = (TypeDeclarationSyntax)node;
36+
if (typeDeclar.Modifiers.Any(wh => wh.IsKind(SyntaxKind.StaticKeyword)))
37+
{
38+
return false;
39+
}
40+
41+
if (typeDeclar.TypeParameterList?.Parameters.Any() == true)
42+
{
43+
return false;
44+
}
45+
46+
if (typeDeclar.Modifiers.Any(wh => wh.IsKind(SyntaxKind.AbstractKeyword)))
47+
{
48+
return false;
49+
}
50+
51+
if (typeDeclar.AttributeLists.Count == 0)
52+
{
53+
return false;
54+
}
55+
56+
return true;
1557
}
1658

17-
public void Initialize(GeneratorInitializationContext context)
59+
static TypeDeclarationSyntax GetSemanticTargetForGeneration(GeneratorSyntaxContext context)
1860
{
19-
// No initialization required for this one
61+
return GetSemanticClassOrStruct(context);
62+
}
63+
64+
static TypeDeclarationSyntax GetSemanticClassOrStruct(GeneratorSyntaxContext context)
65+
{
66+
if (!(context.Node is ClassDeclarationSyntax) && !(context.Node is StructDeclarationSyntax))
67+
{
68+
return null;
69+
}
70+
71+
var typeDeclarationSyntax = (TypeDeclarationSyntax)context.Node;
72+
foreach (var attributeListSyntax in typeDeclarationSyntax.AttributeLists)
73+
{
74+
foreach (AttributeSyntax attributeSyntax in attributeListSyntax.Attributes)
75+
{
76+
IMethodSymbol attributeSymbol = context.SemanticModel.GetSymbolInfo(attributeSyntax).Symbol as IMethodSymbol;
77+
if (attributeSymbol == null)
78+
{
79+
continue;
80+
}
81+
82+
INamedTypeSymbol attributeContainingTypeSymbol = attributeSymbol.ContainingType;
83+
84+
if (attributeContainingTypeSymbol.ContainingNamespace.GetFullNamespace().StartsWith("StackMemoryCollections."))
85+
{
86+
return typeDeclarationSyntax;
87+
}
88+
}
89+
}
90+
91+
return null;
92+
}
93+
94+
private void Execute(Compilation compilation, ImmutableArray<TypeDeclarationSyntax> types, SourceProductionContext context)
95+
{
96+
//System.Diagnostics.Debugger.Launch();
97+
var processor = new AttributeProcessor();
98+
processor.FillAllTypes(compilation, types);
99+
processor.Generate(context);
20100
}
21101
}
22102
}

Src/StackMemoryCollections/Generators/CommonHelpersGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public class CommonHelpersGenerator
77
{
88
public void GenerateCommonHelpers(
99
in List<INamedTypeSymbol> typeHelpers,
10-
in GeneratorExecutionContext context
10+
in SourceProductionContext context
1111
)
1212
{
1313
if (typeHelpers.Count == 0)

Src/StackMemoryCollections/Generators/GenerateList.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal class ListGenerator
1111

1212
public void GenerateList(
1313
in List<INamedTypeSymbol> typeList,
14-
in GeneratorExecutionContext context,
14+
in SourceProductionContext context,
1515
in Dictionary<string, Model.TypeInfo> typeInfos
1616
)
1717
{
@@ -29,7 +29,7 @@ public void GenerateList(
2929
}
3030

3131
private void GenerateList(
32-
in GeneratorExecutionContext context,
32+
in SourceProductionContext context,
3333
in INamedTypeSymbol currentType,
3434
in Model.TypeInfo typeInfo,
3535
in string listNamespace

Src/StackMemoryCollections/Generators/GenerateMemory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ internal class MemoryGenerator
88
private readonly StringBuilder _builder = new StringBuilder();
99

1010
public void GenerateMemory(
11-
in GeneratorExecutionContext context
11+
in SourceProductionContext context
1212
)
1313
{
1414
GenerateMemory(in context, "Class");
1515
GenerateMemory(in context, "Struct");
1616
}
1717

1818
private void GenerateMemory(
19-
in GeneratorExecutionContext context,
19+
in SourceProductionContext context,
2020
in string memoryNamespace
2121
)
2222
{

Src/StackMemoryCollections/Generators/GenerateQueue.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal class QueueGenerator
1111

1212
public void GenerateQueue(
1313
in List<INamedTypeSymbol> typeQueue,
14-
in GeneratorExecutionContext context,
14+
in SourceProductionContext context,
1515
in Dictionary<string, Model.TypeInfo> typeInfos
1616
)
1717
{
@@ -29,7 +29,7 @@ public void GenerateQueue(
2929
}
3030

3131
private void GenerateQueue(
32-
in GeneratorExecutionContext context,
32+
in SourceProductionContext context,
3333
in INamedTypeSymbol currentType,
3434
in Model.TypeInfo typeInfo,
3535
in string queueNamespace

Src/StackMemoryCollections/Generators/GenerateStack.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal class StackGenerator
1111

1212
public void GenerateStack(
1313
in List<INamedTypeSymbol> typeStack,
14-
in GeneratorExecutionContext context,
14+
in SourceProductionContext context,
1515
in Dictionary<string, Model.TypeInfo> typeInfos
1616
)
1717
{
@@ -29,7 +29,7 @@ public void GenerateStack(
2929
}
3030

3131
private void GenerateStack(
32-
in GeneratorExecutionContext context,
32+
in SourceProductionContext context,
3333
in INamedTypeSymbol currentType,
3434
in Model.TypeInfo typeInfo,
3535
in string stackNamespace

Src/StackMemoryCollections/Generators/GenerateWrappers.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal class WrappersGenerator
1111

1212
public void GenerateWrappers(
1313
in List<INamedTypeSymbol> typeWrappers,
14-
in GeneratorExecutionContext context,
14+
in SourceProductionContext context,
1515
in Dictionary<string, Model.TypeInfo> typeInfos
1616
)
1717
{
@@ -30,7 +30,7 @@ public void GenerateWrappers(
3030

3131
private void GenerateWrapper(
3232
in INamedTypeSymbol currentType,
33-
in GeneratorExecutionContext context,
33+
in SourceProductionContext context,
3434
in Model.TypeInfo typeInfo,
3535
in string wrapperNamespace,
3636
in Dictionary<string, Model.TypeInfo> typeInfos

Src/StackMemoryCollections/Generators/HelpersGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ internal class HelpersGenerator
1212

1313
public void GenerateHelpers(
1414
in List<INamedTypeSymbol> typeHelpers,
15-
in GeneratorExecutionContext context,
15+
in SourceProductionContext context,
1616
in Dictionary<string, Model.TypeInfo> typeInfos
1717
)
1818
{
@@ -26,7 +26,7 @@ public void GenerateHelpers(
2626
private void GenerateHelpersForType(
2727
INamedTypeSymbol currentType,
2828
Dictionary<string, Model.TypeInfo> typeInfos,
29-
GeneratorExecutionContext context
29+
SourceProductionContext context
3030
)
3131
{
3232
_builder.Clear();

Src/StackMemoryCollections/Generators/Primitive/GeneratePrimitiveList.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ internal class PrimitiveListGenerator
99
private readonly StringBuilder _builder = new StringBuilder();
1010

1111
public void GeneratePrimitiveList(
12-
in GeneratorExecutionContext context
12+
in SourceProductionContext context
1313
)
1414
{
1515
GenerateList<IntPtr>(context, 0, true);
@@ -34,7 +34,7 @@ in GeneratorExecutionContext context
3434
}
3535

3636
private void GenerateList<T>(
37-
in GeneratorExecutionContext context,
37+
in SourceProductionContext context,
3838
in int sizeOf,
3939
bool calculateSize
4040
) where T : unmanaged
@@ -46,7 +46,7 @@ bool calculateSize
4646
}
4747

4848
private void GeneratePrimitiveList<T>(
49-
in GeneratorExecutionContext context,
49+
in SourceProductionContext context,
5050
in string ListNamespace,
5151
in int sizeOf,
5252
in string sizeOfStr,

0 commit comments

Comments
 (0)