Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental source generator for actors #1334

Merged
merged 70 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
78ef503
Samples - Add k8s deployment yaml to DemoActor sample (#1308)
m3nax Jun 26, 2024
7711fd6
Aligned nuget version
m3nax Jun 26, 2024
30189be
UP
m3nax Jul 2, 2024
86c881a
UP
m3nax Jul 4, 2024
c44384b
Debug profile added
m3nax Jul 9, 2024
9f9a4b7
Updated implementation
m3nax Jul 9, 2024
c86c709
Emitted DAPR001 Diagnostic warning
m3nax Jul 9, 2024
38f4fc1
Added DAPR002 diagnostic
m3nax Jul 9, 2024
8611f67
Cleaun
m3nax Jul 9, 2024
56b9ab9
UP
m3nax Jul 9, 2024
a2f3616
Added summaries
m3nax Jul 9, 2024
b2deca7
Added base interface to ActorClient
m3nax Jul 9, 2024
45ef4f6
Updated
m3nax Jul 9, 2024
a756015
Added ctor
m3nax Jul 9, 2024
28db658
Added nullable directive
m3nax Jul 10, 2024
4be5bb7
Added null check for actorproxy ctor parameter
m3nax Jul 10, 2024
c24d310
Moved DiagnoticException in a dedicate cs file
m3nax Jul 10, 2024
28fc7fe
Moved generator costants to dedicated class
m3nax Jul 10, 2024
aa4c1d4
Added ActorReference creation from the ActorBase class informations (…
m3nax Jun 26, 2024
ee6ca9e
Added overload to support SDK supplying query string on invoked URL (…
WhitWaldo Jul 3, 2024
cd1351a
Fixed actorProxy argument null check
m3nax Jul 10, 2024
ef9d0c2
Moved ActorClientDesciptor into separta cs file
m3nax Jul 10, 2024
25f11e2
Moved textual templates to dedicated class
m3nax Jul 11, 2024
182ce2d
Updated comments, property names
m3nax Jul 11, 2024
f8d83cb
Added argument null check to SyntaxFactoryHelpers
m3nax Jul 11, 2024
afaac59
Added comments
m3nax Jul 11, 2024
92c0a9e
Removed obsolete testing packages https://github.com/dotnet/roslyn-sd…
m3nax Jul 11, 2024
d75c83b
Adapted existing unit test to new source generated code
m3nax Jul 11, 2024
22ac565
Up
m3nax Jul 11, 2024
3c52343
Added tests for SyntaxFactoryHelpers
m3nax Jul 12, 2024
3208ec6
Updated generation of ArgumentNullException
m3nax Jul 12, 2024
495cff6
Updated nullability
m3nax Jul 15, 2024
403e95f
Fixed internal methods tests
m3nax Jul 25, 2024
179ae8b
Added test to IEnumerableExtensions
m3nax Jul 25, 2024
b04e5e0
Unittested GetSyntaxKinds from Accessibility
m3nax Jul 25, 2024
d84981d
UP
m3nax Jul 25, 2024
4308e11
Updated assignment implementation of ctor body
m3nax Jul 30, 2024
5bb1a2b
Improved unit test
m3nax Jul 30, 2024
d0c4260
Added implementation of method generation
m3nax Jul 30, 2024
6692c6a
Fixed ArgumentNullException invocation
m3nax Aug 1, 2024
531adbb
Added test for NameOfExpression
m3nax Aug 1, 2024
36809a0
Fixed ActorProxy method invocation
m3nax Aug 1, 2024
cf34718
Simplified proxy argument definition
m3nax Aug 2, 2024
493cbec
Explicit generic arguments of the proxy call during generation
m3nax Aug 2, 2024
0c287f1
Handled cancellation token with default value
m3nax Aug 2, 2024
ad2c22d
Fixed typo
m3nax Aug 2, 2024
4d336c8
Configured eol used in NormalizeWhitespace function
m3nax Aug 2, 2024
3bc0674
Normalized expected source
m3nax Aug 2, 2024
c0f9c47
Moved to constat the ActorProxyTypeName
m3nax Aug 2, 2024
7a86b4f
Fix typo
m3nax Aug 2, 2024
c5f5f11
Created ActorProxyInvokeMethodAsync SyntaxFactoryHelper
m3nax Aug 8, 2024
51ed60d
Removed custom concat implementation
m3nax Aug 8, 2024
f8b3199
fix (#1329)
hhunter-ms Jul 23, 2024
acfbfe7
link to non-dapr endpoint howto (#1335)
hhunter-ms Aug 9, 2024
2d4fe2f
Merge 1.14 release branch back into `master`. (#1337)
philliphoff Aug 22, 2024
a033218
Fixed merge errors
m3nax Sep 3, 2024
494383c
Updated some summaries
m3nax Sep 3, 2024
89b4069
Added some missing summaries
m3nax Sep 4, 2024
39b4289
Fixed typo
m3nax Sep 4, 2024
66bf943
Merged
m3nax Sep 4, 2024
30bb460
Improved some summary text
m3nax Sep 4, 2024
6b219d2
Improved summaries
m3nax Sep 4, 2024
4e99586
Handled review requests
m3nax Sep 10, 2024
b7614b7
Merge branch 'master' into incremental-source-generator-for-actors
WhitWaldo Oct 8, 2024
963b38a
Merged
m3nax Oct 21, 2024
a50e6de
Changed SyntaxFactoryHelpers accessor to internal
m3nax Oct 21, 2024
7105cce
Merge branch 'master' into incremental-source-generator-for-actors
WhitWaldo Oct 22, 2024
88cc4b9
Merge branch 'master' into incremental-source-generator-for-actors
WhitWaldo Oct 22, 2024
7b5b583
Merged
m3nax Oct 24, 2024
9f595e4
Merge branch 'master' into incremental-source-generator-for-actors
m3nax Oct 24, 2024
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
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.8.0" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're making the pivot to incremental source generators - might as well update each of the associated NuGet packages for Microsoft.CodeAnalysis.* - this one should be able to upgrade to 4.11.0, for example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m3nax One more here - just a package version update while we're at it and I think we're set.

<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing.XUnit" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.8.0" />
<PackageVersion Include="Microsoft.DurableTask.Client.Grpc" Version="1.3.0" />
<PackageVersion Include="Microsoft.DurableTask.Worker.Grpc" Version="1.3.0" />
Expand Down
41 changes: 24 additions & 17 deletions examples/GeneratedActor/ActorClient/ActorClient.csproj
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6</TargetFramework>
<LangVersion>10.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6</TargetFramework>
<LangVersion>10.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<ItemGroup>
<ProjectReference Include="..\ActorCommon\ActorCommon.csproj" />
<ProjectReference Include="..\..\..\src\Dapr.Actors\Dapr.Actors.csproj" />
</ItemGroup>
<!-- Persist the source generator (and other) files to disk -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<!-- 👇 The "base" path for the source generators -->
<!--<GeneratedFolder>Generated</GeneratedFolder>-->
<!-- 👇 Write the output for each target framework to a different sub-folder -->
<!--<CompilerGeneratedFilesOutputPath>$(GeneratedFolder)\$(TargetFramework)</CompilerGeneratedFilesOutputPath>-->
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Dapr.Actors.Generators\Dapr.Actors.Generators.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ActorCommon\ActorCommon.csproj" />
<ProjectReference Include="..\..\..\src\Dapr.Actors\Dapr.Actors.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Dapr.Actors.Generators\Dapr.Actors.Generators.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion examples/GeneratedActor/ActorClient/IClientActor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2023 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
454 changes: 221 additions & 233 deletions src/Dapr.Actors.Generators/ActorClientGenerator.cs

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions src/Dapr.Actors.Generators/AnalyzerReleases.Shipped.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Release 1.14

### New Rules

Rule ID | Category | Severity | Notes
--------|----------|----------|--------------------
DAPR0001| Usage | Error | Cancellation tokens must be the last argument
DAPR0002| Usage | Error | Only methods with a single argument or a single argument followed by a cancellation token are supported
3 changes: 3 additions & 0 deletions src/Dapr.Actors.Generators/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
; Unshipped analyzer release
; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md

38 changes: 38 additions & 0 deletions src/Dapr.Actors.Generators/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace Dapr.Actors.Generators
{
/// <summary>
/// Constants used by the code generator.
/// </summary>
internal static class Constants
{
/// <summary>
/// The namespace used by the generated code.
/// </summary>
public const string GeneratorsNamespace = "Dapr.Actors.Generators";

/// <summary>
/// The name of the attribute used to mark actor interfaces.
/// </summary>
public const string ActorMethodAttributeTypeName = "ActorMethodAttribute";

/// <summary>
/// The full type name of the attribute used to mark actor interfaces.
/// </summary>
public const string ActorMethodAttributeFullTypeName = GeneratorsNamespace + "." + ActorMethodAttributeTypeName;

/// <summary>
/// The name of the attribute used to mark actor interfaces.
/// </summary>
public const string GenerateActorClientAttributeTypeName = "GenerateActorClientAttribute";

/// <summary>
/// The full type name of the attribute used to mark actor interfaces.
/// </summary>
public const string GenerateActorClientAttributeFullTypeName = GeneratorsNamespace + "." + GenerateActorClientAttributeTypeName;

/// <summary>
/// Actor proxy type name.
/// </summary>
public const string ActorProxyTypeName = "Dapr.Actors.Client.ActorProxy";
}
}
64 changes: 37 additions & 27 deletions src/Dapr.Actors.Generators/Dapr.Actors.Generators.csproj
Original file line number Diff line number Diff line change
@@ -1,45 +1,55 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsRoslynComponent>true</IsRoslynComponent>
</PropertyGroup>

<PropertyGroup>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
</PropertyGroup>
<PropertyGroup>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" PrivateAssets="all" />
</ItemGroup>

<!--
<!--
Source generators are built and packaged as analyzers and not "normal" NuGet libraries.
-->

<PropertyGroup>
<!-- Generators must target netstandard2.0. -->
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks></TargetFrameworks>
<PropertyGroup>
<!-- Generators must target netstandard2.0. -->
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks></TargetFrameworks>

<!-- Do not include the generator as a lib dependency -->
<IncludeBuildOutput>false</IncludeBuildOutput>
<!-- Do not include the generator as a lib dependency -->
<IncludeBuildOutput>false</IncludeBuildOutput>

<!-- Suppress false-positive error NU5128 when packing analyzers with no lib/ref files. -->
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<!-- Suppress false-positive error NU5128 when packing analyzers with no lib/ref files. -->
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>

<!-- Suppress generation of symbol package (.snupkg). -->
<IncludeSymbols>false</IncludeSymbols>
<!-- Suppress generation of symbol package (.snupkg). -->
<IncludeSymbols>false</IncludeSymbols>

<!-- Additional NuGet package properties. -->
<Description>This package contains source generators for interacting with Actor services using Dapr.</Description>
<PackageTags>$(PackageTags);Actors</PackageTags>
</PropertyGroup>
<!-- Additional NuGet package properties. -->
<Description>This package contains source generators for interacting with Actor services using Dapr.</Description>
<PackageTags>$(PackageTags);Actors</PackageTags>
</PropertyGroup>

<ItemGroup>
<!-- Package the generator in the analyzer directory of the NuGet package -->
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
<ItemGroup>
<!-- Package the generator in the analyzer directory of the NuGet package -->
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="AnalyzerReleases.Shipped.md" />
<AdditionalFiles Include="AnalyzerReleases.Unshipped.md" />
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="$(AssemblyName).Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b1f597635c44597fcecb493e2b1327033b29b1a98ac956a1a538664b68f87d45fbaada0438a15a6265e62864947cc067d8da3a7d93c5eb2fcbb850e396c8684dba74ea477d82a1bbb18932c0efb30b64ff1677f85ae833818707ac8b49ad8062ca01d2c89d8ab1843ae73e8ba9649cd28666b539444dcdee3639f95e2a099bb2"/>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.CodeAnalysis;

namespace Dapr.Actors.Generators.Diagnostics
{
internal static class CancellationTokensMustBeTheLastArgument
{
public const string DiagnosticId = "DAPR0001";
public const string Title = "Invalid method signature";
public const string MessageFormat = "Cancellation tokens must be the last argument";
public const string Category = "Usage";

private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
DiagnosticId,
Title,
MessageFormat,
Category,
DiagnosticSeverity.Error,
isEnabledByDefault: true);

internal static Diagnostic CreateDiagnostic(ISymbol symbol) => Diagnostic.Create(
Rule,
symbol.Locations.First(),
symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.CodeAnalysis;

namespace Dapr.Actors.Generators.Diagnostics
{
internal static class MethodMustOnlyHaveASingleArgumentOptionallyFollowedByACancellationToken
{
public const string DiagnosticId = "DAPR0002";
public const string Title = "Invalid method signature";
public const string MessageFormat = "Only methods with a single argument or a single argument followed by a cancellation token are supported";
public const string Category = "Usage";

private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
DiagnosticId,
Title,
MessageFormat,
Category,
DiagnosticSeverity.Error,
isEnabledByDefault: true);

internal static Diagnostic CreateDiagnostic(ISymbol symbol) => Diagnostic.Create(
Rule,
symbol.Locations.First(),
symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
}
}
25 changes: 25 additions & 0 deletions src/Dapr.Actors.Generators/DiagnosticsException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.CodeAnalysis;

namespace Dapr.Actors.Generators
{
/// <summary>
/// Exception thrown when diagnostics are encountered during code generation.
/// </summary>
internal sealed class DiagnosticsException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="DiagnosticsException"/> class.
/// </summary>
/// <param name="diagnostics">List of diagnostics generated.</param>
public DiagnosticsException(IEnumerable<Diagnostic> diagnostics)
: base(string.Join("\n", diagnostics.Select(d => d.ToString())))
{
this.Diagnostics = diagnostics.ToArray();
}

/// <summary>
/// Diagnostics encountered during code generation.
/// </summary>
public ICollection<Diagnostic> Diagnostics { get; }
}
}
34 changes: 34 additions & 0 deletions src/Dapr.Actors.Generators/Extensions/IEnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace Dapr.Actors.Generators.Extensions
{
internal static class IEnumerableExtensions
{
/// <summary>
/// Returns the index of the first item in the sequence that satisfies the predicate. If no item satisfies the predicate, -1 is returned.
/// </summary>
/// <typeparam name="T">The type of objects in the <see cref="IEnumerable{T}"/>.</typeparam>
/// <param name="source"><see cref="IEnumerable{T}"/> in which to search.</param>
/// <param name="predicate">Function performed to check whether an item satisfies the condition.</param>
/// <returns>Return the zero-based index of the first occurrence of an element that satisfies the condition, if found; otherwise, -1.</returns>
internal static int IndexOf<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
if (predicate is null)
{
throw new ArgumentNullException(nameof(predicate));
}

int index = 0;

foreach (var item in source)
WhitWaldo marked this conversation as resolved.
Show resolved Hide resolved
{
if (predicate(item))
{
return index;
}

index++;
}

return -1;
}
}
}
Loading
Loading