Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/commands/pr.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- core
- docs
- testing
- tests
- Use this template for the PR:

---
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/validate-pr-title.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
core
docs
testing
tests
requireScope: false
subjectPattern: ^[a-z].*
subjectPatternError: Subject must start with lowercase letter
17 changes: 17 additions & 0 deletions src/MinimalLambda.SourceGenerators/AnalyzerReleases.Shipped.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
## Release 2.1.1

### New Rules

Rule ID | Category | Severity | Notes
---------|-----------------------------|----------|-------------
LH0005 | MinimalLambda.Configuration | Error | Diagnostics
LH0006 | MinimalLambda.Configuration | Error | Diagnostics

## Release 2.0.0

### Removed Rules

Rule ID | Category | Severity | Notes
---------|---------------------|----------|--------------------------------
LH0001 | MinimalLambda.Usage | Error | Multiple method calls detected

## Release 1.0.0

### New Rules
Expand Down
12 changes: 0 additions & 12 deletions src/MinimalLambda.SourceGenerators/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
@@ -1,12 +0,0 @@
### New Rules

Rule ID | Category | Severity | Notes
---------|-----------------------------|----------|-------------
LH0005 | MinimalLambda.Configuration | Error | Diagnostics
LH0006 | MinimalLambda.Configuration | Error | Diagnostics

### Removed Rules

