Skip to content

Commit ca28202

Browse files
committed
TODO: impl true incremental generator
1 parent 9cff3eb commit ca28202

File tree

9 files changed

+173
-14
lines changed

9 files changed

+173
-14
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System.Collections;
2+
using System.Runtime.CompilerServices;
3+
4+
namespace MemoryPack.Generator;
5+
6+
public readonly struct EquatableArray<T> : IEquatable<EquatableArray<T>>, IEnumerable<T>
7+
where T : IEquatable<T>
8+
{
9+
readonly T[]? array;
10+
11+
public EquatableArray() // for collection literal []
12+
{
13+
array = [];
14+
}
15+
16+
public EquatableArray(T[] array)
17+
{
18+
this.array = array;
19+
}
20+
21+
public static implicit operator EquatableArray<T>(T[] array)
22+
{
23+
return new EquatableArray<T>(array);
24+
}
25+
26+
public ref readonly T this[int index]
27+
{
28+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
29+
get => ref array![index];
30+
}
31+
32+
public int Length => array!.Length;
33+
34+
public ReadOnlySpan<T> AsSpan()
35+
{
36+
return array.AsSpan();
37+
}
38+
39+
public ReadOnlySpan<T>.Enumerator GetEnumerator()
40+
{
41+
return AsSpan().GetEnumerator();
42+
}
43+
44+
IEnumerator<T> IEnumerable<T>.GetEnumerator()
45+
{
46+
return array.AsEnumerable().GetEnumerator();
47+
}
48+
49+
IEnumerator IEnumerable.GetEnumerator()
50+
{
51+
return array.AsEnumerable().GetEnumerator();
52+
}
53+
54+
public bool Equals(EquatableArray<T> other)
55+
{
56+
return AsSpan().SequenceEqual(other.AsSpan());
57+
}
58+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Microsoft.CodeAnalysis;
2+
using System.Collections.Immutable;
3+
4+
namespace MemoryPack.Generator;
5+
6+
public class EquatableTypeSymbol(ITypeSymbol typeSymbol) : IEquatable<EquatableTypeSymbol>
7+
{
8+
// Used for build argument parser, maybe ok to equals name.
9+
public ITypeSymbol TypeSymbol => typeSymbol;
10+
11+
// GetMembers is called for Enum and fields is not condition for command equality.
12+
public ImmutableArray<ISymbol> GetMembers() => typeSymbol.GetMembers();
13+
14+
public TypeKind TypeKind { get; } = typeSymbol.TypeKind;
15+
public SpecialType SpecialType { get; } = typeSymbol.SpecialType;
16+
17+
public string ToFullyQualifiedFormatDisplayString() => typeSymbol.ToFullyQualifiedFormatDisplayString();
18+
public string ToDisplayString(NullableFlowState state, SymbolDisplayFormat format) => typeSymbol.ToDisplayString(state, format);
19+
20+
public bool Equals(EquatableTypeSymbol other)
21+
{
22+
if (this.TypeKind != other.TypeKind) return false;
23+
if (this.SpecialType != other.SpecialType) return false;
24+
if (this.TypeSymbol.Name != other.TypeSymbol.Name) return false;
25+
26+
return this.TypeSymbol.EqualsNamespaceAndName(other.TypeSymbol);
27+
}
28+
}
29+
30+
static class EquatableTypeSymbolExtensions
31+
{
32+
public static EquatableTypeSymbol ToEquatable(this ITypeSymbol typeSymbol) => new(typeSymbol);
33+
}

src/MemoryPack.Generator/Extensions.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,24 @@ public static string NewLine(this IEnumerable<string> source)
1212
return string.Join(Environment.NewLine, source);
1313
}
1414

15+
public static bool EqualsNamespaceAndName(this ITypeSymbol? left, ITypeSymbol? right)
16+
{
17+
if (left == null && right == null) return true;
18+
if (left == null || right == null) return false;
19+
20+
var l = left.ContainingNamespace;
21+
var r = right.ContainingNamespace;
22+
while (l != null && r != null)
23+
{
24+
if (l.Name != r.Name) return false;
25+
26+
l = l.ContainingNamespace;
27+
r = r.ContainingNamespace;
28+
}
29+
30+
return (left.Name == right.Name);
31+
}
32+
1533
public static bool ContainsAttribute(this ISymbol symbol, INamedTypeSymbol attribtue)
1634
{
1735
return symbol.GetAttributes().Any(x => SymbolEqualityComparer.Default.Equals(x.AttributeClass, attribtue));
@@ -213,6 +231,11 @@ public static IEnumerable<INamedTypeSymbol> GetAllBaseTypes(this INamedTypeSymbo
213231
}
214232
}
215233

