From 1a875296ca875ff5a25ed2afca3fa3ac2426c516 Mon Sep 17 00:00:00 2001 From: Cam MacFarland Date: Sun, 8 Feb 2026 10:07:59 +0800 Subject: [PATCH] Started v5 --- .github/workflows/test.yml | 2 +- AutoCtor.slnx | 1 + .../AutoCtor.Attributes.csproj | 7 +++- .../AttributeSourceGenerator.cs | 12 +++++++ .../AutoConstructSourceGenerator.cs | 36 +++++++++++++++++++ .../AutoCtor.Roslyn5.0.csproj | 15 ++++++++ src/Directory.Packages.props | 8 ++--- .../AutoConstructSourceGenerator/Emitter.cs | 2 +- src/Shared/Helpers/Extensions.cs | 2 +- src/Shared/Helpers/GeneratorUtilities.cs | 2 +- src/Shared/Models/ParameterList.cs | 2 +- src/Shared/Models/TypeModel.cs | 2 +- src/Tests/ExampleTests.cs | 6 ++-- src/Tests/LangExamples/PropertiesTest.cs | 2 +- ...ertiesTest.cs#PropertiesTest.g.verified.cs | 26 ++++++++++++++ src/Tests/Tests.csproj | 7 +++- src/Tests/Utilities/ExampleTestsHelper.cs | 15 ++++++-- src/Tests/Utilities/GeneratorDriverBuilder.cs | 8 +++++ 18 files changed, 136 insertions(+), 19 deletions(-) create mode 100644 src/AutoCtor.Roslyn5.0/AttributeSourceGenerator.cs create mode 100644 src/AutoCtor.Roslyn5.0/AutoConstructSourceGenerator.cs create mode 100644 src/AutoCtor.Roslyn5.0/AutoCtor.Roslyn5.0.csproj create mode 100644 src/Tests/LangExamples/Verified_5_0/PropertiesTest.cs#PropertiesTest.g.verified.cs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 206c613..90274f8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - roslyn: ["3.11", "4.0", "4.4"] + roslyn: ["3.11", "4.0", "4.4", "5.0"] steps: - name: 🛒 Check-out code uses: actions/checkout@v4 diff --git a/AutoCtor.slnx b/AutoCtor.slnx index be699e9..706f341 100644 --- a/AutoCtor.slnx +++ b/AutoCtor.slnx @@ -29,6 +29,7 @@ + diff --git a/src/AutoCtor.Attributes/AutoCtor.Attributes.csproj b/src/AutoCtor.Attributes/AutoCtor.Attributes.csproj index 285f093..f8254f5 100644 --- a/src/AutoCtor.Attributes/AutoCtor.Attributes.csproj +++ b/src/AutoCtor.Attributes/AutoCtor.Attributes.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netstandard2.0;net8.0;net9.0;net10.0;net462 AutoCtor true true @@ -29,6 +29,8 @@ PrivateAssets="All" ReferenceOutputAssembly="false" /> + @@ -41,6 +43,9 @@ + + + c.AddSource(Emitter.HintName, Emitter.GenerateSource())); + } +} diff --git a/src/AutoCtor.Roslyn5.0/AutoConstructSourceGenerator.cs b/src/AutoCtor.Roslyn5.0/AutoConstructSourceGenerator.cs new file mode 100644 index 0000000..a0cbe3c --- /dev/null +++ b/src/AutoCtor.Roslyn5.0/AutoConstructSourceGenerator.cs @@ -0,0 +1,36 @@ +using Microsoft.CodeAnalysis; + +namespace AutoCtor; + +public sealed partial class AutoConstructSourceGenerator : IIncrementalGenerator +{ + public void Initialize(IncrementalGeneratorInitializationContext context) + { + var properties = context.AnalyzerConfigOptionsProvider + .Select(static (p, ct) => + { + return p.GlobalOptions.TryGetValue("build_property.AutoCtorGuards", out var value) + && (value.Equals("true", StringComparison.OrdinalIgnoreCase) + || value.Equals("enable", StringComparison.OrdinalIgnoreCase)); + }) + .WithTrackingName(TrackingNames.BuildProperties); + + var types = context.SyntaxProvider.ForAttributeWithMetadataName( + AttributeNames.AutoConstruct, + GeneratorUtilities.IsTypeDeclarationWithAttributes, + static (c, ct) => TypeModel.Create((INamedTypeSymbol)c.TargetSymbol)) + .WithTrackingName(TrackingNames.TypeModels) + .Collect(); + + var postCtorMethods = context.SyntaxProvider.ForAttributeWithMetadataName( + AttributeNames.AutoPostConstruct, + GeneratorUtilities.IsMethodDeclarationWithAttributes, + static (c, ct) => PostCtorModel.Create((IMethodSymbol)c.TargetSymbol)) + .WithTrackingName(TrackingNames.PostCtorMethods) + .Collect(); + + context.RegisterSourceOutput( + types.Combine(postCtorMethods).Combine(properties), + Emitter.GenerateSource); + } +} diff --git a/src/AutoCtor.Roslyn5.0/AutoCtor.Roslyn5.0.csproj b/src/AutoCtor.Roslyn5.0/AutoCtor.Roslyn5.0.csproj new file mode 100644 index 0000000..7fedea7 --- /dev/null +++ b/src/AutoCtor.Roslyn5.0/AutoCtor.Roslyn5.0.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + $(DefineConstants);ROSLYN_5;ROSLYN_5_0 + + + + + + + + + + diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 1d2996e..d7e4eb9 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -6,11 +6,11 @@ - + - - - + + + diff --git a/src/Shared/AutoConstructSourceGenerator/Emitter.cs b/src/Shared/AutoConstructSourceGenerator/Emitter.cs index a931d2f..6dc47d6 100644 --- a/src/Shared/AutoConstructSourceGenerator/Emitter.cs +++ b/src/Shared/AutoConstructSourceGenerator/Emitter.cs @@ -5,7 +5,7 @@ #if ROSLYN_3 using EmitterContext = Microsoft.CodeAnalysis.GeneratorExecutionContext; -#elif ROSLYN_4 +#elif ROSLYN_4 || ROSLYN_5 using EmitterContext = Microsoft.CodeAnalysis.SourceProductionContext; #endif diff --git a/src/Shared/Helpers/Extensions.cs b/src/Shared/Helpers/Extensions.cs index c3b093c..12f0f2f 100644 --- a/src/Shared/Helpers/Extensions.cs +++ b/src/Shared/Helpers/Extensions.cs @@ -3,7 +3,7 @@ #if ROSLYN_3 using EmitterContext = Microsoft.CodeAnalysis.GeneratorExecutionContext; -#elif ROSLYN_4 +#elif ROSLYN_4 || ROSLYN_5 using EmitterContext = Microsoft.CodeAnalysis.SourceProductionContext; #endif diff --git a/src/Shared/Helpers/GeneratorUtilities.cs b/src/Shared/Helpers/GeneratorUtilities.cs index 69e660f..09e3efd 100644 --- a/src/Shared/Helpers/GeneratorUtilities.cs +++ b/src/Shared/Helpers/GeneratorUtilities.cs @@ -4,7 +4,7 @@ #if ROSLYN_3 using EmitterContext = Microsoft.CodeAnalysis.GeneratorExecutionContext; -#elif ROSLYN_4 +#elif ROSLYN_4 || ROSLYN_5 using EmitterContext = Microsoft.CodeAnalysis.SourceProductionContext; #endif diff --git a/src/Shared/Models/ParameterList.cs b/src/Shared/Models/ParameterList.cs index 19a1bf9..96ba982 100644 --- a/src/Shared/Models/ParameterList.cs +++ b/src/Shared/Models/ParameterList.cs @@ -4,7 +4,7 @@ #if ROSLYN_3 using EmitterContext = Microsoft.CodeAnalysis.GeneratorExecutionContext; -#elif ROSLYN_4 +#elif ROSLYN_4 || ROSLYN_5 using EmitterContext = Microsoft.CodeAnalysis.SourceProductionContext; #endif diff --git a/src/Shared/Models/TypeModel.cs b/src/Shared/Models/TypeModel.cs index 35f46bf..89434cf 100644 --- a/src/Shared/Models/TypeModel.cs +++ b/src/Shared/Models/TypeModel.cs @@ -170,7 +170,7 @@ private static bool IsValidProperty(IPropertySymbol property) // Not required and not init properties if (!(property.IsReadOnly || -#if ROSLYN_4_4 +#if ROSLYN_4_4 || ROSLYN_5 property.IsRequired || #endif propertySyntax.AccessorList?.Accessors diff --git a/src/Tests/ExampleTests.cs b/src/Tests/ExampleTests.cs index db0852a..5a6246f 100644 --- a/src/Tests/ExampleTests.cs +++ b/src/Tests/ExampleTests.cs @@ -2,7 +2,7 @@ using Microsoft.CodeAnalysis; using static ExampleTestsHelper; -#if ROSLYN_4_4 +#if ROSLYN_4_4 || ROSLYN_5 using Microsoft.CodeAnalysis.CSharp; #endif @@ -54,7 +54,7 @@ await Assert.That(outputCompilation.GetDiagnostics(TestHelper.CancellationToken) .ConfigureAwait(false); } -#if ROSLYN_4_4 +#if ROSLYN_4_4 || ROSLYN_5 [Test] [CombinedDataSources] public async Task EnsureRunsAreCachedCorrectly( @@ -126,7 +126,7 @@ public static IEnumerable> GetExamples() }; } -#if ROSLYN_4_4 +#if ROSLYN_4_4 || ROSLYN_5 foreach (var readmeExample in GetExamplesFiles("ReadmeExamples")) { yield return () => new CodeFileTheoryData(readmeExample) with diff --git a/src/Tests/LangExamples/PropertiesTest.cs b/src/Tests/LangExamples/PropertiesTest.cs index 3b6119b..d1d5ff7 100644 --- a/src/Tests/LangExamples/PropertiesTest.cs +++ b/src/Tests/LangExamples/PropertiesTest.cs @@ -6,7 +6,7 @@ public partial class PropertiesTest protected string ProtectedProperty { get; } public string InitProperty { get; init; } -#if ROSLYN_4_4 +#if ROSLYN_4_4 || ROSLYN_5 public required string RequiredProperty { get; set; } #endif diff --git a/src/Tests/LangExamples/Verified_5_0/PropertiesTest.cs#PropertiesTest.g.verified.cs b/src/Tests/LangExamples/Verified_5_0/PropertiesTest.cs#PropertiesTest.g.verified.cs new file mode 100644 index 0000000..de9a692 --- /dev/null +++ b/src/Tests/LangExamples/Verified_5_0/PropertiesTest.cs#PropertiesTest.g.verified.cs @@ -0,0 +1,26 @@ +//HintName: PropertiesTest.g.cs +//------------------------------------------------------------------------------ +// +// This code was generated by https://github.com/distantcam/AutoCtor +// +//------------------------------------------------------------------------------ + +partial class PropertiesTest +{ + [global::System.Runtime.CompilerServices.CompilerGenerated] + [global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCode] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification = "Generated code.")] + public PropertiesTest( + string getProperty, + string protectedProperty, + string initProperty, + string requiredProperty + ) + { + this.GetProperty = getProperty; + this.ProtectedProperty = protectedProperty; + this.InitProperty = initProperty; + this.RequiredProperty = requiredProperty; + } +} diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index b6a41e8..872bf30 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -11,7 +11,8 @@ - 4.4 + + 5.0 @@ -31,6 +32,10 @@ $(DefineConstants);ROSLYN_4;ROSLYN_4_4 + + $(DefineConstants);ROSLYN_5;ROSLYN_5_0 + + diff --git a/src/Tests/Utilities/ExampleTestsHelper.cs b/src/Tests/Utilities/ExampleTestsHelper.cs index 0c4681c..62eb300 100644 --- a/src/Tests/Utilities/ExampleTestsHelper.cs +++ b/src/Tests/Utilities/ExampleTestsHelper.cs @@ -1,8 +1,11 @@ -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using TUnit.Core.Interfaces; +#if ROSLYN_4 || ROSLYN_5 +using System.Collections.Immutable; +#endif + internal static class ExampleTestsHelper { public static readonly IEnumerable PreprocessorSymbols = [ @@ -20,6 +23,12 @@ internal static class ExampleTestsHelper #endif #if ROSLYN_4_4 "ROSLYN_4_4", +#endif +#if ROSLYN_5 + "ROSLYN_5", +#endif +#if ROSLYN_5_0 + "ROSLYN_5_0", #endif ]; @@ -75,7 +84,7 @@ public CompilationBuilder Create(CodeFileTheoryData theoryData) } } -#if ROSLYN_4 +#if ROSLYN_4 || ROSLYN_5 public static async Task AssertRunsEqual( GeneratorDriverRunResult runResult1, GeneratorDriverRunResult runResult2, diff --git a/src/Tests/Utilities/GeneratorDriverBuilder.cs b/src/Tests/Utilities/GeneratorDriverBuilder.cs index d263ca7..4ab3c47 100644 --- a/src/Tests/Utilities/GeneratorDriverBuilder.cs +++ b/src/Tests/Utilities/GeneratorDriverBuilder.cs @@ -67,6 +67,14 @@ public GeneratorDriver Build(CSharpParseOptions parseOptions) disabledOutputs: IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true )); +#elif ROSLYN_5_0 + return CSharpGeneratorDriver.Create(_generators, + parseOptions: parseOptions, + optionsProvider: new TestAnalyzerConfigOptionsProvider(_analyzerOptions), + driverOptions: new GeneratorDriverOptions( + disabledOutputs: IncrementalGeneratorOutputKind.None, + trackIncrementalGeneratorSteps: true + )); #endif }