Skip to content

Commit 54af66b

Browse files
committed
0.12.1
1 parent 60fb66e commit 54af66b

File tree

6 files changed

+74
-77
lines changed

6 files changed

+74
-77
lines changed

CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
## 0.12.0
1+
## 0.12.1
2+
- Optimize compilation speed
3+
4+
## 0.12.0
25
- Breaking Changes
36
- Variant getters now return references, no more variant setters
47

Coplt.Union.Analyzers/Coplt.Union.Analyzers.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="Coplt.RoslynUtilities" Version="0.5.0">
13+
<PackageReference Include="Coplt.RoslynUtilities" Version="0.6.1">
1414
<PrivateAssets>all</PrivateAssets>
1515
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1616
</PackageReference>

Coplt.Union.Analyzers/Generators/Templates/TemplateStructUnion.cs

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Collections.Immutable;
34
using System.Linq;
45
using System.Numerics;
56
using System.Runtime.CompilerServices;
67
using System.Runtime.InteropServices;
78
using System.Security.Cryptography;
89
using System.Text;
10+
using Coplt.Analyzers.Generators.Templates;
911
using Coplt.Union.Analyzers.Resources;
1012
using Coplt.Analyzers.Utilities;
1113
using Microsoft.CodeAnalysis;
@@ -72,12 +74,12 @@ public static UnionAttr FromData(AttributeData data, List<Diagnostic> diagnostic
7274
public record struct UnionGenerateMethod(bool genToString, bool genEquals, bool genCompareTo);
7375

7476
public class TemplateStructUnion(
75-
Coplt.Analyzers.Generators.Templates.GenBase GenBase,
77+
GenBase GenBase,
7678
string Name,
7779
UnionAttr Attr,
7880
bool ReadOnly,
7981
bool IsClass,
80-
List<UnionCase> Cases,
82+
ImmutableArray<UnionCase> Cases,
8183
bool AnyGeneric,
8284
UnionGenerateMethod genMethods) : ATemplate(GenBase)
8385
{
@@ -157,7 +159,7 @@ protected override void DoGen()
157159
sb.AppendLine();
158160
GenImpl(impl_name, tags_name);
159161

160-
if (Cases.Count > 0)
162+
if (Cases.Length > 0)
161163
{
162164
sb.AppendLine();
163165
GenMake(impl_name, tags_name);
@@ -201,8 +203,8 @@ private void GenTags(string name, string spaces = " ")
201203
var type = Attr.TagsUnderlying;
202204
if (type == null)
203205
{
204-
if (Cases.Count < byte.MaxValue) type = "byte";
205-
else if (Cases.Count < short.MaxValue) type = "short";
206+
if (Cases.Length < byte.MaxValue) type = "byte";
207+
else if (Cases.Length < short.MaxValue) type = "short";
206208
else type = "int";
207209
}
208210
sb.AppendLine($"{spaces}public enum {name} : {type}");
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.Collections.Immutable;
23
using System.Linq;
34
using System.Numerics;
45
using System.Text;
@@ -19,54 +20,39 @@ public class UnionGenerator : IIncrementalGenerator
1920
public void Initialize(IncrementalGeneratorInitializationContext context)
2021
{
2122
var sources = context.SyntaxProvider.ForAttributeWithMetadataName(
22-
"Coplt.Union.UnionAttribute",
23-
static (syntax, _) => syntax is StructDeclarationSyntax or ClassDeclarationSyntax,
24-
static (ctx, _) =>
25-
{
26-
var diagnostics = new List<Diagnostic>();
27-
var attr = ctx.Attributes.First();
28-
var union_attr = UnionAttr.FromData(attr, diagnostics);
29-
var syntax = (TypeDeclarationSyntax)ctx.TargetNode;
30-
var semanticModel = ctx.SemanticModel;
31-
var symbol = (INamedTypeSymbol)ctx.TargetSymbol;
32-
var rawFullName = symbol.ToDisplayString();
33-
var nameWraps = symbol.WrapNames();
34-
var nameWrap = symbol.WrapName();
35-
var readOnly = symbol.IsReadOnly;
36-
var isClass = syntax is ClassDeclarationSyntax;
37-
var hasToString = symbol.GetMembers("ToString")
38-
.Where(s => s is IMethodSymbol)
39-
.Cast<IMethodSymbol>()
40-
.Any(s => s.TypeParameters.Length == 0 && s.Parameters.Length == 0);
41-
var NamedArguments = attr.NamedArguments.ToDictionary(a => a.Key, a => a.Value);
42-
var genToString = NamedArguments.TryGetValue("GenerateToString", out var _GenerateToString)
43-
? (bool)_GenerateToString.Value!
44-
: !hasToString;
45-
var genEquals = !NamedArguments.TryGetValue("GenerateEquals", out var _GenerateEquals) ||
46-
(bool)_GenerateEquals.Value!;
47-
var genCompareTo = !NamedArguments.TryGetValue("GenerateCompareTo", out var _GenerateCompareTo) ||
48-
(bool)_GenerateCompareTo.Value!;
49-
var genMethods = new UnionGenerateMethod(genToString, genEquals, genCompareTo);
50-
return (syntax, semanticModel, union_attr, readOnly, isClass, genMethods,
51-
rawFullName, nameWraps, nameWrap, AlwaysEq.Create(diagnostics));
52-
}
53-
)
54-
.Combine(context.CompilationProvider)
55-
.Select(static (input, _) =>
23+
"Coplt.Union.UnionAttribute",
24+
static (syntax, _) => syntax is StructDeclarationSyntax or ClassDeclarationSyntax,
25+
static (ctx, _) =>
5626
{
57-
var ((syntax, semanticModel, union_attr, readOnly, isClass, genMethods, rawFullName, nameWraps,
58-
nameWrap, diagnostics), compilation) =
59-
input;
60-
var nullable = compilation.Options.NullableContextOptions;
61-
var usings = new HashSet<string>();
62-
Utils.GetUsings(syntax, usings);
63-
var genBase = new GenBase(rawFullName, nullable, usings, nameWraps, nameWrap);
64-
var templates = syntax.Members
27+
var diagnostics = new List<Diagnostic>();
28+
var compilation = ctx.SemanticModel.Compilation;
29+
var attr = ctx.Attributes.First();
30+
var union_attr = UnionAttr.FromData(attr, diagnostics);
31+
var syntax = (TypeDeclarationSyntax)ctx.TargetNode;
32+
var semantic_model = ctx.SemanticModel;
33+
var symbol = (INamedTypeSymbol)ctx.TargetSymbol;
34+
var GenBase = Utils.BuildGenBase(syntax, symbol, compilation);
35+
var IsReadOnly = symbol.IsReadOnly;
36+
var IsClass = syntax is ClassDeclarationSyntax;
37+
var HasToString = symbol.GetMembers("ToString")
38+
.Where(s => s is IMethodSymbol)
39+
.Cast<IMethodSymbol>()
40+
.Any(s => s.TypeParameters.Length == 0 && s.Parameters.Length == 0);
41+
var NamedArguments = attr.NamedArguments.ToDictionary(a => a.Key, a => a.Value);
42+
var GenToString = NamedArguments.TryGetValue("GenerateToString", out var _GenerateToString)
43+
? (bool)_GenerateToString.Value!
44+
: !HasToString;
45+
var GenEquals = !NamedArguments.TryGetValue("GenerateEquals", out var _GenerateEquals) ||
46+
(bool)_GenerateEquals.Value!;
47+
var GenCompareTo = !NamedArguments.TryGetValue("GenerateCompareTo", out var _GenerateCompareTo) ||
48+
(bool)_GenerateCompareTo.Value!;
49+
var GenMethods = new UnionGenerateMethod(GenToString, GenEquals, GenCompareTo);
50+
var Templates = syntax.Members
6551
.Where(static t => t is InterfaceDeclarationSyntax)
6652
.Cast<InterfaceDeclarationSyntax>()
6753
.Select(t =>
6854
{
69-
var symbol = semanticModel.GetDeclaredSymbol(t);
55+
var symbol = semantic_model.GetDeclaredSymbol(t);
7056
return (t, symbol);
7157
})
7258
.Where(i =>
@@ -75,18 +61,18 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
7561
return symbol!.GetAttributes().Any(a =>
7662
a.AttributeClass?.ToDisplayString() == "Coplt.Union.UnionTemplateAttribute");
7763
})
78-
.ToArray();
79-
if (templates.Length > 1)
64+
.ToList();
65+
if (Templates.Count > 1)
8066
{
8167
var desc = Utils.MakeWarning(Id, Strings.Get("Generator.Union.Error.MultiTemplate"));
82-
foreach (var t in templates)
68+
foreach (var t in Templates)
8369
{
84-
diagnostics.Value.Add(Diagnostic.Create(desc, t.t.Identifier.GetLocation()));
70+
diagnostics.Add(Diagnostic.Create(desc, t.t.Identifier.GetLocation()));
8571
}
8672
}
87-
var cases = new List<UnionCase>();
88-
var any_generic = false;
89-
foreach (var (template, _) in templates)
73+
var cases = ImmutableArray.CreateBuilder<UnionCase>();
74+
var AnyGeneric = false;
75+
foreach (var (template, _) in Templates)
9076
{
9177
foreach (var (member, i) in template.Members.Select((a, b) => (a, b)))
9278
{
@@ -95,7 +81,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
9581
var case_name = mds.Identifier.ToString();
9682
var ret_type = mds.ReturnType.ToString();
9783
var kind = UnionCaseTypeKind.None;
98-
var member_symbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(mds)!;
84+
var member_symbol = (IMethodSymbol)semantic_model.GetDeclaredSymbol(mds)!;
9985
var tag_attr = member_symbol.GetAttributes().FirstOrDefault(a =>
10086
a.AttributeClass?.ToDisplayString() == "Coplt.Union.UnionTagAttribute");
10187
string? tag = null;
@@ -109,7 +95,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
10995
}
11096
var ret_type_symbol = member_symbol.ReturnType;
11197
var is_generic = ret_type_symbol.IsNotInstGenericType();
112-
if (is_generic) any_generic = true;
98+
if (is_generic) AnyGeneric = true;
11399
if (ret_type_symbol.IsUnmanagedType) kind = UnionCaseTypeKind.Unmanaged;
114100
else if (ret_type_symbol.IsReferenceType) kind = UnionCaseTypeKind.Class;
115101
if (is_generic)
@@ -152,7 +138,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
152138
{
153139
var desc = Utils.MakeInfo(Id,
154140
Strings.Get("Generator.Union.Info.PossiblyInvalidSymbol"));
155-
diagnostics.Value.Add(Diagnostic.Create(desc, member.GetLocation()));
141+
diagnostics.Add(Diagnostic.Create(desc, member.GetLocation()));
156142
}
157143
}
158144
cases.Add(new UnionCase(case_name, tag, ret_type, kind, is_generic));
@@ -163,37 +149,41 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
163149
Strings.Get("Generator.Union.Error.IllegalTemplateMember"));
164150
if (member is BaseTypeDeclarationSyntax bts)
165151
{
166-
diagnostics.Value.Add(Diagnostic.Create(desc, bts.Identifier.GetLocation()));
152+
diagnostics.Add(Diagnostic.Create(desc, bts.Identifier.GetLocation()));
167153
}
168154
else
169155
{
170-
diagnostics.Value.Add(Diagnostic.Create(desc, member.GetLocation()));
156+
diagnostics.Add(Diagnostic.Create(desc, member.GetLocation()));
171157
}
172158
}
173159
}
174160
}
175-
var name = syntax.Identifier.ToString();
176-
return (name, union_attr, readOnly, isClass, cases, any_generic, genMethods, genBase, diagnostics);
177-
});
161+
var Name = syntax.Identifier.ToString();
162+
return (
163+
Name, UnionAttr: union_attr, IsReadOnly, isClass: IsClass,
164+
cases.ToImmutableArray(), AnyGeneric, GenMethods, GenBase,
165+
AlwaysEq.Create(diagnostics)
166+
);
167+
}
168+
);
178169

