Skip to content

Commit 80d3e43

Browse files
committed
Minor optimizations
1 parent 1cf6296 commit 80d3e43

30 files changed

Lines changed: 420 additions & 430 deletions

src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/AdHocUnions/AdHocUnionCodeGenerator.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ private void GenerateConversionsFromValue()
156156
/// <summary>
157157
/// ").Append(_state.Settings.ConversionFromValue == ConversionOperatorsGeneration.Implicit ? "Implicit" : "Explicit").Append(" conversion from type ").AppendTypeForXmlComment(memberType).Append(@".
158158
/// </summary>
159-
/// <param name=""").Append(memberType.ArgumentName).Append(@""">Value to covert from.</param>
160-
/// <returns>A new instance of ").AppendTypeForXmlComment(_state).Append(@" converted from <paramref name=""").Append(memberType.ArgumentName).Append(@"""/>.</returns>
159+
/// <param name=""").AppendArgumentName(memberType.ArgumentName).Append(@""">Value to covert from.</param>
160+
/// <returns>A new instance of ").AppendTypeForXmlComment(_state).Append(@" converted from <paramref name=""").AppendArgumentName(memberType.ArgumentName).Append(@"""/>.</returns>
161161
public static ").AppendConversionOperator(_state.Settings.ConversionFromValue).Append(" operator ").AppendTypeFullyQualified(_state).Append("(").AppendTypeFullyQualified(memberType).Append(" ").AppendEscaped(memberType.ArgumentName).Append(@")
162162
{
163163
return new ").AppendTypeFullyQualified(_state).Append("(").AppendEscaped(memberType.ArgumentName).Append(@");
@@ -423,7 +423,7 @@ private void GenerateSwitchForAction(bool withState, bool isPartially)
423423
var memberType = _state.MemberTypes[i];
424424

425425
_sb.Append(@"
426-
/// <param name=""").Append(memberType.ArgumentName).Append(@""">The action to execute if the current value is of type ").AppendTypeForXmlComment(memberType).Append(".</param>");
426+
/// <param name=""").AppendArgumentName(memberType.ArgumentName).Append(@""">The action to execute if the current value is of type ").AppendTypeForXmlComment(memberType).Append(".</param>");
427427
}
428428

429429
if (!_state.IsReferenceType)
@@ -581,7 +581,7 @@ private void GenerateSwitchForFunc(bool withState, bool isPartially)
581581
var memberType = _state.MemberTypes[i];
582582

583583
_sb.Append(@"
584-
/// <param name=""").Append(memberType.ArgumentName).Append(@""">The function to execute if the current value is of type ").AppendTypeForXmlComment(memberType).Append(".</param>");
584+
/// <param name=""").AppendArgumentName(memberType.ArgumentName).Append(@""">The function to execute if the current value is of type ").AppendTypeForXmlComment(memberType).Append(".</param>");
585585
}
586586

587587
if (!_state.IsReferenceType)
@@ -735,7 +735,7 @@ private void GenerateMap(bool isPartially)
735735
var memberType = _state.MemberTypes[i];
736736

737737
_sb.Append(@"
738-
/// <param name=""").Append(memberType.ArgumentName).Append(@""">The instance to return if the current value is of type ").AppendTypeForXmlComment(memberType).Append(".</param>");
738+
/// <param name=""").AppendArgumentName(memberType.ArgumentName).Append(@""">The instance to return if the current value is of type ").AppendTypeForXmlComment(memberType).Append(".</param>");
739739
}
740740

741741
if (!_state.IsReferenceType)
@@ -840,6 +840,8 @@ private void GenerateIndexBasedMapSwitchBody(bool isPartially)
840840

841841
private void GenerateConstructors()
842842
{
843+
var valueArgName = ArgumentName.Create("value", renderAsIs: true);
844+
843845
for (var i = 0; i < _state.MemberTypes.Count; i++)
844846
{
845847
var memberType = _state.MemberTypes[i];
@@ -848,7 +850,7 @@ private void GenerateConstructors()
848850
continue;
849851

850852
var hasDuplicates = memberType.TypeDuplicateCounter != 0;
851-
var argName = hasDuplicates ? "value" : memberType.ArgumentName;
853+
var argName = hasDuplicates ? valueArgName : memberType.ArgumentName;
852854

853855
_sb.Append(@"
854856
");
@@ -857,9 +859,9 @@ private void GenerateConstructors()
857859
{
858860
_sb.Append(@"
859861
/// <summary>
860-
/// Initializes new instance with <paramref name=""").Append(argName).Append(@"""/>.
862+
/// Initializes new instance with <paramref name=""").AppendArgumentName(argName).Append(@"""/>.
861863
/// </summary>
862-
/// <param name=""").Append(argName).Append(@""">Value to create a new instance for.</param>");
864+
/// <param name=""").AppendArgumentName(argName).Append(@""">Value to create a new instance for.</param>");
863865
}
864866

865867
_sb.Append(@"
@@ -906,9 +908,9 @@ private void GenerateFactoriesForTypeDuplicates()
906908
_sb.Append(@"
907909
908910
/// <summary>
909-
/// Creates new instance with <paramref name=""").Append(memberType.ArgumentName).Append(@"""/>.
911+
/// Creates new instance with <paramref name=""").AppendArgumentName(memberType.ArgumentName).Append(@"""/>.
910912
/// </summary>
911-
/// <param name=""").Append(memberType.ArgumentName).Append(@""">Value to create a new instance for.</param>");
913+
/// <param name=""").AppendArgumentName(memberType.ArgumentName).Append(@""">Value to create a new instance for.</param>");
912914

913915
_sb.Append(@"
914916
").AppendAccessModifier(_state.Settings.ConstructorAccessModifier).Append(" static ").Append(_state.Name).Append(" Create").Append(memberType.Name).Append("(")

src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/AdHocUnions/AdHocUnionMemberTypeState.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public sealed class AdHocUnionMemberTypeState
1717
public bool IsInterface { get; }
1818
public int TypeDuplicateCounter { get; }
1919

20-
public string ArgumentName { get; }
20+
public ArgumentName ArgumentName { get; }
2121
public string BackingFieldName { get; }
2222
public AdHocUnionMemberTypeSetting Setting { get; }
2323

@@ -32,7 +32,7 @@ public AdHocUnionMemberTypeState(
3232
AdHocUnionMemberTypeSetting setting)
3333
{
3434
Name = name;
35-
ArgumentName = Name.MakeArgumentName();
35+
ArgumentName = ArgumentName.Create(Name);
3636

3737
var backingFieldName = (typeDuplicateCounter == 0 ? Name : defaultName).MakeBackingFieldName();
3838
BackingFieldName = backingFieldName == Name ? $"_{backingFieldName}" : backingFieldName;

src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/AdHocUnions/AdHocUnionSourceGenerator.cs

Lines changed: 33 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,8 @@
33
namespace Thinktecture.CodeAnalysis.AdHocUnions;
44

55
[Generator]
6-
public class AdHocUnionSourceGenerator : ThinktectureSourceGeneratorBase, IIncrementalGenerator
6+
public sealed class AdHocUnionSourceGenerator() : ThinktectureSourceGeneratorBase(20_000), IIncrementalGenerator
77
{
8-
public AdHocUnionSourceGenerator()
9-
: base(20_000)
10-
{
11-
}
12-
138
public void Initialize(IncrementalGeneratorInitializationContext context)
149
{
1510
var options = GetGeneratorOptions(context);
@@ -35,27 +30,26 @@ private void InitializeGenericUnionSourceGen(
3530
IncrementalValueProvider<GeneratorOptions> options,
3631
string fullyQualifiedMetadataName)
3732
{
38-
InitializeUnionSourceGen(context, options, fullyQualifiedMetadataName, IsGenericCandidate, GetSourceGenContextOrNullForGeneric);
33+
InitializeUnionSourceGen(context, options, fullyQualifiedMetadataName, GetSourceGenContextOrNullForGeneric);
3934
}
4035

4136
private void InitializeNonGenericUnionSourceGen(
4237
IncrementalGeneratorInitializationContext context,
4338
IncrementalValueProvider<GeneratorOptions> options,
4439
string fullyQualifiedMetadataName)
4540
{
46-
InitializeUnionSourceGen(context, options, fullyQualifiedMetadataName, IsNonGenericCandidate, GetSourceGenContextOrNullForNonGeneric);
41+
InitializeUnionSourceGen(context, options, fullyQualifiedMetadataName, GetSourceGenContextOrNullForNonGeneric);
4742
}
4843

4944
private void InitializeUnionSourceGen(
5045
IncrementalGeneratorInitializationContext context,
5146
IncrementalValueProvider<GeneratorOptions> options,
5247
string fullyQualifiedMetadataName,
53-
Func<SyntaxNode, CancellationToken, bool> isCandate,
5448
Func<GeneratorAttributeSyntaxContext, CancellationToken, SourceGenContext?> getSourceGenContextOrNull)
5549
{
5650
var unionTypeOrError = context.SyntaxProvider
5751
.ForAttributeWithMetadataName(fullyQualifiedMetadataName,
58-
isCandate,
52+
IsCandidate,
5953
getSourceGenContextOrNull)
6054
.SelectMany(static (state, _) => state.HasValue
6155
? [state.Value]
@@ -71,115 +65,39 @@ private void InitializeUnionSourceGen(
7165
InitializeExceptionReporting(context, unionTypeOrError);
7266
}
7367

74-
private bool IsGenericCandidate(SyntaxNode syntaxNode, CancellationToken cancellationToken)
68+
private static bool IsCandidate(SyntaxNode syntaxNode, CancellationToken cancellationToken)
7569
{
76-
try
70+
return syntaxNode switch
7771
{
78-
return syntaxNode switch
79-
{
80-
ClassDeclarationSyntax classDeclaration when IsUnionCandidate(classDeclaration) => true,
81-
StructDeclarationSyntax structDeclaration when IsUnionCandidate(structDeclaration) => true,
82-
_ => false
83-
};
84-
}
85-
catch (Exception ex)
86-
{
87-
Logger.LogError("Error during checking whether a syntax node is a discriminated union candidate", exception: ex);
88-
return false;
89-
}
90-
}
91-
92-
private bool IsNonGenericCandidate(SyntaxNode syntaxNode, CancellationToken cancellationToken)
93-
{
94-
try
95-
{
96-
return syntaxNode switch
97-
{
98-
ClassDeclarationSyntax => true,
99-
StructDeclarationSyntax => true,
100-
_ => false
101-
};
102-
}
103-
catch (Exception ex)
104-
{
105-
Logger.LogError("Error during checking whether a syntax node is a discriminated union candidate", exception: ex);
106-
return false;
107-
}
108-
}
109-
110-
private bool IsUnionCandidate(TypeDeclarationSyntax typeDeclaration)
111-
{
112-
var isCandidate = !typeDeclaration.IsGeneric();
113-
114-
if (isCandidate)
115-
{
116-
Logger.LogDebug("The type declaration is a discriminated union candidate", typeDeclaration);
117-
}
118-
else
119-
{
120-
Logger.LogTrace("The type declaration is not a discriminated union candidate", typeDeclaration);
121-
}
122-
123-
return isCandidate;
72+
ClassDeclarationSyntax classDeclaration => !classDeclaration.IsGeneric(),
73+
StructDeclarationSyntax structDeclaration => !structDeclaration.IsGeneric(),
74+
_ => false
75+
};
12476
}
12577

12678
private SourceGenContext? GetSourceGenContextOrNullForGeneric(GeneratorAttributeSyntaxContext context, CancellationToken cancellationToken)
12779
{
12880
return GetSourceGenContextOrNull(
12981
context,
130-
(tds, data) =>
131-
{
132-
var attributeType = data.AttributeClass;
133-
134-
if (attributeType is null)
135-
{
136-
Logger.LogDebug("The attribute type is null", tds);
137-
return null;
138-
}
139-
140-
if (attributeType.TypeKind == TypeKind.Error)
141-
{
142-
Logger.LogDebug("The attribute type is erroneous", tds);
143-
return null;
144-
}
145-
146-
if (attributeType.TypeArguments.IsDefaultOrEmpty)
147-
return null;
148-
149-
return attributeType.TypeArguments;
150-
},
82+
static (attributeClass, _) => attributeClass.TypeArguments.IsDefaultOrEmpty ? null : attributeClass.TypeArguments,
15183
cancellationToken);
15284
}
15385

15486
private SourceGenContext? GetSourceGenContextOrNullForNonGeneric(GeneratorAttributeSyntaxContext context, CancellationToken cancellationToken)
15587
{
15688
return GetSourceGenContextOrNull(
15789
context,
158-
(tds, data) =>
90+
static (_, constructorArguments) =>
15991
{
160-
var attributeType = data.AttributeClass;
161-
162-
if (attributeType is null)
163-
{
164-
Logger.LogDebug("The attribute type is null", tds);
165-
return null;
166-
}
167-
168-
if (attributeType.TypeKind == TypeKind.Error)
169-
{
170-
Logger.LogDebug("The attribute type is erroneous", tds);
171-
return null;
172-
}
173-
174-
if(data.ConstructorArguments.IsDefaultOrEmpty)
92+
if (constructorArguments.IsDefaultOrEmpty)
17593
return null;
17694

177-
var types = new List<ITypeSymbol>();
95+
var types = new List<ITypeSymbol>(constructorArguments.Length);
17896
var foundNull = false;
17997

180-
for (var i = 0; i < data.ConstructorArguments.Length; i++)
98+
for (var i = 0; i < constructorArguments.Length; i++)
18199
{
182-
var argument = data.ConstructorArguments[i];
100+
var argument = constructorArguments[i];
183101

184102
if (argument.IsNull)
185103
{
@@ -193,14 +111,14 @@ private bool IsUnionCandidate(TypeDeclarationSyntax typeDeclaration)
193111
types.Add(type);
194112
}
195113

196-
return types;
114+
return types.Count > 0 ? types : null;
197115
},
198116
cancellationToken);
199117
}
200118

201119
private SourceGenContext? GetSourceGenContextOrNull(
202120
GeneratorAttributeSyntaxContext context,
203-
Func<TypeDeclarationSyntax, AttributeData, IReadOnlyList<ITypeSymbol>?> getMemberTypes,
121+
Func<INamedTypeSymbol, ImmutableArray<TypedConstant>, IReadOnlyList<ITypeSymbol>?> getMemberTypes,
204122
CancellationToken cancellationToken)
205123
{
206124
var tds = (TypeDeclarationSyntax)context.TargetNode;
@@ -209,44 +127,35 @@ private bool IsUnionCandidate(TypeDeclarationSyntax typeDeclaration)
209127
{
210128
var type = (INamedTypeSymbol)context.TargetSymbol;
211129

212-
if (type.TypeKind == TypeKind.Error)
130+
if (type.TypeKind == TypeKind.Error
131+
|| context.Attributes.IsDefaultOrEmpty
132+
|| context.Attributes.Length != 1)
213133
{
214-
Logger.LogDebug("Type from semantic model is erroneous", tds);
215-
return null;
216-
}
217-
218-
if (context.Attributes.IsDefaultOrEmpty)
219-
return null;
220-
221-
if (context.Attributes.Length > 1)
222-
{
223-
Logger.LogDebug($"Type has more than 1 '{Constants.Attributes.Union.NAME}'", tds);
224134
return null;
225135
}
226136

227137
var attributeData = context.Attributes[0];
228-
var memberTypeSymbols = getMemberTypes(tds, attributeData);
229138

230-
if (memberTypeSymbols is null)
139+
if (attributeData.AttributeClass is null
140+
|| attributeData.AttributeClass.TypeKind == TypeKind.Error)
231141
{
232142
return null;
233143
}
234144

235-
if (memberTypeSymbols.Count < 2)
145+
var memberTypeSymbols = getMemberTypes(attributeData.AttributeClass, attributeData.ConstructorArguments);
146+
147+
if (memberTypeSymbols is null
148+
|| memberTypeSymbols.Count < 2)
236149
{
237-
Logger.LogDebug($"Expected the union to have at least 2 member types but found {memberTypeSymbols.Count}", tds);
238150
return null;
239151
}
240152

241153
var errorMessage = AttributeInfo.TryCreate(type, out var attributeInfo);
242154

243155
if (errorMessage is not null)
244-
{
245-
Logger.LogDebug(errorMessage, tds);
246-
return null;
247-
}
156+
return new SourceGenContext(new SourceGenError(errorMessage, tds));
248157

249-
var factory = TypedMemberStateFactoryProvider.GetFactoryOrNull(context.SemanticModel.Compilation, Logger);
158+
var factory = TypedMemberStateFactoryProvider.GetFactoryOrNull(context.SemanticModel.Compilation);
250159

251160
if (factory is null)
252161
return new SourceGenContext(new SourceGenError("Could not fetch type information for code generation of a discriminated union", tds));
@@ -260,10 +169,7 @@ private bool IsUnionCandidate(TypeDeclarationSyntax typeDeclaration)
260169
var memberType = memberTypeSymbols[i];
261170

262171
if (memberType.TypeKind == TypeKind.Error)
263-
{
264-
Logger.LogDebug("Type of the member is erroneous", tds);
265172
return null;
266-
}
267173

268174
var memberTypeSettings = settings.MemberTypeSettings[i];
269175
memberType = memberType.IsReferenceType && memberTypeSettings.IsNullableReferenceType ? memberType.WithNullableAnnotation(NullableAnnotation.Annotated) : memberType;
@@ -292,13 +198,15 @@ private bool IsUnionCandidate(TypeDeclarationSyntax typeDeclaration)
292198

293199
if (!memberType.TryBuildMemberName(out var defaultName))
294200
{
295-
Logger.LogError("Type of the member must be a named type or array type", tds);
296-
return null;
201+
return new SourceGenContext(new SourceGenError("Type of the member must be a named type or array type", tds));
297202
}
298203

299204
var name = memberTypeSettings.Name ??
300205
(typeDuplicateCounter == 0 ? defaultName : defaultName + typeDuplicateCounter);
301206

207+
if (String.IsNullOrWhiteSpace(name))
208+
return null;
209+
302210
memberTypeStates[i] = new AdHocUnionMemberTypeState(name,
303211
defaultName,
304212
typeDuplicateCounter,
@@ -311,8 +219,6 @@ private bool IsUnionCandidate(TypeDeclarationSyntax typeDeclaration)
311219
settings,
312220
attributeInfo);
313221

314-
Logger.LogDebug("The type declaration is a valid union", null, unionState);
315-
316222
return new SourceGenContext(unionState);
317223
}
318224
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)

0 commit comments

Comments
 (0)