234+
internal static string ToFullyQualifiedFormatDisplayString(this ITypeSymbol typeSymbol)
235+
{
236+
return typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
237+
}
238+
216239
public static string FullyQualifiedToString(this ISymbol symbol)
217240
{
218241
return symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);

src/MemoryPack.Generator/MemoryPack.Generator.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
5-
<LangVersion>11</LangVersion>
5+
<LangVersion>12</LangVersion>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<AnalyzerLanguage>cs</AnalyzerLanguage>
88
<Nullable>enable</Nullable>

src/MemoryPack.Generator/MemoryPackGenerator.cs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,18 @@ void RegisterMemoryPackable(IncrementalGeneratorInitializationContext context)
5555
}
5656

5757
return (string?)null;
58-
});
58+
})
59+
.WithTrackingName("MemoryPack.MemoryPackable.0_AnalyzerConfigOptionsProvider"); // annotate for IncrementalGeneratorTest
60+
61+
var parseOptions = context.ParseOptionsProvider
62+
.Select((parseOptions, token) =>
63+
{
64+
var csOptions = (CSharpParseOptions)parseOptions;
65+
var langVersion = csOptions.LanguageVersion;
66+
var net7 = csOptions.PreprocessorSymbolNames.Contains("NET7_0_OR_GREATER");
67+
return (langVersion, net7);
68+
})
69+
.WithTrackingName("MemoryPack.MemoryPackable.0_ParseOptionsProvider");
5970

6071
var typeDeclarations = context.SyntaxProvider.ForAttributeWithMetadataName(
6172
MemoryPackableAttributeFullName,
@@ -70,7 +81,8 @@ or RecordDeclarationSyntax
7081
transform: static (context, token) =>
7182
{
7283
return (TypeDeclarationSyntax)context.TargetNode;
73-
});
84+
})
85+
.WithTrackingName("MemoryPack.MemoryPackable.1_ForAttributeMemoryPackableAttribute");
7486

7587
var typeDeclarations2 = context.SyntaxProvider.ForAttributeWithMetadataName(
7688
MemoryPackUnionFormatterAttributeFullName,
@@ -81,22 +93,16 @@ or RecordDeclarationSyntax
8193
transform: static (context, token) =>
8294
{
8395
return (TypeDeclarationSyntax)context.TargetNode;
84-
});
85-
86-
var parseOptions = context.ParseOptionsProvider.Select((parseOptions, token) =>
87-
{
88-
var csOptions = (CSharpParseOptions)parseOptions;
89-
var langVersion = csOptions.LanguageVersion;
90-
var net7 = csOptions.PreprocessorSymbolNames.Contains("NET7_0_OR_GREATER");
91-
return (langVersion, net7);
92-
});
96+
})
97+
.WithTrackingName("MemoryPack.MemoryPackable.1_ForAttributeMemoryPackUnion");
9398

9499
{
95100
var source = typeDeclarations
96101
.Combine(context.CompilationProvider)
97102
.WithComparer(Comparer.Instance)
98103
.Combine(logProvider)
99-
.Combine(parseOptions);
104+
.Combine(parseOptions)
105+
.WithTrackingName("MemoryPack.MemoryPackable.2_MemoryPackableCombined");
100106

101107
context.RegisterSourceOutput(source, static (context, source) =>
102108
{
@@ -112,7 +118,8 @@ or RecordDeclarationSyntax
112118
.Combine(context.CompilationProvider)
113119
.WithComparer(Comparer.Instance)
114120
.Combine(logProvider)
115-
.Combine(parseOptions);
121+
.Combine(parseOptions)
122+
.WithTrackingName("MemoryPack.MemoryPackable.2_MemoryPackUnionCombined");
116123

117124
context.RegisterSourceOutput(source, static (context, source) =>
118125
{
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace MemoryPack.Tests.SourceGeneratorTests;
8+
9+
public class IncrementalGeneratorTest
10+
{
11+
[Fact]
12+
public void Run()
13+
{
14+
// lang=C#-test
15+
var step1 = """
16+
[MemoryPackable]
17+
public partial class MyClass
18+
{
19+
public int MyProperty { get; set; }
20+
}
21+
""";
22+
23+
// lang=C#-test
24+
var step2 = """
25+
[MemoryPackable]
26+
public partial class MyClass
27+
{
28+
public int MyProperty { get; set; }
29+
// unrelated line
30+
}
31+
""";
32+
33+
var hoge = CSharpGeneratorRunner.GetIncrementalGeneratorTrackedStepsReasons("MemoryPack.MemoryPackable.", step1, step2);
34+
35+
}
36+
}
37+
38+

0 commit comments

Comments
 (0)