179170
context.RegisterSourceOutput(sources, static (ctx, input) =>
180171
{
181-
var (name, union_attr, readOnly, isClass, cases, any_generic, genMethods, genBase, diagnostics) = input;
182-
if (diagnostics.Value.Count > 0)
172+
var (Name, UnionAttr, IsReadOnly, IsClass, Cases, AnyGeneric, GenMethods, GenBase, Diagnostics) = input;
173+
if (Diagnostics.Value.Count > 0)
183174
{
184-
foreach (var diagnostic in diagnostics.Value)
175+
foreach (var diagnostic in Diagnostics.Value)
185176
{
186177
ctx.ReportDiagnostic(diagnostic);
187178
}
188179
}
189180
var code = new TemplateStructUnion(
190-
genBase, name, union_attr, readOnly, isClass, cases, any_generic, genMethods
191-
)
192-
.Gen();
193-
var sourceText = SourceText.From(code, Encoding.UTF8);
194-
var rawSourceFileName = genBase.FileFullName;
195-
var sourceFileName = $"{rawSourceFileName}.union.g.cs";
196-
ctx.AddSource(sourceFileName, sourceText);
181+
GenBase, Name, UnionAttr, IsReadOnly, IsClass, Cases, AnyGeneric, GenMethods
182+
).Gen();
183+
var source_text = SourceText.From(code, Encoding.UTF8);
184+
var raw_source_file_name = GenBase.FileFullName;
185+
var sourceFileName = $"{raw_source_file_name}.union.g.cs";
186+
ctx.AddSource(sourceFileName, source_text);
197187
});
198188
}
199189
}

Coplt.Union.Source/Coplt.Union.Source.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<PropertyGroup>
66
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
77
<PackageId>Coplt.Union</PackageId>
8-
<Version>0.12.0</Version>
8+
<Version>0.12.1</Version>
99
<IsPackable>true</IsPackable>
1010
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
1111
</PropertyGroup>

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
Generate Tagged Union using source generator
1313

14+
- Source distribution, no runtime dependencies
1415
- All unmanaged types will overlap
1516
- All classes will overlap
1617
- Other types are sequential
@@ -21,14 +22,15 @@ Generate Tagged Union using source generator
2122
[Union]
2223
public readonly partial struct Union1
2324
{
25+
// This template is not used at runtime, its only purpose is to provide type symbols to the roslyn analyzer
2426
[UnionTemplate]
2527
private interface Template
2628
{
2729
int A();
2830
string B();
2931
bool C();
3032
(int a, int b) D();
31-
void E();
33+
void E(); // Tag only variant
3234
List<int>? F();
3335
(int a, string b) G();
3436
}

0 commit comments

Comments
 (0)