Rule ID | Category | Severity | Notes
---------|------------------------------|----------|-----------------------------------
LH0001 | MinimalLambda.Usage | Error | Multiple method calls detected
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using MinimalLambda.SourceGenerators.Models;
Expand All @@ -9,24 +8,6 @@ namespace MinimalLambda.SourceGenerators;
[Generator]
public class MapHandlerIncrementalGenerator : IIncrementalGenerator
{
private readonly string _generatorName;
private readonly string _generatorVersion;

public MapHandlerIncrementalGenerator()
{
var assembly = Assembly.GetExecutingAssembly();

_generatorName = assembly.GetName().FullName;
_generatorVersion = assembly.GetName().Version.ToString();
}

/// <summary>This constructor is only used for testing.</summary>
internal MapHandlerIncrementalGenerator(string generatorName, string generatorVersion)
{
_generatorName = generatorName;
_generatorVersion = generatorVersion;
}

public void Initialize(IncrementalGeneratorInitializationContext context)
{
// Language version gate - only generate source if C# 11 or later is used
Expand Down Expand Up @@ -139,12 +120,7 @@ is CSharpCompilation
if (info is null)
return;

LambdaHostOutputGenerator.Generate(
productionContext,
info.Value,
_generatorName,
_generatorVersion
);
LambdaHostOutputGenerator.Generate(productionContext, info.Value);
}
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ namespace MinimalLambda.SourceGenerators;

internal static class CommonSources
{
internal static string Generate(string generatedCodeAttribute)
internal static string Generate()
{
var model = new { GeneratedCodeAttribute = generatedCodeAttribute };
var model = new { LambdaHostOutputGenerator.GeneratedCodeAttribute };

var template = TemplateHelper.LoadTemplate(
GeneratorConstants.InterceptsLocationAttributeTemplateFile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ internal static string Generate(
string methodName,
string? wrapperReturnType,
string? defaultWrapperReturnValue,
string targetType,
string generatedCodeAttribute
string targetType
)
{
var calls = higherOrderMethodInfos
Expand Down Expand Up @@ -110,7 +109,7 @@ string generatedCodeAttribute
{
Name = methodName,
Calls = calls,
GeneratedCodeAttribute = generatedCodeAttribute,
LambdaHostOutputGenerator.GeneratedCodeAttribute,
};

var template = TemplateHelper.LoadTemplate(GeneratorConstants.GenericHandlerTemplateFile);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using MinimalLambda.SourceGenerators.Models;

namespace MinimalLambda.SourceGenerators;

internal static class LambdaHostOutputGenerator
{
internal static void Generate(
SourceProductionContext context,
CompilationInfo compilationInfo,
string generatorName,
string generatorVersion
)
internal static string GeneratedCodeAttribute
{
get
{
if (field is null)
{
var assembly = Assembly.GetExecutingAssembly();
var generatorName = assembly.GetName().FullName;
var generatorVersion = assembly.GetName().Version.ToString();

field = $"[GeneratedCode(\"{generatorName}\", \"{generatorVersion}\")]";
}

return field;
}
}

internal static void Generate(SourceProductionContext context, CompilationInfo compilationInfo)
{
// validate the generator data and report any diagnostics before exiting.
var diagnostics = DiagnosticGenerator.GenerateDiagnostics(compilationInfo);
Expand All @@ -25,13 +38,9 @@ string generatorVersion
return;
}

// create GeneratedCodeAttribute. This is used across all generated source files.
var generatedCodeAttribute =
$"[GeneratedCode(\"{generatorName}\", \"{generatorVersion}\")]";

List<string?> outputs =
[
CommonSources.Generate(generatedCodeAttribute),
CommonSources.Generate(),
"""
namespace MinimalLambda.Generated
{
Expand All @@ -52,19 +61,13 @@ namespace MinimalLambda.Generated
outputs.Add(
MapHandlerSources.Generate(
compilationInfo.MapHandlerInvocationInfos,
compilationInfo.BuilderInfos,
generatedCodeAttribute
compilationInfo.BuilderInfos
)
);

// add UseMiddleware<T> interceptors
if (compilationInfo.UseMiddlewareTInfos.Count >= 1)
outputs.Add(
UseMiddlewareTSource.Generate(
compilationInfo.UseMiddlewareTInfos,
generatedCodeAttribute
)
);
outputs.Add(UseMiddlewareTSource.Generate(compilationInfo.UseMiddlewareTInfos));

// add OnInit interceptors
if (compilationInfo.OnInitInvocationInfos.Count >= 1)
Expand All @@ -74,8 +77,7 @@ namespace MinimalLambda.Generated
"OnInit",
"bool",
"true",
"ILambdaOnInitBuilder",
generatedCodeAttribute
"ILambdaOnInitBuilder"
)
);

Expand All @@ -87,8 +89,7 @@ namespace MinimalLambda.Generated
"OnShutdown",
null,
null,
"ILambdaOnShutdownBuilder",
generatedCodeAttribute
"ILambdaOnShutdownBuilder"
)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ internal static class MapHandlerSources
{
internal static string Generate(
EquatableArray<HigherOrderMethodInfo> mapHandlerInvocationInfos,
EquatableArray<SimpleMethodInfo> builderInfo,
string generatedCodeAttribute
EquatableArray<SimpleMethodInfo> builderInfo
)
{
var mapHandlerCalls = mapHandlerInvocationInfos.Select(mapHandlerInvocationInfo =>
Expand Down Expand Up @@ -69,7 +68,7 @@ string generatedCodeAttribute
return template.Render(
new
{
GeneratedCodeAttribute = generatedCodeAttribute,
LambdaHostOutputGenerator.GeneratedCodeAttribute,
MapHandlerCalls = mapHandlerCalls,
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ namespace MinimalLambda.SourceGenerators;

internal static class UseMiddlewareTSource
{
internal static string Generate(
EquatableArray<UseMiddlewareTInfo> useMiddlewareTInfos,
string generatedCodeAttribute
)
internal static string Generate(EquatableArray<UseMiddlewareTInfo> useMiddlewareTInfos)
{
var useMiddlewareTCalls = useMiddlewareTInfos.Select(useMiddlewareTInfo =>
{
Expand Down Expand Up @@ -87,7 +84,7 @@ n is AttributeConstants.FromServices or AttributeConstants.FromKeyedService
var template = TemplateHelper.LoadTemplate(GeneratorConstants.UseMiddlewareTTemplateFile);

return template.Render(
new { GeneratedCodeAttribute = generatedCodeAttribute, Calls = useMiddlewareTCalls }
new { LambdaHostOutputGenerator.GeneratedCodeAttribute, Calls = useMiddlewareTCalls }
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text.RegularExpressions;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Core;
using Amazon.Lambda.RuntimeSupport;
Expand Down Expand Up @@ -54,7 +55,24 @@ internal static Task Verify(string source, int expectedTrees = 1)

result.GeneratedTrees.Length.Should().Be(expectedTrees);

return Verifier.Verify(driver).UseDirectory("Snapshots").DisableDiff();
return Verifier
.Verify(driver)
.UseDirectory("Snapshots")
.DisableDiff()
.ScrubLinesWithReplace(line =>
{
// replace [GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")]
if (line.Contains("GeneratedCode", StringComparison.Ordinal))
return RegexHelper
.GeneratedCodeAttributeRegex()
.Replace(line, """[GeneratedCode("REPLACED", "REPLACED")]""");

// replace [InterceptsLocation(1, "")]
if (line.Contains("InterceptsLocation", StringComparison.Ordinal))
return RegexHelper.InterceptsLocationRegex().Replace(line, "REPLACED");

return line;
});
}

internal static (GeneratorDriver driver, Compilation compilation) GenerateFromSource(
Expand Down Expand Up @@ -106,14 +124,24 @@ .. Net90.References.All.ToList(),
compilationOptions
);

var generator = new MapHandlerIncrementalGenerator(
"MinimalLambda.SourceGenerators",
"0.0.0"
).AsSourceGenerator();
var generator = new MapHandlerIncrementalGenerator().AsSourceGenerator();

var driver = CSharpGeneratorDriver.Create(generator);
var updatedDriver = driver.RunGenerators(compilation, CancellationToken.None);

return (updatedDriver, compilation);
}
}

internal static partial class RegexHelper
{
[GeneratedRegex("""\[GeneratedCode\("([^"]+)",\s*"([^"]+)"\)\]""", RegexOptions.None, "en-US")]
internal static partial Regex GeneratedCodeAttributeRegex();

[GeneratedRegex(
"""(?<=\[InterceptsLocation\(\d+, ")([A-Za-z0-9+/=]{2,})(?="\)\])""",
RegexOptions.None,
"en-US"
)]
internal static partial Regex InterceptsLocationRegex();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace System.Runtime.CompilerServices
{
using System.CodeDom.Compiler;

[GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")]
[GeneratedCode("REPLACED", "REPLACED")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
file sealed class InterceptsLocationAttribute : Attribute
{
Expand All @@ -37,13 +37,13 @@ namespace MinimalLambda.Generated
using MinimalLambda;
using MinimalLambda.Builder;

[GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")]
[GeneratedCode("REPLACED", "REPLACED")]
file static class GeneratedLambdaInvocationBuilderExtensions
{
private const string EventFeatureProviderKey = "__EventFeatureProvider";
private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider";

[InterceptsLocation(1, "Tx1x72WT0aa+xpOr41o/dzsBAABJbnB1dEZpbGUuY3M=")]
[InterceptsLocation(1, "REPLACED")]
internal static ILambdaInvocationBuilder MapHandlerInterceptor0(
this ILambdaInvocationBuilder application,
Delegate handler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace System.Runtime.CompilerServices
{
using System.CodeDom.Compiler;

[GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")]
[GeneratedCode("REPLACED", "REPLACED")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
file sealed class InterceptsLocationAttribute : Attribute
{
Expand All @@ -37,13 +37,13 @@ namespace MinimalLambda.Generated
using MinimalLambda;
using MinimalLambda.Builder;

[GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")]
[GeneratedCode("REPLACED", "REPLACED")]
file static class GeneratedLambdaInvocationBuilderExtensions
{
private const string EventFeatureProviderKey = "__EventFeatureProvider";
private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider";

[InterceptsLocation(1, "RRgc5MNn+AL4pWTKQhrXsLYAAABJbnB1dEZpbGUuY3M=")]
[InterceptsLocation(1, "REPLACED")]
internal static ILambdaInvocationBuilder MapHandlerInterceptor0(
this ILambdaInvocationBuilder application,
Delegate handler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace System.Runtime.CompilerServices
{
using System.CodeDom.Compiler;

[GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")]
[GeneratedCode("REPLACED", "REPLACED")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
file sealed class InterceptsLocationAttribute : Attribute
{
Expand All @@ -37,13 +37,13 @@ namespace MinimalLambda.Generated
using MinimalLambda;
using MinimalLambda.Builder;

[GeneratedCode("MinimalLambda.SourceGenerators", "0.0.0")]
[GeneratedCode("REPLACED", "REPLACED")]
file static class GeneratedLambdaInvocationBuilderExtensions
{
private const string EventFeatureProviderKey = "__EventFeatureProvider";
private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider";

[InterceptsLocation(1, "x0XA1nde6vAUjFMeY2ZDTdoAAABJbnB1dEZpbGUuY3M=")]
[InterceptsLocation(1, "REPLACED")]
internal static ILambdaInvocationBuilder MapHandlerInterceptor0(
this ILambdaInvocationBuilder application,
Delegate handler
Expand Down
Loading
Loading