Skip to content

Commit 6270be3

Browse files
authored
Improve sourcegen performance (#70)
1 parent 18642eb commit 6270be3

16 files changed

+316
-302
lines changed

.github/workflows/dotnet.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
build:
2121
runs-on: ubuntu-latest
2222
steps:
23-
- uses: actions/checkout@v3
23+
- uses: actions/checkout@v4
2424
- name: Set Version Variable
2525
if: ${{ github.ref_type == 'tag' }}
2626
env:

src/DynamoDBGenerator.SourceGenerator/DynamoDBDMarshallerEntry.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ private static void Execute(SourceProductionContext context,
4040
? null
4141
: $"{typeSymbol.ContainingNamespace}.";
4242

43-
context.AddSource($"{typeNamespace}{typeSymbol.Name}.g",
44-
string.Join(Constants.NewLine, CreateFileContent(typeSymbol, compilation)));
43+
context.AddSource(
44+
$"{typeNamespace}{typeSymbol.Name}.g",
45+
string.Join(Constants.NewLine, CreateFileContent(typeSymbol, compilation))
46+
);
4547
}
4648
}
4749

@@ -62,10 +64,10 @@ private static IEnumerable<string> CreateFileContent(ISymbol type, Compilation c
6264

6365
var (options, args) = CreateArguments(type, compilation);
6466
var classContent =
65-
$"public sealed partial class {type.Name}".CreateBlock(DynamoDbMarshaller.CreateRepository(args, options));
67+
$"public sealed partial class {type.Name}".CreateScope(DynamoDbMarshaller.CreateRepository(args, options));
6668
var content = type.ContainingNamespace.IsGlobalNamespace
6769
? classContent
68-
: $"namespace {type.ContainingNamespace.ToDisplayString()}".CreateBlock(classContent);
70+
: $"namespace {type.ContainingNamespace.ToDisplayString()}".CreateScope(classContent);
6971

7072
foreach (var s in content)
7173
yield return s;

src/DynamoDBGenerator.SourceGenerator/DynamoDbMarshaller.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,18 @@ private static IEnumerable<string> CreateImplementations(IEnumerable<DynamoDBMar
2222
var argumentTypeName = argument.AnnotatedArgumentType;
2323

2424
var constructor = $"public {argument.ImplementationName}({MarshallerOptions.Name} {MarshallerOptions.ParamReference})"
25-
.CreateBlock($"{MarshallerOptions.FieldReference} = {MarshallerOptions.ParamReference};", $"{KeyMarshaller.PrimaryKeyMarshallerReference} = {KeyMarshaller.AssignmentRoot(argument.EntityTypeSymbol)};");
25+
.CreateScope($"{MarshallerOptions.FieldReference} = {MarshallerOptions.ParamReference};", $"{KeyMarshaller.PrimaryKeyMarshallerReference} = {KeyMarshaller.AssignmentRoot(argument.EntityTypeSymbol)};");
2626
var interfaceImplementation = constructor
2727
.Concat(Marshaller.RootSignature(argument.EntityTypeSymbol, entityTypeName))
28-
.Concat(Unmarshaller.RootSignature(argument.EntityTypeSymbol, entityTypeName))
28+
.Concat(UnMarshaller.RootSignature(argument.EntityTypeSymbol, entityTypeName))
2929
.Concat(KeyMarshaller.IndexKeyMarshallerRootSignature(argument.EntityTypeSymbol))
3030
.Concat(expressionValueMethod)
3131
.Append(expressionMethodName)
3232
.Append(KeyMarshaller.PrimaryKeyMarshallerDeclaration)
3333
.Prepend(MarshallerOptions.FieldDeclaration);
3434

3535
var classImplementation = $"private sealed class {argument.ImplementationName}: {Interface}<{entityTypeName}, {argumentTypeName}, {nameTrackerTypeName}, {valueTrackerTypeName}>"
36-
.CreateBlock(interfaceImplementation);
36+
.CreateScope(interfaceImplementation);
3737

3838
yield return options.TryInstantiate() switch
3939
{
@@ -54,7 +54,7 @@ public static IEnumerable<string> CreateRepository(IEnumerable<DynamoDBMarshalle
5454
var getDynamoDbProperties = TypeExtensions.CacheFactory(SymbolEqualityComparer.IncludeNullability, TypeExtensions.GetDynamoDbProperties);
5555
var code = CreateImplementations(loadedArguments, options)
5656
.Concat(Marshaller.CreateClass(loadedArguments, getDynamoDbProperties, options))
57-
.Concat(Unmarshaller.CreateClass(loadedArguments, getDynamoDbProperties, options))
57+
.Concat(UnMarshaller.CreateClass(loadedArguments, getDynamoDbProperties, options))
5858
.Concat(AttributeExpressionName.CreateClasses(loadedArguments, getDynamoDbProperties, options))
5959
.Concat(AttributeExpressionValue.CreateExpressionAttributeValue(loadedArguments, getDynamoDbProperties, options))
6060
.Concat(KeyMarshaller.CreateKeys(loadedArguments, getDynamoDbProperties, options));
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Immutable;
12
using Microsoft.CodeAnalysis;
23
using Microsoft.CodeAnalysis.CSharp.Syntax;
34

@@ -6,13 +7,23 @@ namespace DynamoDBGenerator.SourceGenerator.Extensions;
67
// Great source: https://github.com/dotnet/runtime/blob/main/src/tools/illink/src/ILLink.RoslynAnalyzer/CompilationExtensions.cs
78
public static class CompilationExtensions
89
{
9-
private static ITypeSymbol? GetTypeSymbol(this Compilation compilation, SyntaxNode typeDeclarationSyntax)
10+
public static ReadOnlySpan<ITypeSymbol> GetTypeSymbols(this Compilation compilation, ImmutableArray<ClassDeclarationSyntax> classDeclarations)
1011
{
11-
return compilation.GetSemanticModel(typeDeclarationSyntax.SyntaxTree).GetDeclaredSymbol(typeDeclarationSyntax) as ITypeSymbol;
12-
}
12+
var span = classDeclarations.AsSpan();
13+
var symbols = new ITypeSymbol[classDeclarations.Length];
14+
for (var i = 0; i < span.Length; i++)
15+
{
16+
var classDeclarationSyntax = span[i];
1317

14-
public static IEnumerable<ITypeSymbol> GetTypeSymbols(this Compilation compilation, IEnumerable<TypeDeclarationSyntax> typeDeclarationSyntax)
15-
{
16-
return typeDeclarationSyntax.Select(x => GetTypeSymbol(compilation, x)).Where(x => x is not null) as IEnumerable<ITypeSymbol>;
18+
if (compilation
19+
.GetSemanticModel(classDeclarationSyntax.SyntaxTree)
20+
.GetDeclaredSymbol(classDeclarationSyntax)
21+
is not ITypeSymbol typeSymbol)
22+
throw new ArgumentException($"Could not convert the '{classDeclarationSyntax.ToFullString()}' into a '{nameof(ITypeSymbol)}'.");
23+
24+
symbols[i] = typeSymbol;
25+
}
26+
27+
return new ReadOnlySpan<ITypeSymbol>(symbols);
1728
}
1829
}

src/DynamoDBGenerator.SourceGenerator/Extensions/StringExtensions.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ private static string Indent(int level)
2121

2222
return indent;
2323
}
24-
public static IEnumerable<string> CreateBlock(this string header, IEnumerable<string> content, int indentLevel)
24+
public static IEnumerable<string> CreateScope(this string header, IEnumerable<string> content, int indentLevel)
2525
{
2626
var indent = Indent(indentLevel);
2727

@@ -33,7 +33,7 @@ public static IEnumerable<string> CreateBlock(this string header, IEnumerable<st
3333

3434
yield return string.Intern($"{indent}}}");
3535
}
36-
public static IEnumerable<string> CreateBlock(this string header, IEnumerable<string> content)
36+
public static IEnumerable<string> CreateScope(this string header, IEnumerable<string> content)
3737
{
3838
yield return header;
3939
yield return "{";
@@ -44,7 +44,7 @@ public static IEnumerable<string> CreateBlock(this string header, IEnumerable<st
4444
yield return "}";
4545
}
4646

47-
public static IEnumerable<string> CreateBlock(this string header, string content)
47+
public static IEnumerable<string> CreateScope(this string header, string content)
4848
{
4949
yield return header;
5050
yield return "{";
@@ -54,7 +54,7 @@ public static IEnumerable<string> CreateBlock(this string header, string content
5454
yield return "}";
5555
}
5656

57-
public static IEnumerable<string> CreateBlock(this string header, string content, string second)
57+
public static IEnumerable<string> CreateScope(this string header, string content, string second)
5858
{
5959
yield return header;
6060
yield return "{";

0 commit comments

Comments
 (0)