├── .editorconfig ├── .github ├── FUNDING.yml ├── dependabot.yml ├── matchers │ └── dotnet.json ├── release.yml └── workflows │ ├── build.yml │ └── publish.yml ├── AutoCtor.sln ├── license ├── mdsnippets.json ├── readme.md ├── readme.source.md └── src ├── AutoCtor.Attributes ├── AutoConstructAttribute.cs └── AutoCtor.Attributes.csproj ├── AutoCtor.Example ├── AutoCtor.Example.csproj ├── BasicExamples.cs ├── GuardsExamples.cs └── PostConstructExamples.cs ├── AutoCtor.Roslyn3.11 ├── AutoConstructSourceGenerator.cs └── AutoCtor.Roslyn3.11.csproj ├── AutoCtor.Roslyn4.0 ├── AutoConstructSourceGenerator.cs └── AutoCtor.Roslyn4.0.csproj ├── AutoCtor.Roslyn4.4 ├── AutoConstructSourceGenerator.cs └── AutoCtor.Roslyn4.4.csproj ├── AutoCtor.Shared ├── AnalyzerReleases.Shipped.md ├── AnalyzerReleases.Unshipped.md ├── AttributeSourceGenerator │ └── Emitter.cs ├── AutoConstructSourceGenerator │ ├── Diagnostics.cs │ ├── Emitter.cs │ └── Tracking.cs ├── AutoCtor.Shared.projitems ├── AutoCtor.Shared.shproj ├── Helpers │ ├── CodeBuilder.Block.cs │ ├── CodeBuilder.InterpolatedStringHandler.cs │ ├── CodeBuilder.PartialType.cs │ ├── CodeBuilder.Templates.cs │ ├── CodeBuilder.cs │ ├── EquatableList.cs │ ├── EquatableTypeSymbol.cs │ ├── Extensions.cs │ ├── GeneratorUtilities.cs │ └── Polyfill.cs └── Models │ ├── AttributeNames.cs │ ├── IHaveDiagnostics.cs │ ├── MemberModel.cs │ ├── ModelUtilities.cs │ ├── ParameterList.cs │ ├── ParameterModel.cs │ ├── PostCtorModel.cs │ └── TypeModel.cs ├── AutoCtor.Tests ├── AutoCtor.Tests.csproj ├── ExampleTests.cs ├── Examples │ ├── AbstractClassTest.ExamplesGeneratedCode#AbstractClassTest.g.verified.cs │ ├── AbstractClassTest.cs │ ├── AllParametersSameTypeTest.ExamplesGeneratedCode#AllParametersAreSameTypeTest.g.verified.cs │ ├── AllParametersSameTypeTest.cs │ ├── AmbiguousMarkedMethods.ExamplesGeneratedCode#AmbiguousMarkedMethods.g.verified.cs │ ├── AmbiguousMarkedMethods.ExamplesGeneratedCode.verified.txt │ ├── AmbiguousMarkedMethods.cs │ ├── BaseTest.ExamplesGeneratedCode#BaseBaseClass.g.verified.cs │ ├── BaseTest.ExamplesGeneratedCode#BaseClass.g.verified.cs │ ├── BaseTest.ExamplesGeneratedCode#BaseTest.g.verified.cs │ ├── BaseTest.ExamplesGeneratedCode#ComplexBase.g.verified.cs │ ├── BaseTest.ExamplesGeneratedCode#ComplexTest.g.verified.cs │ ├── BaseTest.ExamplesGeneratedCode#TheClass.g.verified.cs │ ├── BaseTest.cs │ ├── BlankTest.cs │ ├── Broken251Release.ExamplesGeneratedCode#Broken251Release.g.verified.cs │ ├── Broken251Release.cs │ ├── ConflicingNames.ExamplesGeneratedCode#AClass.g.verified.cs │ ├── ConflicingNames.ExamplesGeneratedCode#BClass.g.verified.cs │ ├── ConflicingNames.ExamplesGeneratedCode#CClass.g.verified.cs │ ├── ConflicingNames.cs │ ├── DerivedExample.ExamplesGeneratedCode#Derived.g.verified.cs │ ├── DerivedExample.cs │ ├── ExcludeStaticAndInitialisedFieldsTest.ExamplesGeneratedCode#ExcludeStaticAndInitialisedFieldsTest.g.verified.cs │ ├── ExcludeStaticAndInitialisedFieldsTest.cs │ ├── FriendlyParameterNamesTest.ExamplesGeneratedCode#FriendlyParameterNamesTest.g.verified.cs │ ├── FriendlyParameterNamesTest.cs │ ├── GenericClassTest.ExamplesGeneratedCode#GenericClassTest[T].g.verified.cs │ ├── GenericClassTest.cs │ ├── GenericInheritanceTest.ExamplesGeneratedCode#ConcreteClass.g.verified.cs │ ├── GenericInheritanceTest.ExamplesGeneratedCode#ConcreteClass1[T].g.verified.cs │ ├── GenericInheritanceTest.ExamplesGeneratedCode#ConcreteClass2.g.verified.cs │ ├── GenericInheritanceTest.ExamplesGeneratedCode#ConcreteClassWithAnotherField.g.verified.cs │ ├── GenericInheritanceTest.ExamplesGeneratedCode#ConcreteClassWithGenericArg[T2].g.verified.cs │ ├── GenericInheritanceTest.ExamplesGeneratedCode#GenericBase2[T1, T2].g.verified.cs │ ├── GenericInheritanceTest.ExamplesGeneratedCode#GenericBase[T].g.verified.cs │ ├── GenericInheritanceTest.cs │ ├── Guard.ExamplesGeneratedCode#Guard.g.verified.cs │ ├── Guard.cs │ ├── IgnoreField.cs │ ├── InheritanceTest.ExamplesGeneratedCode#A.g.verified.cs │ ├── InheritanceTest.ExamplesGeneratedCode#B.g.verified.cs │ ├── InheritanceTest.ExamplesGeneratedCode#C.g.verified.cs │ ├── InheritanceTest.ExamplesGeneratedCode#D.g.verified.cs │ ├── InheritanceTest.ExamplesGeneratedCode#E.g.verified.cs │ ├── InheritanceTest.cs │ ├── Issue125.ExamplesGeneratedCode#OrderRequest.g.verified.cs │ ├── Issue125.cs │ ├── Issue206.ExamplesGeneratedCode#Base[T2].g.verified.cs │ ├── Issue206.ExamplesGeneratedCode#Derived.g.verified.cs │ ├── Issue206.cs │ ├── Issue299.ExamplesGeneratedCode#Issue299.g.verified.cs │ ├── Issue299.cs │ ├── KeyedServicesTest.ExamplesGeneratedCode#ChildKeyedServicesTest.g.verified.cs │ ├── KeyedServicesTest.ExamplesGeneratedCode#KeyedServicesTest[T].g.verified.cs │ ├── KeyedServicesTest.cs │ ├── KeywordsTest.ExamplesGeneratedCode#KeywordsTest.g.verified.cs │ ├── KeywordsTest.cs │ ├── MixedNestedClassAndRecordTest.ExamplesGeneratedCode#OuterClass1.OuterRecord1.OuterClass2.MixedNestedClassAndRecordTest.g.verified.cs │ ├── MixedNestedClassAndRecordTest.cs │ ├── MultipleGenericInheritance.ExamplesGeneratedCode#Example1.g.verified.cs │ ├── MultipleGenericInheritance.ExamplesGeneratedCode#Example2.g.verified.cs │ ├── MultipleGenericInheritance.ExamplesGeneratedCode#Generic[TA, TB].g.verified.cs │ ├── MultipleGenericInheritance.cs │ ├── NamespaceDoubleNestedClassTest.ExamplesGeneratedCode#TestNamespace.OuterClass1.OuterClass2.NamespaceDoubleNestedClassTest.g.verified.cs │ ├── NamespaceDoubleNestedClassTest.cs │ ├── NamespaceTest.ExamplesGeneratedCode#TestNamespace.NamespaceTest.g.verified.cs │ ├── NamespaceTest.cs │ ├── NullableAnnotationTest.ExamplesGeneratedCode#NullableAnnotationTests.g.verified.cs │ ├── NullableAnnotationTest.cs │ ├── ObsoleteBaseCtor.ExamplesGeneratedCode#AutoClass.g.verified.cs │ ├── ObsoleteBaseCtor.cs │ ├── OuterClass.ExamplesGeneratedCode#OuterClass.NestedClassTest.g.verified.cs │ ├── OuterClass.cs │ ├── PostCtorAttributeTest.ExamplesGeneratedCode#PostCtorAttributeTest.g.verified.cs │ ├── PostCtorAttributeTest.cs │ ├── PostCtorReturnsNonVoidTest.ExamplesGeneratedCode#PostCtorReturnsNonVoidTest.g.verified.cs │ ├── PostCtorReturnsNonVoidTest.ExamplesGeneratedCode.verified.txt │ ├── PostCtorReturnsNonVoidTest.cs │ ├── PostCtorWithArgumentsTest.ExamplesGeneratedCode#PostCtorWithArgumentsTest.g.verified.cs │ ├── PostCtorWithArgumentsTest.cs │ ├── PostCtorWithGenericTest.ExamplesGeneratedCode#PostCtorWithGenericTest.g.verified.cs │ ├── PostCtorWithGenericTest.ExamplesGeneratedCode.verified.txt │ ├── PostCtorWithGenericTest.cs │ ├── PostCtorWithInArgumentTest.ExamplesGeneratedCode#PostCtorWithInArgumentTest.g.verified.cs │ ├── PostCtorWithInArgumentTest.cs │ ├── PostCtorWithKeyedOutParameterTest.ExamplesGeneratedCode#PostCtorWithKeyedOutParameterTest.g.verified.cs │ ├── PostCtorWithKeyedOutParameterTest.ExamplesGeneratedCode.verified.txt │ ├── PostCtorWithKeyedOutParameterTest.cs │ ├── PostCtorWithKeyedServiceOutParameterTest.ExamplesGeneratedCode#PostCtorWithKeyedServiceOutParameterTest.g.verified.cs │ ├── PostCtorWithKeyedServiceOutParameterTest.ExamplesGeneratedCode.verified.txt │ ├── PostCtorWithKeyedServiceOutParameterTest.cs │ ├── PostCtorWithKeyedServiceTest.ExamplesGeneratedCode#BaseClass.g.verified.cs │ ├── PostCtorWithKeyedServiceTest.ExamplesGeneratedCode#PostCtorWithKeyedServiceTest.g.verified.cs │ ├── PostCtorWithKeyedServiceTest.cs │ ├── PostCtorWithMSKeyedServiceTest.ExamplesGeneratedCode#PostCtorWithMSKeyedServiceTest.g.verified.cs │ ├── PostCtorWithMSKeyedServiceTest.cs │ ├── PostCtorWithOptionalArgumentsTest.ExamplesGeneratedCode#PostCtorWithOptionalArgumentsTest.g.verified.cs │ ├── PostCtorWithOptionalArgumentsTest.ExamplesGeneratedCode.verified.txt │ ├── PostCtorWithOptionalArgumentsTest.cs │ ├── PostCtorWithOutArgumentTest.ExamplesGeneratedCode#PostCtorWithOutArgumentTest.g.verified.cs │ ├── PostCtorWithOutArgumentTest.cs │ ├── PostCtorWithRefArgumentTest.ExamplesGeneratedCode#PostCtorWithRefArgumentTest.g.verified.cs │ ├── PostCtorWithRefArgumentTest.cs │ ├── PostCtorWithRefReadonlyArgumentTest.ExamplesGeneratedCode#PostCtorWithRefReadonlyArgumentTest.g.verified.cs │ ├── PostCtorWithRefReadonlyArgumentTest.cs │ ├── RecordTest.ExamplesGeneratedCode#RecordStructTest.g.verified.cs │ ├── RecordTest.ExamplesGeneratedCode#RecordTest.g.verified.cs │ ├── RecordTest.cs │ ├── SealedTest.ExamplesGeneratedCode#SealedTest.g.verified.cs │ ├── SealedTest.cs │ ├── StructTest.ExamplesGeneratedCode#StructTest.g.verified.cs │ ├── StructTest.cs │ ├── UniqueNameTest.ExamplesGeneratedCode#UniqueNameTest.g.verified.cs │ └── UniqueNameTest.cs ├── GeneratedAttributeTests.AttributeGeneratedCode#AutoConstructAttribute.g.verified.cs ├── GeneratedAttributeTests.cs ├── GuardExamples │ ├── DisabledGuard.ExamplesGeneratedCode#DisabledGuard.g.verified.cs │ ├── DisabledGuard.cs │ ├── Guard.ExamplesGeneratedCode#Guard.g.verified.cs │ ├── Guard.cs │ ├── NullableTypes.ExamplesGeneratedCode#NullableTypes.g.verified.cs │ └── NullableTypes.cs ├── Issue73.VerifyGeneratedCode#B.TheClass.g.verified.cs ├── Issue73.cs ├── LangExamples │ ├── PropertiesTest.cs │ ├── Verified_3_11 │ │ └── PropertiesTest.ExamplesGeneratedCode#PropertiesTest.g.verified.cs │ ├── Verified_4_0 │ │ └── PropertiesTest.ExamplesGeneratedCode#PropertiesTest.g.verified.cs │ └── Verified_4_4 │ │ └── PropertiesTest.ExamplesGeneratedCode#PropertiesTest.g.verified.cs ├── Utilities │ ├── CodeFileTheoryData.cs │ ├── CompilationBuilder.cs │ ├── ExampleTestsHelper.cs │ ├── GeneratorDriverBuilder.cs │ ├── ModuleInitializer.cs │ └── Shim.cs └── VerifyChecksTests.cs ├── Common.props ├── Directory.Build.props ├── Directory.Packages.props ├── global.json └── nugetfiles ├── AutoCtor.badcompat.targets ├── AutoCtor.props └── AutoCtor.targets /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: distantcam 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: nuget 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | ignore: 9 | - dependency-name: "Microsoft.CodeAnalysis.Analyzers" 10 | - dependency-name: "Microsoft.CodeAnalysis.CSharp" 11 | groups: 12 | verify: 13 | patterns: 14 | - "verify.*" 15 | xunit: 16 | patterns: 17 | - "xunit*" 18 | -------------------------------------------------------------------------------- /.github/matchers/dotnet.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "dotnet-file", 5 | "pattern": [ 6 | { 7 | "regexp": "^(.+)\\((\\d+).+\\):\\s(\\w+)\\s(.+)\\:\\s(.*)$", 8 | "file": 1, 9 | "line": 2, 10 | "severity": 3, 11 | "code": 4, 12 | "message": 5 13 | } 14 | ] 15 | }, 16 | { 17 | "owner": "dotnet-run", 18 | "pattern": [ 19 | { 20 | "regexp": "^.+\\s\\:\\s(\\w+)\\s(.*)\\:\\s(.*)$", 21 | "severity": 1, 22 | "code": 2, 23 | "message": 3 24 | } 25 | ] 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | categories: 3 | - title: 🐞 Bug Fixes 4 | labels: 5 | - bug 6 | - title: 🏕 Features 7 | labels: 8 | - "*" 9 | exclude: 10 | labels: 11 | - dependencies 12 | - title: 👒 Dependencies 13 | labels: 14 | - dependencies 15 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: 🛠️ build 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | - feature/* 9 | - hotfix/* 10 | tags: 11 | - "[0-9]+.[0-9]+.[0-9]+" 12 | - "[0-9]+.[0-9]+.[0-9]+-**" 13 | 14 | jobs: 15 | test: 16 | name: 🧪 Run tests 17 | runs-on: ubuntu-latest 18 | strategy: 19 | matrix: 20 | roslyn: ["3.11", "4.0", "4.4"] 21 | steps: 22 | - name: 🛒 Check-out code 23 | uses: actions/checkout@v4 24 | 25 | - name: 📐 Setup .NET Core SDK 26 | uses: actions/setup-dotnet@v4 27 | with: 28 | global-json-file: src/global.json 29 | 30 | - name: 🔍 Enable problem matchers 31 | run: echo "::add-matcher::.github/matchers/dotnet.json" 32 | 33 | - name: 🛠️ Build code 34 | run: dotnet build --configuration Release 35 | 36 | - name: 🧪 Testing ${{ matrix.roslyn }} code 37 | run: > 38 | dotnet test 39 | --configuration Release 40 | -p:GeneratorVersion=${{ matrix.roslyn }} 41 | --logger GitHubActions 42 | -- 43 | RunConfiguration.CollectSourceInformation=true 44 | 45 | - name: Upload Test Results 46 | if: failure() 47 | uses: actions/upload-artifact@v4 48 | with: 49 | name: verify-test-results 50 | path: | 51 | **/*.received.* 52 | 53 | build: 54 | name: 🛠️ Build 55 | if: ${{ github.event_name == 'push' && github.ref_type == 'tag' }} 56 | runs-on: ubuntu-latest 57 | needs: test 58 | steps: 59 | - name: 🛒 Check-out code 60 | uses: actions/checkout@v4 61 | 62 | - name: 📐 Setup .NET Core SDK 63 | uses: actions/setup-dotnet@v4 64 | with: 65 | global-json-file: src/global.json 66 | 67 | - name: 🔍 Enable problem matchers 68 | run: echo "::add-matcher::.github/matchers/dotnet.json" 69 | 70 | - name: 🔧 Load packages 71 | run: dotnet restore 72 | 73 | - name: 🛠️ Build code 74 | run: dotnet build --configuration Release -p:Version=${{ github.ref_name }} -p:GitSha=${{ github.sha }} --no-restore 75 | 76 | - name: 📝 Generate Release Notes 77 | run: gh release create ${{ github.ref_name }} --draft --generate-notes nugets/*.nupkg 78 | env: 79 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 80 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: ✈️ publish 2 | 3 | on: 4 | release: 5 | types: 6 | - published 7 | 8 | jobs: 9 | publish: 10 | name: 📦 Publish nuget library 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: 📦 Download Artifact 14 | run: gh release download ${{ github.ref_name }} --repo ${{ github.repository }} --pattern '*.nupkg' 15 | env: 16 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | 18 | - name: ✈️ Push Nuget 19 | run: dotnet nuget push *.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate 20 | -------------------------------------------------------------------------------- /AutoCtor.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 17 3 | VisualStudioVersion = 17.2.32616.157 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8CC56491-C17C-44A5-8686-C41491E2E624}" 6 | ProjectSection(SolutionItems) = preProject 7 | src\nugetfiles\AutoCtor.badcompat.targets = src\nugetfiles\AutoCtor.badcompat.targets 8 | src\nugetfiles\AutoCtor.props = src\nugetfiles\AutoCtor.props 9 | src\nugetfiles\AutoCtor.targets = src\nugetfiles\AutoCtor.targets 10 | src\Common.props = src\Common.props 11 | src\Directory.Build.props = src\Directory.Build.props 12 | src\Directory.Packages.props = src\Directory.Packages.props 13 | src\global.json = src\global.json 14 | mdsnippets.json = mdsnippets.json 15 | readme.source.md = readme.source.md 16 | EndProjectSection 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoCtor.Example", "src\AutoCtor.Example\AutoCtor.Example.csproj", "{31FE2891-3F48-4FE9-9524-0250905B77B5}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoCtor.Tests", "src\AutoCtor.Tests\AutoCtor.Tests.csproj", "{C8D666C8-D2F5-4A6E-928D-EAFE8F688AAC}" 21 | EndProject 22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoCtor.Attributes", "src\AutoCtor.Attributes\AutoCtor.Attributes.csproj", "{638834EA-E4D5-429E-A11E-4BFA91FD59E2}" 23 | EndProject 24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoCtor.Roslyn3.11", "src\AutoCtor.Roslyn3.11\AutoCtor.Roslyn3.11.csproj", "{ADC68ADD-629A-4A05-8869-CD1ECF2914C1}" 25 | EndProject 26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoCtor.Roslyn4.4", "src\AutoCtor.Roslyn4.4\AutoCtor.Roslyn4.4.csproj", "{56918D57-9044-452E-8830-2739B3BBE9E3}" 27 | EndProject 28 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "AutoCtor.Shared", "src\AutoCtor.Shared\AutoCtor.Shared.shproj", "{0381B830-8FD4-4392-A38A-3B2EE86A2094}" 29 | EndProject 30 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoCtor.Roslyn4.0", "src\AutoCtor.Roslyn4.0\AutoCtor.Roslyn4.0.csproj", "{F73002A3-779E-445D-B563-85361FD8B35F}" 31 | EndProject 32 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}" 33 | ProjectSection(SolutionItems) = preProject 34 | .github\workflows\build.yml = .github\workflows\build.yml 35 | .github\workflows\publish.yml = .github\workflows\publish.yml 36 | EndProjectSection 37 | EndProject 38 | Global 39 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 40 | Debug|Any CPU = Debug|Any CPU 41 | Release|Any CPU = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 44 | {31FE2891-3F48-4FE9-9524-0250905B77B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {31FE2891-3F48-4FE9-9524-0250905B77B5}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {31FE2891-3F48-4FE9-9524-0250905B77B5}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {31FE2891-3F48-4FE9-9524-0250905B77B5}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {C8D666C8-D2F5-4A6E-928D-EAFE8F688AAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {C8D666C8-D2F5-4A6E-928D-EAFE8F688AAC}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {C8D666C8-D2F5-4A6E-928D-EAFE8F688AAC}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {C8D666C8-D2F5-4A6E-928D-EAFE8F688AAC}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {638834EA-E4D5-429E-A11E-4BFA91FD59E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {638834EA-E4D5-429E-A11E-4BFA91FD59E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {638834EA-E4D5-429E-A11E-4BFA91FD59E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {638834EA-E4D5-429E-A11E-4BFA91FD59E2}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {ADC68ADD-629A-4A05-8869-CD1ECF2914C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {ADC68ADD-629A-4A05-8869-CD1ECF2914C1}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {ADC68ADD-629A-4A05-8869-CD1ECF2914C1}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {ADC68ADD-629A-4A05-8869-CD1ECF2914C1}.Release|Any CPU.Build.0 = Release|Any CPU 60 | {56918D57-9044-452E-8830-2739B3BBE9E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {56918D57-9044-452E-8830-2739B3BBE9E3}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {56918D57-9044-452E-8830-2739B3BBE9E3}.Release|Any CPU.ActiveCfg = Release|Any CPU 63 | {56918D57-9044-452E-8830-2739B3BBE9E3}.Release|Any CPU.Build.0 = Release|Any CPU 64 | {F73002A3-779E-445D-B563-85361FD8B35F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 65 | {F73002A3-779E-445D-B563-85361FD8B35F}.Debug|Any CPU.Build.0 = Debug|Any CPU 66 | {F73002A3-779E-445D-B563-85361FD8B35F}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {F73002A3-779E-445D-B563-85361FD8B35F}.Release|Any CPU.Build.0 = Release|Any CPU 68 | EndGlobalSection 69 | GlobalSection(SolutionProperties) = preSolution 70 | HideSolutionNode = FALSE 71 | EndGlobalSection 72 | GlobalSection(NestedProjects) = preSolution 73 | {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {8CC56491-C17C-44A5-8686-C41491E2E624} 74 | EndGlobalSection 75 | GlobalSection(ExtensibilityGlobals) = postSolution 76 | SolutionGuid = {6C1E6B0F-E4E8-410D-A9C6-D9128CAC4EC8} 77 | EndGlobalSection 78 | GlobalSection(SharedMSBuildProjectFiles) = preSolution 79 | src\AutoCtor.Shared\AutoCtor.Shared.projitems*{0381b830-8fd4-4392-a38a-3b2ee86a2094}*SharedItemsImports = 13 80 | src\AutoCtor.Shared\AutoCtor.Shared.projitems*{56918d57-9044-452e-8830-2739b3bbe9e3}*SharedItemsImports = 5 81 | src\AutoCtor.Shared\AutoCtor.Shared.projitems*{adc68add-629a-4a05-8869-cd1ecf2914c1}*SharedItemsImports = 5 82 | src\AutoCtor.Shared\AutoCtor.Shared.projitems*{f73002a3-779e-445d-b563-85361fd8b35f}*SharedItemsImports = 5 83 | EndGlobalSection 84 | EndGlobal 85 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Cameron MacFarland 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /mdsnippets.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/SimonCropp/MarkdownSnippets/master/schema.json" 3 | } 4 | -------------------------------------------------------------------------------- /readme.source.md: -------------------------------------------------------------------------------- 1 | # AutoCtor 2 | 3 | [![Build Status](https://img.shields.io/github/actions/workflow/status/distantcam/autoctor/build.yml)](https://github.com/distantcam/AutoCtor/actions/workflows/build.yml) 4 | [![NuGet Status](https://img.shields.io/nuget/v/AutoCtor.svg)](https://www.nuget.org/packages/AutoCtor/) 5 | [![Nuget Downloads](https://img.shields.io/nuget/dt/autoctor.svg)](https://www.nuget.org/packages/AutoCtor/) 6 | 7 | 8 | AutoCtor is a Roslyn Source Generator that will automatically create a constructor for your class for use with constructor Dependency Injection. 9 | 10 | 11 | toc 12 | 13 | ## NuGet packages 14 | 15 | https://nuget.org/packages/AutoCtor/ 16 | 17 | ## Usage 18 | 19 | ### Your code 20 | 21 | snippet: Basic 22 | 23 | ### What gets generated 24 | 25 | snippet: BasicGeneratedCode 26 | 27 | Back to Contents 28 | ## More Features 29 | 30 | ### Post constructor Initialisation 31 | 32 | You can mark a method to be called at the end of the constructor with the attribute `[AutoPostConstruct]`. This method must return void. 33 | 34 | snippet: PostConstruct 35 | 36 | snippet: PostConstructGeneratedCode 37 | 38 | ### Keyed Services 39 | 40 | When using `Microsoft.Extensions.DependencyInjection` you can mark fields and properties with `[AutoKeyedService]` and it will be included in the constructor. 41 | 42 | snippet: KeyedService 43 | 44 | snippet: KeyedServiceGeneratedCode 45 | 46 | ### Initialize with parameters 47 | 48 | Post constructor methods can also take parameters. These parameters will be passed in from the constructor. 49 | 50 | snippet: PostConstructWithParameters 51 | 52 | snippet: PostConstructWithParametersGeneratedCode 53 | 54 | ### Initialize readonly fields with ref or out 55 | 56 | If a parameter is marked `ref` or `out` and matches the type of a readonly field, it can set that field during construction. 57 | 58 | snippet: PostConstructWithOutParameters 59 | 60 | snippet: PostConstructWithOutParametersGeneratedCode 61 | 62 | ### Argument Guards 63 | 64 | Null guards for the arguments to the constructor can be added in 2 ways. 65 | 66 | In your project you can add a `AutoCtorGuards` property. 67 | 68 | ```xml 69 | 70 | 71 | 72 | true 73 | 74 | 75 | 76 | ``` 77 | 78 | In each `AutoConstruct` attribute you can add a setting to enable/disable guards. 79 | 80 | snippet: Guards 81 | 82 | snippet: GuardsGeneratedCode 83 | 84 | ### Property Initialisation 85 | 86 | AutoCtor can set properties that are considered as read only properties. 87 | 88 | snippet: PropertyExamples 89 | 90 | Back to Contents 91 | ## More examples 92 | 93 | You can also initialise readonly fields, and AutoCtor will not include them in the constructor. 94 | 95 | snippet: PresetField 96 | 97 | snippet: PresetFieldGeneratedCode 98 | 99 | If there is a single base constructor with parameters, AutoCtor will include that base constructor in the constructor it creates. 100 | 101 | snippet: Inherit 102 | 103 | snippet: InheritGeneratedCode 104 | 105 | Back to Contents 106 | ## Embedding the attributes in your project 107 | 108 | By default, the `[AutoConstruct]` attributes referenced in your project are contained in an external dll. It is also possible to embed the attributes directly in your project. To do this, you must do two things: 109 | 110 | 1. Define the MSBuild constant `AUTOCTOR_EMBED_ATTRIBUTES`. This ensures the attributes are embedded in your project. 111 | 2. Add `compile` to the list of excluded assets in your `` element. This ensures the attributes in your project are referenced, instead of the _AutoCtor.Attributes.dll_ library. 112 | 113 | Your project file should look like this: 114 | 115 | ```xml 116 | 117 | 118 | 119 | 120 | AUTOCTOR_EMBED_ATTRIBUTES 121 | 122 | 123 | 124 | 127 | 128 | 129 | 130 | ``` 131 | 132 | Back to Contents 133 | ## Preserving usage of the `[AutoConstruct]` attribute 134 | 135 | The `[AutoConstruct]` attributes are decorated with the `[Conditional]` attribute, so their usage will not appear in the build output of your project. If you use reflection at runtime you will not find the `[AutoConstruct]` attributes. 136 | 137 | If you wish to preserve these attributes in the build output, you can define the `AUTOCTOR_USAGES` MSBuild variable. 138 | 139 | ```xml 140 | 141 | 142 | 143 | 144 | AUTOCTOR_USAGES 145 | 146 | 147 | 148 | 149 | 150 | 151 | ``` 152 | 153 | Back to Contents 154 | ## Stats 155 | 156 | ![Alt](https://repobeats.axiom.co/api/embed/8d02b2c004a5f958b4365abad3d4d1882dca200f.svg "Repobeats analytics image") 157 | -------------------------------------------------------------------------------- /src/AutoCtor.Attributes/AutoConstructAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using static System.AttributeTargets; 3 | 4 | #pragma warning disable CS9113 // Parameter is unread. 5 | 6 | namespace AutoCtor; 7 | 8 | public enum GuardSetting 9 | { 10 | Default, 11 | Disabled, 12 | Enabled 13 | } 14 | 15 | [AttributeUsage(Class | Struct, Inherited = false)] 16 | [Conditional("AUTOCTOR_USAGES")] 17 | public sealed class AutoConstructAttribute(GuardSetting guard = GuardSetting.Default) : Attribute; 18 | 19 | [AttributeUsage(Method, Inherited = false)] 20 | [Conditional("AUTOCTOR_USAGES")] 21 | public sealed class AutoPostConstructAttribute : Attribute; 22 | 23 | [AttributeUsage(Field | Property, Inherited = false)] 24 | [Conditional("AUTOCTOR_USAGES")] 25 | public sealed class AutoConstructIgnoreAttribute : Attribute; 26 | 27 | [AttributeUsage(Field | Property | Parameter, Inherited = false)] 28 | [Conditional("AUTOCTOR_USAGES")] 29 | public sealed class AutoKeyedServiceAttribute(object? key) : Attribute; 30 | -------------------------------------------------------------------------------- /src/AutoCtor.Attributes/AutoCtor.Attributes.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | AutoCtor 6 | true 7 | true 8 | 9 | 10 | 11 | AutoCtor 12 | 0.0.0 13 | Cameron MacFarland 14 | Source Generator to automatically create a constructor with all the readonly fields set. 15 | MIT 16 | readme.md 17 | $(SolutionDir)nugets 18 | https://github.com/distantcam/AutoCtor 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 30 | 32 | 33 | 34 | 35 | 37 | 38 | 40 | 41 | 43 | 44 | 46 | 48 | 49 | 51 | 53 | 55 | 56 | 58 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/AutoCtor.Example/AutoCtor.Example.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | disable 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Example/BasicExamples.cs: -------------------------------------------------------------------------------- 1 | namespace AutoCtor.BasicExamples; 2 | 3 | public interface IService; 4 | public interface IAnotherService; 5 | 6 | #region Basic 7 | 8 | [AutoConstruct] 9 | public partial class ExampleClass 10 | { 11 | private readonly IService _service; 12 | } 13 | 14 | #endregion 15 | 16 | partial class ExampleClass 17 | { 18 | #region BasicGeneratedCode 19 | public ExampleClass(IService service) 20 | { 21 | _service = service; 22 | } 23 | #endregion 24 | } 25 | 26 | #region PresetField 27 | 28 | [AutoConstruct] 29 | public partial class ClassWithPresetField 30 | { 31 | private readonly IService _service; 32 | private readonly IList _list = new List(); 33 | } 34 | 35 | #endregion 36 | 37 | partial class ClassWithPresetField 38 | { 39 | #region PresetFieldGeneratedCode 40 | public ClassWithPresetField(IService service) 41 | { 42 | _service = service; 43 | // no code to set _list 44 | } 45 | #endregion 46 | } 47 | 48 | #region Inherit 49 | 50 | public abstract class BaseClass 51 | { 52 | protected IAnotherService _anotherService; 53 | 54 | public BaseClass(IAnotherService anotherService) 55 | { 56 | _anotherService = anotherService; 57 | } 58 | } 59 | 60 | [AutoConstruct] 61 | public partial class ClassWithBase : BaseClass 62 | { 63 | private readonly IService _service; 64 | } 65 | 66 | #endregion 67 | 68 | partial class ClassWithBase 69 | { 70 | #region InheritGeneratedCode 71 | public ClassWithBase(IAnotherService anotherService, IService service) : base(anotherService) 72 | { 73 | _service = service; 74 | } 75 | #endregion 76 | } 77 | 78 | public partial class PropertyExamples 79 | { 80 | #region PropertyExamples 81 | 82 | // AutoCtor will initialise these 83 | public string GetProperty { get; } 84 | protected string ProtectedProperty { get; } 85 | public string InitProperty { get; init; } 86 | public required string RequiredProperty { get; set; } 87 | 88 | // AutoCtor will ignore these 89 | public string InitializerProperty { get; } = "Constant"; 90 | public string GetSetProperty { get; set; } 91 | public string FixedProperty => "Constant"; 92 | public string RedirectedProperty => InitializerProperty; 93 | 94 | #endregion 95 | } 96 | 97 | #region KeyedService 98 | 99 | [AutoConstruct] 100 | public partial class KeyedExampleClass 101 | { 102 | [AutoKeyedService("key")] 103 | private readonly IService _keyedService; 104 | } 105 | 106 | #endregion 107 | 108 | partial class KeyedExampleClass 109 | { 110 | #region KeyedServiceGeneratedCode 111 | public KeyedExampleClass( 112 | [Microsoft.Extensions.DependencyInjection.FromKeyedServices("key")] 113 | IService keyedService) 114 | { 115 | _keyedService = keyedService; 116 | } 117 | #endregion 118 | } 119 | -------------------------------------------------------------------------------- /src/AutoCtor.Example/GuardsExamples.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | public class Service { } 4 | 5 | #region Guards 6 | 7 | [AutoConstruct(GuardSetting.Enabled)] 8 | public partial class GuardedClass 9 | { 10 | private readonly Service _service; 11 | } 12 | 13 | #endregion 14 | 15 | 16 | partial class GuardedClass 17 | { 18 | #region GuardsGeneratedCode 19 | public GuardedClass(Service service) 20 | { 21 | _service = service ?? throw new ArgumentNullException(nameof(service)); 22 | } 23 | #endregion 24 | } 25 | -------------------------------------------------------------------------------- /src/AutoCtor.Example/PostConstructExamples.cs: -------------------------------------------------------------------------------- 1 | namespace AutoCtor.PostConstructExamples; 2 | 3 | public interface IService; 4 | public interface IOtherService; 5 | public interface IInitialiseService; 6 | public interface IServiceFactory { IService CreateService(); } 7 | 8 | #pragma warning disable IDE0040 // Add accessibility modifiers 9 | 10 | #region PostConstruct 11 | 12 | [AutoConstruct] 13 | public partial class PostConstructMethod 14 | { 15 | private readonly IService _service; 16 | 17 | [AutoPostConstruct] 18 | private void Initialize() 19 | { 20 | } 21 | } 22 | 23 | #endregion 24 | 25 | partial class PostConstructMethod 26 | { 27 | #region PostConstructGeneratedCode 28 | public PostConstructMethod(IService service) 29 | { 30 | _service = service; 31 | Initialize(); 32 | } 33 | #endregion 34 | } 35 | 36 | #region PostConstructWithParameters 37 | 38 | public partial class PostConstructMethodWithParameters 39 | { 40 | private readonly IService _service; 41 | 42 | [AutoPostConstruct] 43 | private void Initialize(IInitialiseService initialiseService) 44 | { 45 | } 46 | } 47 | 48 | #endregion 49 | 50 | partial class PostConstructMethodWithParameters 51 | { 52 | #region PostConstructWithParametersGeneratedCode 53 | public PostConstructMethodWithParameters(IService service, IInitialiseService initialiseService) 54 | { 55 | _service = service; 56 | Initialize(initialiseService); 57 | } 58 | #endregion 59 | } 60 | 61 | #region PostConstructWithOutParameters 62 | 63 | public partial class PostConstructWithOutParameters 64 | { 65 | private readonly IService _service; 66 | private readonly IOtherService _otherService; 67 | 68 | [AutoPostConstruct] 69 | private void Initialize(IServiceFactory serviceFactory, out IService service) 70 | { 71 | service = serviceFactory.CreateService(); 72 | } 73 | } 74 | 75 | #endregion 76 | 77 | partial class PostConstructWithOutParameters 78 | { 79 | #region PostConstructWithOutParametersGeneratedCode 80 | public PostConstructWithOutParameters(IOtherService otherService, IServiceFactory serviceFactory) 81 | { 82 | _otherService = otherService; 83 | Initialize(serviceFactory, out _service); 84 | } 85 | #endregion 86 | } 87 | -------------------------------------------------------------------------------- /src/AutoCtor.Roslyn3.11/AutoConstructSourceGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using Microsoft.CodeAnalysis; 3 | 4 | namespace AutoCtor; 5 | 6 | public sealed partial class AttributeSourceGenerator : ISourceGenerator 7 | { 8 | public void Initialize(GeneratorInitializationContext context) 9 | { 10 | context.RegisterForPostInitialization(static c => 11 | c.AddSource(Emitter.HintName, Emitter.GenerateSource())); 12 | } 13 | public void Execute(GeneratorExecutionContext context) { } 14 | } 15 | 16 | public sealed partial class AutoConstructSourceGenerator : ISourceGenerator 17 | { 18 | private sealed class SyntaxContextReceiver(CancellationToken cancellationToken) : ISyntaxContextReceiver 19 | { 20 | public List? TypeModels { get; private set; } 21 | public List? MarkedMethods { get; private set; } 22 | 23 | public void OnVisitSyntaxNode(GeneratorSyntaxContext context) 24 | { 25 | INamedTypeSymbol? type; 26 | IMethodSymbol? method; 27 | if (GeneratorUtilities.IsTypeDeclarationWithAttributes(context.Node, cancellationToken) 28 | 29 | && (type = GeneratorUtilities.GetSymbol(context, cancellationToken)) != null 30 | 31 | && GeneratorUtilities.HasAttribute(type, AttributeNames.AutoConstruct)) 32 | { 33 | (TypeModels ??= []).Add(TypeModel.Create(type)); 34 | } 35 | 36 | else if (GeneratorUtilities.IsMethodDeclarationWithAttributes(context.Node, cancellationToken) 37 | 38 | && (method = GeneratorUtilities.GetSymbol(context, cancellationToken)) != null 39 | 40 | && GeneratorUtilities.HasAttribute(method, AttributeNames.AutoPostConstruct)) 41 | { 42 | (MarkedMethods ??= []).Add(PostCtorModel.Create(method)); 43 | } 44 | } 45 | } 46 | 47 | public void Initialize(GeneratorInitializationContext context) 48 | { 49 | context.RegisterForSyntaxNotifications(static () => 50 | new SyntaxContextReceiver(CancellationToken.None)); 51 | } 52 | 53 | public void Execute(GeneratorExecutionContext context) 54 | { 55 | if (context.SyntaxContextReceiver is not SyntaxContextReceiver receiver 56 | || receiver.TypeModels == null) 57 | return; 58 | 59 | var enableGuards = false; 60 | if (context.AnalyzerConfigOptions.GlobalOptions 61 | .TryGetValue("build_property.AutoCtorGuards", out var projectGuardSetting)) 62 | { 63 | enableGuards = 64 | projectGuardSetting.Equals("true", StringComparison.OrdinalIgnoreCase) || 65 | projectGuardSetting.Equals("enable", StringComparison.OrdinalIgnoreCase); 66 | } 67 | 68 | var models = ( 69 | receiver.TypeModels?.ToImmutableArray() ?? ImmutableArray.Empty, 70 | receiver.MarkedMethods?.ToImmutableArray() ?? ImmutableArray.Empty 71 | ); 72 | Emitter.GenerateSource(context, (models, enableGuards)); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/AutoCtor.Roslyn3.11/AutoCtor.Roslyn3.11.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | $(DefineConstants);ROSLYN_3;ROSLYN_3_11 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Roslyn4.0/AutoConstructSourceGenerator.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace AutoCtor; 4 | 5 | public sealed partial class AttributeSourceGenerator : IIncrementalGenerator 6 | { 7 | public void Initialize(IncrementalGeneratorInitializationContext context) 8 | { 9 | context.RegisterPostInitializationOutput(static c => 10 | c.AddSource(Emitter.HintName, Emitter.GenerateSource())); 11 | } 12 | } 13 | 14 | public sealed partial class AutoConstructSourceGenerator : IIncrementalGenerator 15 | { 16 | public void Initialize(IncrementalGeneratorInitializationContext context) 17 | { 18 | var properties = context.AnalyzerConfigOptionsProvider 19 | .Select(static (p, ct) => 20 | { 21 | return p.GlobalOptions.TryGetValue("build_property.AutoCtorGuards", out var value) 22 | && (value.Equals("true", StringComparison.OrdinalIgnoreCase) 23 | || value.Equals("enable", StringComparison.OrdinalIgnoreCase)); 24 | }); 25 | 26 | var types = context.SyntaxProvider.CreateSyntaxProvider( 27 | GeneratorUtilities.IsTypeDeclarationWithAttributes, 28 | GeneratorUtilities.GetSymbol) 29 | .Where(static x => GeneratorUtilities.HasAttribute(x, AttributeNames.AutoConstruct)) 30 | .Select(static (x, _) => TypeModel.Create(x!)) 31 | .Collect(); 32 | 33 | var postCtorMethods = context.SyntaxProvider.CreateSyntaxProvider( 34 | GeneratorUtilities.IsMethodDeclarationWithAttributes, 35 | GeneratorUtilities.GetSymbol) 36 | .Where(static x => GeneratorUtilities.HasAttribute(x, AttributeNames.AutoPostConstruct)) 37 | .Select(static (x, _) => PostCtorModel.Create(x!)) 38 | .Collect(); 39 | 40 | context.RegisterSourceOutput( 41 | types.Combine(postCtorMethods).Combine(properties), 42 | Emitter.GenerateSource); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/AutoCtor.Roslyn4.0/AutoCtor.Roslyn4.0.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | $(DefineConstants);ROSLYN_4;ROSLYN_4_0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Roslyn4.4/AutoConstructSourceGenerator.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace AutoCtor; 4 | 5 | public sealed partial class AttributeSourceGenerator : IIncrementalGenerator 6 | { 7 | public void Initialize(IncrementalGeneratorInitializationContext context) 8 | { 9 | context.RegisterPostInitializationOutput(static c => 10 | c.AddSource(Emitter.HintName, Emitter.GenerateSource())); 11 | } 12 | } 13 | 14 | public sealed partial class AutoConstructSourceGenerator : IIncrementalGenerator 15 | { 16 | public void Initialize(IncrementalGeneratorInitializationContext context) 17 | { 18 | var properties = context.AnalyzerConfigOptionsProvider 19 | .Select(static (p, ct) => 20 | { 21 | return p.GlobalOptions.TryGetValue("build_property.AutoCtorGuards", out var value) 22 | && (value.Equals("true", StringComparison.OrdinalIgnoreCase) 23 | || value.Equals("enable", StringComparison.OrdinalIgnoreCase)); 24 | }) 25 | .WithTrackingName(TrackingNames.BuildProperties); 26 | 27 | var types = context.SyntaxProvider.ForAttributeWithMetadataName( 28 | AttributeNames.AutoConstruct, 29 | GeneratorUtilities.IsTypeDeclarationWithAttributes, 30 | static (c, ct) => TypeModel.Create((INamedTypeSymbol)c.TargetSymbol)) 31 | .WithTrackingName(TrackingNames.TypeModels) 32 | .Collect(); 33 | 34 | var postCtorMethods = context.SyntaxProvider.ForAttributeWithMetadataName( 35 | AttributeNames.AutoPostConstruct, 36 | GeneratorUtilities.IsMethodDeclarationWithAttributes, 37 | static (c, ct) => PostCtorModel.Create((IMethodSymbol)c.TargetSymbol)) 38 | .WithTrackingName(TrackingNames.PostCtorMethods) 39 | .Collect(); 40 | 41 | context.RegisterSourceOutput( 42 | types.Combine(postCtorMethods).Combine(properties), 43 | Emitter.GenerateSource); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/AutoCtor.Roslyn4.4/AutoCtor.Roslyn4.4.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | $(DefineConstants);ROSLYN_4;ROSLYN_4_4 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/AnalyzerReleases.Shipped.md: -------------------------------------------------------------------------------- 1 | ; Shipped analyzer releases 2 | ; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md 3 | 4 | ## Release 2.0 5 | 6 | ### New Rules 7 | 8 | Rule ID | Category | Severity | Notes 9 | --------|----------|----------|------- 10 | ACTR001 | AutoCtor | Warning | ACTR001_AutoConstructSourceGenerator 11 | ACTR002 | AutoCtor | Warning | ACTR002_AutoConstructSourceGenerator 12 | ACTR003 | AutoCtor | Warning | ACTR003_AutoConstructSourceGenerator 13 | ACTR004 | AutoCtor | Warning | ACTR004_AutoConstructSourceGenerator 14 | 15 | ## Release 2.8 16 | 17 | ### New Rules 18 | 19 | Rule ID | Category | Severity | Notes 20 | --------|----------|----------|------- 21 | ACTR005 | AutoCtor | Warning | ACTR005_AutoConstructSourceGenerator 22 | ACTR006 | AutoCtor | Warning | ACTR006_AutoConstructSourceGenerator 23 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/AnalyzerReleases.Unshipped.md: -------------------------------------------------------------------------------- 1 | ; Unshipped analyzer release 2 | ; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md 3 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/AttributeSourceGenerator/Emitter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.Text; 3 | 4 | namespace AutoCtor; 5 | 6 | [Generator(LanguageNames.CSharp)] 7 | public partial class AttributeSourceGenerator 8 | { 9 | private static class Emitter 10 | { 11 | public static string HintName = "AutoConstructAttribute.g.cs"; 12 | 13 | public static SourceText GenerateSource() 14 | { 15 | var source = new CodeBuilder(); 16 | source.AppendHeader().AppendLine(); 17 | source.AppendLine("#if AUTOCTOR_EMBED_ATTRIBUTES"); 18 | using (source.StartBlock("namespace AutoCtor")) 19 | { 20 | source.AddCompilerGeneratedAttribute().AddGeneratedCodeAttribute(); 21 | using (source.StartBlock("internal enum GuardSetting")) 22 | { 23 | source.AppendLine("Default,"); 24 | source.AppendLine("Disabled,"); 25 | source.AppendLine("Enabled"); 26 | } 27 | 28 | source.AddCompilerGeneratedAttribute().AddGeneratedCodeAttribute(); 29 | source.AppendLine("[global::System.AttributeUsage(global::System.AttributeTargets.Class | global::System.AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]"); 30 | source.AppendLine("internal sealed class AutoConstructAttribute : global::System.Attribute"); 31 | using (source.StartBlock()) 32 | { 33 | source.AppendLine("public AutoConstructAttribute(GuardSetting guard = GuardSetting.Default)"); 34 | source.StartBlock().Dispose(); 35 | } 36 | 37 | source.AddCompilerGeneratedAttribute().AddGeneratedCodeAttribute(); 38 | source.AppendLine("[global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false, Inherited = false)]"); 39 | source.AppendLine("internal sealed class AutoPostConstructAttribute : global::System.Attribute"); 40 | source.StartBlock().Dispose(); 41 | 42 | source.AddCompilerGeneratedAttribute().AddGeneratedCodeAttribute(); 43 | source.AppendLine("[global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false, Inherited = false)]"); 44 | source.AppendLine("internal sealed class AutoConstructIgnoreAttribute : global::System.Attribute"); 45 | source.StartBlock().Dispose(); 46 | } 47 | source.AppendLine("#endif"); 48 | 49 | return source; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/AutoConstructSourceGenerator/Diagnostics.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | #if ROSLYN_3 4 | using EmitterContext = Microsoft.CodeAnalysis.GeneratorExecutionContext; 5 | #elif ROSLYN_4 6 | using EmitterContext = Microsoft.CodeAnalysis.SourceProductionContext; 7 | #endif 8 | 9 | namespace AutoCtor; 10 | 11 | internal static class Diagnostics 12 | { 13 | public static void ReportDiagnostic(EmitterContext context, IHaveDiagnostics item, DiagnosticDescriptor diagnostic) 14 | { 15 | foreach (var loc in item.Locations) 16 | context.ReportDiagnostic(Diagnostic.Create(diagnostic, loc, item.ErrorName)); 17 | } 18 | 19 | /// 20 | /// Id: ACTR001
21 | /// Title: Ambiguous marked post constructor method 22 | ///
23 | public static readonly DiagnosticDescriptor AmbiguousMarkedPostConstructMethod = new( 24 | id: "ACTR001", 25 | title: "Ambiguous marked post constructor method", 26 | messageFormat: "Only one method in a type should be marked with an [AutoPostConstruct] attribute", 27 | category: "AutoCtor", 28 | DiagnosticSeverity.Warning, 29 | isEnabledByDefault: true); 30 | 31 | /// 32 | /// Id: ACTR002
33 | /// Title: Post construct method must return void 34 | ///
35 | public static readonly DiagnosticDescriptor PostConstructMethodNotVoid = new( 36 | id: "ACTR002", 37 | title: "Post construct method must return void", 38 | messageFormat: "The method '{0}' must return void to be used as the post construct method", 39 | category: "AutoCtor", 40 | DiagnosticSeverity.Warning, 41 | isEnabledByDefault: true); 42 | 43 | /// 44 | /// Id: ACTR003
45 | /// Title: Post construct method must not have any optional arguments 46 | ///
47 | public static readonly DiagnosticDescriptor PostConstructMethodHasOptionalArgs = new( 48 | id: "ACTR003", 49 | title: "Post construct method must not have any optional arguments", 50 | messageFormat: "The parameter '{0}' must not be optional", 51 | category: "AutoCtor", 52 | DiagnosticSeverity.Warning, 53 | isEnabledByDefault: true); 54 | 55 | /// 56 | /// Id: ACTR004
57 | /// Title: Post construct method must not be generic 58 | ///
59 | public static readonly DiagnosticDescriptor PostConstructMethodCannotBeGeneric = new( 60 | id: "ACTR004", 61 | title: "Post construct method must not be generic", 62 | messageFormat: "The method '{0}' must not be generic to be used as the post construct method", 63 | category: "AutoCtor", 64 | DiagnosticSeverity.Warning, 65 | isEnabledByDefault: true); 66 | 67 | /// 68 | /// Id: ACTR005
69 | /// Title: Post construct out or ref parameter must not be a keyed service 70 | ///
71 | public static readonly DiagnosticDescriptor PostConstructOutParameterCannotBeKeyed = new( 72 | id: "ACTR005", 73 | title: "Post construct out or ref parameter must not be a keyed service", 74 | messageFormat: "The parameter '{0}' must not be a keyed service, or cannot be out or ref", 75 | category: "AutoCtor", 76 | DiagnosticSeverity.Warning, 77 | isEnabledByDefault: true); 78 | 79 | /// 80 | /// Id: ACTR006
81 | /// Title: Post construct out or ref parameter must not match a keyed field 82 | ///
83 | public static readonly DiagnosticDescriptor PostConstructOutParameterMustNotMatchKeyedField = new( 84 | id: "ACTR006", 85 | title: "Post construct out or ref parameter must not match a keyed field", 86 | messageFormat: "The field '{0}' must not be a keyed service when used as a post construct out or ref parameter", 87 | category: "AutoCtor", 88 | DiagnosticSeverity.Warning, 89 | isEnabledByDefault: true); 90 | } 91 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/AutoConstructSourceGenerator/Tracking.cs: -------------------------------------------------------------------------------- 1 | namespace AutoCtor; 2 | 3 | public partial class AutoConstructSourceGenerator 4 | { 5 | public static class TrackingNames 6 | { 7 | public static string BuildProperties => nameof(BuildProperties); 8 | public static string TypeModels => nameof(TypeModels); 9 | public static string PostCtorMethods => nameof(PostCtorMethods); 10 | 11 | public static IReadOnlyCollection AllTrackers { get; } = [ 12 | BuildProperties, 13 | TypeModels, 14 | PostCtorMethods, 15 | ]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/AutoCtor.Shared.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 0381b830-8fd4-4392-a38a-3b2ee86a2094 7 | 8 | 9 | AutoCtor.Shared 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/AutoCtor.Shared.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0381b830-8fd4-4392-a38a-3b2ee86a2094 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Helpers/CodeBuilder.Block.cs: -------------------------------------------------------------------------------- 1 | internal partial class CodeBuilder 2 | { 3 | public IDisposable StartBlock() => StartIndent("{", "}"); 4 | public IDisposable StartBlock(string line) 5 | { 6 | AppendLine(line); 7 | return StartIndent("{", "}"); 8 | } 9 | 10 | public IDisposable StartIndent(string? startLine = null, string? endLine = null) 11 | { 12 | if (!string.IsNullOrEmpty(startLine)) 13 | AppendLine(startLine!); 14 | IncreaseIndent(); 15 | return new DetentDisposable(this, endLine); 16 | } 17 | 18 | private readonly struct DetentDisposable(CodeBuilder codeBuilder, string? endLine) : IDisposable 19 | { 20 | public void Dispose() 21 | { 22 | codeBuilder.DecreaseIndent(); 23 | if (!string.IsNullOrEmpty(endLine)) 24 | codeBuilder.AppendLine(endLine!); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Helpers/CodeBuilder.InterpolatedStringHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | #pragma warning disable CS9113 // Parameter is unread. 4 | #pragma warning disable IDE0060 // Remove unused parameter 5 | 6 | internal partial class CodeBuilder 7 | { 8 | public CodeBuilder Append( 9 | [InterpolatedStringHandlerArgument("")] 10 | ref CodeBuilderInterpolatedStringHandler builder) => this; 11 | 12 | public CodeBuilder Append(bool enabled, 13 | [InterpolatedStringHandlerArgument("", nameof(enabled))] 14 | ref ConditionalCodeBuilderInterpolatedStringHandler builder) => this; 15 | 16 | public CodeBuilder AppendLineRaw( 17 | [InterpolatedStringHandlerArgument("")] 18 | ref CodeBuilderInterpolatedStringHandler builder) => AppendLine(); 19 | 20 | public CodeBuilder AppendLineRaw(bool enabled, 21 | [InterpolatedStringHandlerArgument("", nameof(enabled))] 22 | ref ConditionalCodeBuilderInterpolatedStringHandler builder) => enabled ? AppendLine() : this; 23 | 24 | public CodeBuilder AppendLine( 25 | [InterpolatedStringHandlerArgument("")] 26 | IndentedCodeBuilderInterpolatedStringHandler builder) => AppendLine(); 27 | 28 | public CodeBuilder AppendLine(bool enabled, 29 | [InterpolatedStringHandlerArgument("", nameof(enabled))] 30 | ConditionalIndentedCodeBuilderInterpolatedStringHandler builder) => enabled ? AppendLine() : this; 31 | 32 | private void AppendFormatted(IEnumerable items, string? format) 33 | { 34 | if (format == "comma") 35 | AppendCommaSeparated(items); 36 | 37 | if (format == "commaindent") 38 | AppendCommaIndented(items); 39 | } 40 | 41 | private void AppendCommaSeparated(IEnumerable items) 42 | { 43 | var comma = false; 44 | foreach (var item in items) 45 | { 46 | if (comma) 47 | Append(", "); 48 | comma = true; 49 | Append(item); 50 | } 51 | } 52 | 53 | private void AppendCommaIndented(IEnumerable items) 54 | { 55 | var length = items.Sum(s => s.Length); 56 | if (length < 60) 57 | { 58 | AppendCommaSeparated(items); 59 | return; 60 | } 61 | 62 | AppendLine(); 63 | IncreaseIndent(); 64 | var comma = false; 65 | foreach (var item in items) 66 | { 67 | if (comma) 68 | Append(",").AppendLine(); 69 | comma = true; 70 | AppendIndent().Append(item); 71 | } 72 | AppendLine(); 73 | DecreaseIndent(); 74 | AppendIndent(); 75 | } 76 | 77 | [InterpolatedStringHandler] 78 | internal readonly struct CodeBuilderInterpolatedStringHandler( 79 | int literalLength, int formattedCount, CodeBuilder codeBuilder) 80 | { 81 | public readonly void AppendLiteral(string s) => codeBuilder.Append(s); 82 | public readonly void AppendFormatted(string s) => codeBuilder.Append(s); 83 | public readonly void AppendFormatted(IEnumerable items, string? format) 84 | => codeBuilder.AppendFormatted(items, format); 85 | } 86 | 87 | [InterpolatedStringHandler] 88 | internal readonly struct ConditionalCodeBuilderInterpolatedStringHandler( 89 | int literalLength, int formattedCount, CodeBuilder codeBuilder, bool enabled) 90 | { 91 | public readonly bool AppendLiteral(string s) { if (enabled) codeBuilder.Append(s); return enabled; } 92 | public readonly bool AppendFormatted(string s) { if (enabled) codeBuilder.Append(s); return enabled; } 93 | public readonly bool AppendFormatted(IEnumerable items, string? format) 94 | { if (enabled) codeBuilder.AppendFormatted(items, format); return enabled; } 95 | } 96 | 97 | [InterpolatedStringHandler] 98 | internal class IndentedCodeBuilderInterpolatedStringHandler( 99 | int literalLength, int formattedCount, CodeBuilder codeBuilder) 100 | { 101 | private bool _hasIndented; 102 | 103 | private void EnsureIndent() 104 | { 105 | if (_hasIndented) return; 106 | codeBuilder.AppendIndent(); 107 | _hasIndented = true; 108 | } 109 | 110 | public void AppendLiteral(string s) { EnsureIndent(); codeBuilder.Append(s); } 111 | public void AppendFormatted(string s) { EnsureIndent(); codeBuilder.Append(s); } 112 | public void AppendFormatted(IEnumerable items, string? format) 113 | { EnsureIndent(); codeBuilder.AppendFormatted(items, format); } 114 | } 115 | 116 | [InterpolatedStringHandler] 117 | internal class ConditionalIndentedCodeBuilderInterpolatedStringHandler( 118 | int literalLength, int formattedCount, CodeBuilder codeBuilder, bool enabled) 119 | : IndentedCodeBuilderInterpolatedStringHandler(literalLength, formattedCount, codeBuilder) 120 | { 121 | public new bool AppendLiteral(string s) { if (enabled) base.AppendLiteral(s); return enabled; } 122 | public new bool AppendFormatted(string s) { if (enabled) base.AppendFormatted(s); return enabled; } 123 | public new bool AppendFormatted(IEnumerable items, string? format) 124 | { if (enabled) base.AppendFormatted(items, format); return enabled; } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Helpers/CodeBuilder.PartialType.cs: -------------------------------------------------------------------------------- 1 | internal interface IPartialTypeModel 2 | { 3 | string? Namespace { get; } 4 | EquatableList TypeDeclarations { get; } 5 | } 6 | 7 | internal partial class CodeBuilder 8 | { 9 | public IDisposable StartPartialType(IPartialTypeModel typeModel) 10 | { 11 | if (!string.IsNullOrEmpty(typeModel.Namespace)) 12 | { 13 | AppendLine($"namespace {typeModel.Namespace!}"); 14 | AppendLine("{"); 15 | IncreaseIndent(); 16 | } 17 | 18 | for (var i = 0; i < typeModel.TypeDeclarations.Count; i++) 19 | { 20 | AppendLine(typeModel.TypeDeclarations[i]); 21 | AppendLine("{"); 22 | IncreaseIndent(); 23 | } 24 | 25 | return new CloseBlockDisposable(this, typeModel.TypeDeclarations.Count + (typeModel.Namespace != null ? 1 : 0)); 26 | } 27 | 28 | private readonly struct CloseBlockDisposable(CodeBuilder codeBuilder, int count) : IDisposable 29 | { 30 | public void Dispose() 31 | { 32 | for (var i = 0; i < count; i++) 33 | { 34 | codeBuilder.DecreaseIndent(); 35 | codeBuilder.AppendLine("}"); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Helpers/CodeBuilder.Templates.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | internal partial class CodeBuilder 4 | { 5 | private static readonly string s_assemblyName; 6 | private static readonly string s_version; 7 | private static readonly string? s_packageProjectUrl; 8 | private static readonly string? s_gitSha; 9 | 10 | static CodeBuilder() 11 | { 12 | var assembly = Assembly.GetAssembly(typeof(CodeBuilder)); 13 | s_assemblyName = assembly?.GetCustomAttribute()?.Title ?? "Untitled"; 14 | s_version = assembly?.GetCustomAttribute()?.Version ?? "0.0.0.0"; 15 | var metadata = assembly?.GetCustomAttributes()?.ToDictionary(m => m.Key, m => m.Value); 16 | if (metadata != null) 17 | { 18 | metadata.TryGetValue("PackageProjectUrl", out s_packageProjectUrl); 19 | metadata.TryGetValue("GitSha", out s_gitSha); 20 | } 21 | } 22 | 23 | public CodeBuilder AddCompilerGeneratedAttribute() 24 | => AppendLine("[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]"); 25 | 26 | public CodeBuilder AddDebuggerNonUserCodeAttribute() 27 | => AppendLine("[global::System.Diagnostics.DebuggerNonUserCodeAttribute]"); 28 | 29 | public CodeBuilder AddGeneratedCodeAttribute() 30 | => AppendLine($"[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"{s_assemblyName}\", \"{s_version}\")]"); 31 | 32 | public CodeBuilder AppendHeader() => 33 | AppendLine($"//------------------------------------------------------------------------------") 34 | .AppendLine($"// ") 35 | .AppendLine(!string.IsNullOrEmpty(s_packageProjectUrl), $"// This code was generated by {s_packageProjectUrl!}") 36 | .AppendLine($"// Version: {s_version}") 37 | .AppendLine(!string.IsNullOrEmpty(s_gitSha), $"// SHA: {s_gitSha!}") 38 | .AppendLine($"// ") 39 | .AppendLine($"//------------------------------------------------------------------------------"); 40 | } 41 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Helpers/CodeBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Microsoft.CodeAnalysis.Text; 3 | 4 | internal partial class CodeBuilder 5 | { 6 | private readonly StringBuilder _stringBuilder = new(); 7 | private int _indent = 0; 8 | 9 | public char IndentChar { get; set; } = '\t'; 10 | public string Indent => new(IndentChar, _indent); 11 | 12 | public CodeBuilder IncreaseIndent() { _indent++; return this; } 13 | public CodeBuilder DecreaseIndent() { if (_indent > 0) _indent--; return this; } 14 | 15 | public CodeBuilder Append(string text) { _stringBuilder.Append(text); return this; } 16 | public CodeBuilder Append(bool enabled, string text) { if (enabled) _stringBuilder.Append(text); return this; } 17 | public CodeBuilder AppendLine() { _stringBuilder.AppendLine(); return this; } 18 | public CodeBuilder AppendLine(string line) { _stringBuilder.AppendLine(Indent + line); return this; } 19 | public CodeBuilder AppendLine(bool enabled, string line) { if (enabled) _stringBuilder.AppendLine(Indent + line); return this; } 20 | public CodeBuilder AppendLineRaw(string line) { _stringBuilder.AppendLine(line); return this; } 21 | public CodeBuilder AppendLineRaw(bool enabled, string line) { if (enabled) _stringBuilder.AppendLine(line); return this; } 22 | public CodeBuilder AppendIndent() { _stringBuilder.Append(Indent); return this; } 23 | 24 | public static implicit operator SourceText(CodeBuilder codeBuilder) 25 | => SourceText.From(codeBuilder._stringBuilder.ToString(), Encoding.UTF8); 26 | } 27 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Helpers/EquatableList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Immutable; 3 | 4 | internal readonly struct EquatableList : IEquatable>, IReadOnlyList, IEnumerable 5 | { 6 | private readonly IEqualityComparer _equalityComparer; 7 | private readonly ImmutableArray _data = ImmutableArray.Empty; 8 | private readonly int _hash = 0; 9 | 10 | public EquatableList(IEnumerable data, IEqualityComparer? equalityComparer = null) 11 | { 12 | _equalityComparer = equalityComparer ?? EqualityComparer.Default; 13 | _data = data.ToImmutableArray(); 14 | for (var i = 0; i < _data.Length; i++) 15 | _hash = _hash * 0x29_55_55_A5 + _equalityComparer.GetHashCode(_data[i]); 16 | } 17 | 18 | public bool Equals(EquatableList other) 19 | { 20 | if (_data.IsDefault != other._data.IsDefault) 21 | return false; 22 | if (_data.IsDefault) 23 | return true; 24 | 25 | if (_data.Length != other._data.Length) 26 | return false; 27 | 28 | var thisEnumerator = _data.GetEnumerator(); 29 | var otherEnumerator = other._data.GetEnumerator(); 30 | 31 | while (thisEnumerator.MoveNext()) 32 | { 33 | if (!otherEnumerator.MoveNext() || !_equalityComparer.Equals(thisEnumerator.Current, otherEnumerator.Current)) 34 | return false; 35 | } 36 | 37 | return !otherEnumerator.MoveNext(); 38 | } 39 | 40 | public override bool Equals(object obj) 41 | { 42 | if (obj is not EquatableList el) return false; 43 | return Equals(el); 44 | } 45 | 46 | public override int GetHashCode() => _hash; 47 | 48 | public readonly int Count => _data.Length; 49 | public readonly T this[int index] => _data[index]; 50 | 51 | public IEnumerator GetEnumerator() => _data.IsDefaultOrEmpty 52 | ? Enumerable.Empty().GetEnumerator() 53 | : ((IEnumerable)_data).GetEnumerator(); 54 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 55 | } 56 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Helpers/EquatableTypeSymbol.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | internal readonly record struct EquatableTypeSymbol(ITypeSymbol TypeSymbol) 4 | { 5 | private readonly string _fullyQualifiedString = TypeSymbol.ToDisplayString(FullyQualifiedFormat); 6 | 7 | public override int GetHashCode() => ToString().GetHashCode(); 8 | public bool Equals(EquatableTypeSymbol other) => EqualityComparer.Default.Equals(ToString(), other.ToString()); 9 | public override string ToString() => _fullyQualifiedString; 10 | } 11 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Helpers/Extensions.cs: -------------------------------------------------------------------------------- 1 | internal static class Extensions 2 | { 3 | public static T? OnlyOrDefault(this IEnumerable source) 4 | { 5 | if (source is IList list) 6 | { 7 | return list.Count switch 8 | { 9 | 1 => list[0], 10 | _ => default, 11 | }; 12 | } 13 | using var e = source.GetEnumerator(); 14 | if (!e.MoveNext()) return default; 15 | var result = e.Current; 16 | if (!e.MoveNext()) return result; 17 | return default; 18 | } 19 | 20 | public static T? OnlyOrDefault(this IEnumerable source, Func predicate) 21 | { 22 | using var e = source.GetEnumerator(); 23 | T? result = default; 24 | do 25 | { 26 | if (!e.MoveNext()) return result; 27 | } while (!predicate(e.Current)); 28 | result = e.Current; 29 | do 30 | { 31 | if (!e.MoveNext()) return result; 32 | } while (!predicate(e.Current)); 33 | return default; 34 | } 35 | 36 | public static bool MoreThan(this IEnumerable source, int limit) 37 | { 38 | if (source is ICollection collection) 39 | return collection.Count > limit; 40 | var count = 0; 41 | using var e = source.GetEnumerator(); 42 | while (e.MoveNext()) 43 | { 44 | count++; 45 | if (count > limit) 46 | return true; 47 | } 48 | return false; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Helpers/GeneratorUtilities.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | using Microsoft.CodeAnalysis.CSharp.Syntax; 4 | 5 | #if ROSLYN_3 6 | using EmitterContext = Microsoft.CodeAnalysis.GeneratorExecutionContext; 7 | #elif ROSLYN_4 8 | using EmitterContext = Microsoft.CodeAnalysis.SourceProductionContext; 9 | #endif 10 | 11 | internal static class GeneratorUtilities 12 | { 13 | public static readonly SymbolDisplayFormat HintSymbolDisplayFormat = new( 14 | globalNamespaceStyle: 15 | SymbolDisplayGlobalNamespaceStyle.Omitted, 16 | typeQualificationStyle: 17 | SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, 18 | genericsOptions: 19 | SymbolDisplayGenericsOptions.IncludeTypeParameters, 20 | miscellaneousOptions: 21 | SymbolDisplayMiscellaneousOptions.UseSpecialTypes); 22 | 23 | public static string ToParameterPrefix(this RefKind kind) 24 | { 25 | return kind switch 26 | { 27 | RefKind.Ref => "ref", 28 | RefKind.Out => "out", 29 | RefKind.In => "in", 30 | (RefKind)4 => "in", // ref readonly parameter introduced in C#12 31 | _ => string.Empty 32 | }; 33 | } 34 | 35 | public static string EscapeKeywordIdentifier(this string identifier) => 36 | SyntaxFacts.IsKeywordKind(SyntaxFacts.GetKeywordKind(identifier)) ? "@" + identifier : identifier; 37 | 38 | public static string? GetNamespace(ITypeSymbol type) => 39 | type.ContainingNamespace.IsGlobalNamespace ? null : type.ContainingNamespace.ToString(); 40 | 41 | public static EquatableList GetTypeDeclarations(ITypeSymbol type) 42 | { 43 | var typeDeclarations = new Stack(); 44 | var currentType = type; 45 | while (currentType is not null) 46 | { 47 | var typeKeyword = currentType switch 48 | { 49 | { IsRecord: true, IsValueType: true } => "record struct", 50 | { IsRecord: true, IsValueType: false } => "record", 51 | { IsRecord: false, IsValueType: true } => "struct", 52 | { IsRecord: false, IsValueType: false } => "class", 53 | _ => string.Empty 54 | }; 55 | 56 | var staticKeyword = currentType.IsStatic ? "static " : ""; 57 | var typeName = currentType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); 58 | typeDeclarations.Push($"{staticKeyword}partial {typeKeyword} {typeName}"); 59 | currentType = currentType.ContainingType; 60 | } 61 | return new EquatableList(typeDeclarations); 62 | } 63 | 64 | public static string GetHintName(ITypeSymbol type) 65 | { 66 | return type.ToDisplayString(HintSymbolDisplayFormat) 67 | .Replace('<', '[') 68 | .Replace('>', ']'); 69 | } 70 | 71 | public static bool IsTypeDeclarationWithAttributes(SyntaxNode node, CancellationToken cancellationToken) 72 | => node is TypeDeclarationSyntax { AttributeLists.Count: > 0 }; 73 | 74 | public static bool IsMethodDeclarationWithAttributes(SyntaxNode node, CancellationToken cancellationToken) 75 | => node is MethodDeclarationSyntax { AttributeLists.Count: > 0 }; 76 | 77 | public static TSymbol? GetSymbol(GeneratorSyntaxContext context, CancellationToken cancellationToken) where TSymbol : class, ISymbol 78 | => context.SemanticModel.GetDeclaredSymbol(context.Node, cancellationToken) as TSymbol; 79 | 80 | public static bool HasAttribute(ISymbol? symbol, string attributeName) 81 | { 82 | return symbol != null && symbol.GetAttributes().Any(a => a.AttributeClass?.ToDisplayString() == attributeName); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Helpers/Polyfill.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace System.Runtime.CompilerServices; 4 | 5 | // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IsExternalInit.cs 6 | [EditorBrowsable(EditorBrowsableState.Never)] 7 | internal static class IsExternalInit { } 8 | 9 | // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/InterpolatedStringHandlerAttribute.cs 10 | /// Indicates the attributed type is to be used as an interpolated string handler. 11 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] 12 | internal sealed class InterpolatedStringHandlerAttribute : Attribute 13 | { 14 | /// Initializes the . 15 | public InterpolatedStringHandlerAttribute() { } 16 | } 17 | 18 | // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/InterpolatedStringHandlerArgumentAttribute.cs 19 | /// Indicates which arguments to a method involving an interpolated string handler should be passed to that handler. 20 | [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] 21 | internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute 22 | { 23 | /// Initializes a new instance of the class. 24 | /// The name of the argument that should be passed to the handler. 25 | /// The empty string may be used as the name of the receiver in an instance method. 26 | public InterpolatedStringHandlerArgumentAttribute(string argument) => Arguments = [argument]; 27 | 28 | /// Initializes a new instance of the class. 29 | /// The names of the arguments that should be passed to the handler. 30 | /// The empty string may be used as the name of the receiver in an instance method. 31 | public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) => Arguments = arguments; 32 | 33 | /// Gets the names of the arguments that should be passed to the handler. 34 | /// The empty string may be used as the name of the receiver in an instance method. 35 | public string[] Arguments { get; } 36 | } 37 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Models/AttributeNames.cs: -------------------------------------------------------------------------------- 1 | internal static class AttributeNames 2 | { 3 | public const string AutoConstruct = "AutoCtor.AutoConstructAttribute"; 4 | public const string AutoPostConstruct = "AutoCtor.AutoPostConstructAttribute"; 5 | public const string AutoConstructIgnore = "AutoCtor.AutoConstructIgnoreAttribute"; 6 | public const string AutoKeyedService = "AutoCtor.AutoKeyedServiceAttribute"; 7 | } 8 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Models/IHaveDiagnostics.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | internal interface IHaveDiagnostics 4 | { 5 | string ErrorName { get; } 6 | EquatableList Locations { get; } 7 | } 8 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Models/MemberModel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using static ModelUtilities; 3 | 4 | internal readonly record struct MemberModel( 5 | EquatableTypeSymbol Type, 6 | string FriendlyName, 7 | string IdentifierName, 8 | string ErrorName, 9 | string? KeyedService, 10 | 11 | bool IsReferenceType, 12 | bool IsNullableAnnotated, 13 | 14 | EquatableList Locations 15 | ) : IHaveDiagnostics 16 | { 17 | public static MemberModel Create(IFieldSymbol field) 18 | { 19 | var friendlyName = field.Name.Length > 1 && field.Name[0] == '_' 20 | ? field.Name.Substring(1).EscapeKeywordIdentifier() 21 | : field.Name.EscapeKeywordIdentifier(); 22 | 23 | return new MemberModel( 24 | Type: new(field.Type), 25 | FriendlyName: friendlyName, 26 | IdentifierName: "this." + field.Name.EscapeKeywordIdentifier(), 27 | ErrorName: field.Name, 28 | KeyedService: GetServiceKey(field), 29 | 30 | IsReferenceType: field.Type.IsReferenceType, 31 | IsNullableAnnotated: field.Type.NullableAnnotation == NullableAnnotation.Annotated, 32 | 33 | Locations: new(field.Locations) 34 | ); 35 | } 36 | 37 | public static MemberModel Create(IPropertySymbol property) 38 | { 39 | var friendlyName = new string([char.ToLower(property.Name[0]), .. property.Name.Substring(1)]).EscapeKeywordIdentifier(); 40 | 41 | return new MemberModel( 42 | Type: new(property.Type), 43 | FriendlyName: friendlyName, 44 | IdentifierName: "this." + property.Name.EscapeKeywordIdentifier(), 45 | ErrorName: property.Name, 46 | KeyedService: GetServiceKey(property), 47 | 48 | IsReferenceType: property.Type.IsReferenceType, 49 | IsNullableAnnotated: property.Type.NullableAnnotation == NullableAnnotation.Annotated, 50 | 51 | Locations: new(property.Locations) 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Models/ModelUtilities.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | 4 | internal static class ModelUtilities 5 | { 6 | public static string? GetServiceKey(ISymbol symbol) 7 | { 8 | var keyedService = symbol.GetAttributes() 9 | .Where(a => a.AttributeClass?.ToDisplayString() == AttributeNames.AutoKeyedService 10 | || a.AttributeClass?.ToDisplayString() == "Microsoft.Extensions.DependencyInjection.FromKeyedServicesAttribute") 11 | .FirstOrDefault(); 12 | 13 | if (keyedService != null) 14 | return keyedService.ConstructorArguments[0].ToCSharpString(); 15 | 16 | return null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Models/ParameterList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using AutoCtor; 3 | using Microsoft.CodeAnalysis; 4 | 5 | #if ROSLYN_3 6 | using EmitterContext = Microsoft.CodeAnalysis.GeneratorExecutionContext; 7 | #elif ROSLYN_4 8 | using EmitterContext = Microsoft.CodeAnalysis.SourceProductionContext; 9 | #endif 10 | 11 | internal class ParameterListBuilder(IEnumerable fields, IEnumerable properties) 12 | { 13 | private IEnumerable _baseParameters = []; 14 | private IEnumerable _postCtorParameters = []; 15 | 16 | public void AddBaseParameters(IEnumerable baseParameters) 17 | => _baseParameters = baseParameters; 18 | 19 | public void AddPostCtorParameters(IEnumerable postCtorParameters) 20 | => _postCtorParameters = postCtorParameters; 21 | 22 | public ParameterList Build(EmitterContext context) 23 | { 24 | var baseParameters = new List(); 25 | var postCtorParameters = new List(); 26 | var parametersMap = new Dictionary(); 27 | var parameterModels = new List(); 28 | 29 | var nameHash = new HashSet(); 30 | var uniqueNames = new Dictionary(); 31 | 32 | foreach (var p in _baseParameters) 33 | { 34 | var name = GetUniqueName(p, nameHash, uniqueNames); 35 | parameterModels.Add(p); 36 | 37 | baseParameters.Add(name); 38 | } 39 | foreach (var m in fields) 40 | { 41 | // ref/out from postctor 42 | if (_postCtorParameters.Any(p => p.Type == m.Type 43 | && (p.RefKind == RefKind.Ref || p.RefKind == RefKind.Out))) 44 | continue; 45 | 46 | var p = new ParameterModel( 47 | RefKind: RefKind.None, 48 | Name: m.FriendlyName, 49 | ErrorName: m.ErrorName, 50 | KeyedService: m.KeyedService, 51 | IsOptional: false, 52 | IsOutOrRef: false, 53 | Locations: m.Locations, 54 | Type: m.Type); 55 | var name = GetUniqueName(p, nameHash, uniqueNames); 56 | parameterModels.Add(p); 57 | 58 | parametersMap.Add(m, name); 59 | } 60 | foreach (var m in properties) 61 | { 62 | var p = new ParameterModel( 63 | RefKind: RefKind.None, 64 | Name: m.FriendlyName, 65 | ErrorName: m.ErrorName, 66 | KeyedService: m.KeyedService, 67 | IsOptional: false, 68 | IsOutOrRef: false, 69 | Locations: m.Locations, 70 | Type: m.Type); 71 | var name = GetUniqueName(p, nameHash, uniqueNames); 72 | parameterModels.Add(p); 73 | 74 | parametersMap.Add(m, name); 75 | } 76 | foreach (var p in _postCtorParameters) 77 | { 78 | var isOutOrRefParameter = p.RefKind == RefKind.Ref || p.RefKind == RefKind.Out; 79 | var matchingField = fields.FirstOrDefault(m => isOutOrRefParameter && m.Type == p.Type); 80 | if (matchingField != default) 81 | { 82 | if (matchingField.KeyedService != null) 83 | { 84 | Diagnostics.ReportDiagnostic(context, matchingField, 85 | Diagnostics.PostConstructOutParameterMustNotMatchKeyedField); 86 | } 87 | 88 | postCtorParameters.Add(p.RefKind != RefKind.None 89 | ? $"{p.RefKind.ToParameterPrefix()} {matchingField.IdentifierName}" 90 | : matchingField.IdentifierName); 91 | continue; 92 | } 93 | 94 | var name = GetUniqueName(p, nameHash, uniqueNames); 95 | parameterModels.Add(p); 96 | 97 | postCtorParameters.Add(p.RefKind != RefKind.None 98 | ? $"{p.RefKind.ToParameterPrefix()} {name}" : name); 99 | } 100 | 101 | var constructorParameters = uniqueNames.Select(ConstructorParameterCSharp).ToList(); 102 | 103 | return new( 104 | constructorParameters, 105 | baseParameters, 106 | postCtorParameters, 107 | parametersMap, 108 | parameterModels 109 | ); 110 | } 111 | 112 | private static string ConstructorParameterCSharp(KeyValuePair u) 113 | { 114 | if (u.Key.KeyedService != null) 115 | return $"[global::Microsoft.Extensions.DependencyInjection.FromKeyedServices({u.Key.KeyedService})] {u.Key.Type} {u.Value}"; 116 | 117 | return $"{u.Key.Type} {u.Value}"; 118 | } 119 | 120 | private string GetUniqueName(ParameterModel p, HashSet nameHash, Dictionary uniqueNames) 121 | { 122 | if (uniqueNames.TryGetValue(p, out var name)) 123 | return name; 124 | 125 | var i = 0; 126 | name = p.Name; 127 | while (nameHash.Contains(name)) 128 | { 129 | name = p.Name + i++; 130 | } 131 | nameHash.Add(name); 132 | uniqueNames.Add(p, name); 133 | return name; 134 | } 135 | } 136 | 137 | internal class ParameterList( 138 | IEnumerable ctorParameterDeclarations, 139 | IEnumerable baseParameters, 140 | IEnumerable postCtorParameters, 141 | Dictionary parameterMap, 142 | IEnumerable parameterModels 143 | ) : IEnumerable 144 | { 145 | public bool HasBaseParameters => baseParameters.Any(); 146 | public IEnumerable CtorParameterDeclarations => ctorParameterDeclarations; 147 | public IEnumerable BaseParameters => baseParameters; 148 | public IEnumerable PostCtorParameters => postCtorParameters; 149 | 150 | public string? GetParameter(MemberModel m) => 151 | parameterMap.TryGetValue(m, out var result) ? result : null; 152 | 153 | public IEnumerator GetEnumerator() => parameterModels.GetEnumerator(); 154 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 155 | } 156 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Models/ParameterModel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | internal readonly record struct ParameterModel( 4 | RefKind RefKind, 5 | string Name, 6 | string ErrorName, 7 | string? KeyedService, 8 | bool IsOptional, 9 | bool IsOutOrRef, 10 | EquatableList Locations, 11 | EquatableTypeSymbol Type 12 | ) : IHaveDiagnostics 13 | { 14 | public static ParameterModel Create(IParameterSymbol parameter) 15 | { 16 | return new( 17 | RefKind: parameter.RefKind, 18 | Name: parameter.Name.EscapeKeywordIdentifier(), 19 | ErrorName: parameter.Name, 20 | KeyedService: ModelUtilities.GetServiceKey(parameter), 21 | IsOptional: parameter.IsOptional, 22 | IsOutOrRef: parameter.RefKind == RefKind.Ref 23 | || parameter.RefKind == RefKind.Out, 24 | Locations: new(parameter.Locations), 25 | Type: new(parameter.Type) 26 | ); 27 | } 28 | 29 | public bool Equals(ParameterModel other) 30 | { 31 | return EqualityComparer.Default.Equals(Name, other.Name) 32 | && EqualityComparer.Default.Equals(KeyedService, other.KeyedService) 33 | && EqualityComparer.Default.Equals(Type, other.Type); 34 | } 35 | 36 | public override int GetHashCode() 37 | { 38 | return (EqualityComparer.Default.GetHashCode(Name) * -1521134295 39 | + EqualityComparer.Default.GetHashCode(KeyedService)) * -1521134295 40 | + EqualityComparer.Default.GetHashCode(Type); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/AutoCtor.Shared/Models/PostCtorModel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | internal readonly record struct PostCtorModel( 4 | string TypeKey, 5 | string Name, 6 | string ErrorName, 7 | bool ReturnsVoid, 8 | bool IsGenericMethod, 9 | 10 | EquatableList Parameters, 11 | EquatableList Locations 12 | ) : IHaveDiagnostics 13 | { 14 | public static PostCtorModel Create(IMethodSymbol method) 15 | { 16 | return new( 17 | TypeKey: TypeModel.CreateKey(method.ContainingType), 18 | Name: method.Name, 19 | ErrorName: method.Name, 20 | ReturnsVoid: method.ReturnsVoid, 21 | IsGenericMethod: method.IsGenericMethod, 22 | 23 | Parameters: new(method.Parameters.Select(ParameterModel.Create)), 24 | Locations: new(method.Locations) 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/AutoCtor.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | exe 5 | net8.0 6 | false 7 | CS0169;CS0414 8 | 9 | 10 | 11 | 12 | 13 | 4.4 14 | 15 | 16 | 17 | obj\roslyn$(GeneratorVersion)\ 18 | bin\roslyn$(GeneratorVersion)\ 19 | 20 | 21 | 22 | $(DefineConstants);ROSLYN_3;ROSLYN_3_11 23 | 24 | 25 | 26 | $(DefineConstants);ROSLYN_4;ROSLYN_4_0 27 | 28 | 29 | 30 | $(DefineConstants);ROSLYN_4;ROSLYN_4_4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | all 54 | runtime; build; native; contentfiles; analyzers; buildtransitive 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/ExampleTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp; 4 | using static ExampleTestsHelper; 5 | 6 | namespace AutoCtor.Tests; 7 | 8 | public class ExampleTests 9 | { 10 | [Theory] 11 | [MemberData(nameof(GetExamples))] 12 | public async Task ExamplesGeneratedCode(CodeFileTheoryData theoryData) 13 | { 14 | var builder = CreateCompilation(theoryData); 15 | var compilation = await builder.Build(nameof(ExampleTests)); 16 | var driver = new GeneratorDriverBuilder() 17 | .AddGenerator(new AutoConstructSourceGenerator()) 18 | .WithAnalyzerOptions(theoryData.Options) 19 | .Build(builder.ParseOptions) 20 | .RunGenerators(compilation, TestContext.Current.CancellationToken); 21 | 22 | await Verify(driver) 23 | .UseDirectory(theoryData.VerifiedDirectory) 24 | .UseTypeName(theoryData.Name) 25 | .IgnoreParametersForVerified(); 26 | } 27 | 28 | [Theory] 29 | [MemberData(nameof(GetExamples))] 30 | public async Task CodeCompilesProperly(CodeFileTheoryData theoryData) 31 | { 32 | var builder = CreateCompilation(theoryData); 33 | var compilation = await builder.Build(nameof(ExampleTests)); 34 | new GeneratorDriverBuilder() 35 | .AddGenerator(new AutoConstructSourceGenerator()) 36 | .WithAnalyzerOptions(theoryData.Options) 37 | .Build(builder.ParseOptions) 38 | .RunGeneratorsAndUpdateCompilation( 39 | compilation, 40 | out var outputCompilation, 41 | out _, 42 | TestContext.Current.CancellationToken); 43 | 44 | Assert.Empty(outputCompilation.GetDiagnostics(TestContext.Current.CancellationToken) 45 | .Where(d => !theoryData.IgnoredCompileDiagnostics.Contains(d.Id))); 46 | } 47 | 48 | #if ROSLYN_4_4 49 | [Theory] 50 | [MemberData(nameof(GetExamples))] 51 | public async Task EnsureRunsAreCachedCorrectly(CodeFileTheoryData theoryData) 52 | { 53 | var builder = CreateCompilation(theoryData); 54 | var compilation = await builder.Build(nameof(ExampleTests)); 55 | 56 | var driver = new GeneratorDriverBuilder() 57 | .AddGenerator(new AutoConstructSourceGenerator()) 58 | .WithAnalyzerOptions(theoryData.Options) 59 | .Build(builder.ParseOptions); 60 | 61 | driver = driver.RunGenerators(compilation, TestContext.Current.CancellationToken); 62 | var firstResult = driver.GetRunResult(); 63 | 64 | // Change the compilation 65 | compilation = compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText("// dummy", 66 | CSharpParseOptions.Default.WithLanguageVersion(theoryData.LangPreview 67 | ? LanguageVersion.Preview 68 | : LanguageVersion.Latest), 69 | cancellationToken: TestContext.Current.CancellationToken)); 70 | 71 | driver = driver.RunGenerators(compilation, TestContext.Current.CancellationToken); 72 | var secondResult = driver.GetRunResult(); 73 | 74 | AssertRunsEqual(firstResult, secondResult, 75 | AutoConstructSourceGenerator.TrackingNames.AllTrackers); 76 | } 77 | #endif 78 | 79 | // ---------------------------------------------------------------------------------------- 80 | 81 | private static CompilationBuilder CreateCompilation(CodeFileTheoryData theoryData) 82 | { 83 | return CreateCompilation(theoryData) 84 | .AddNugetReference( 85 | "Microsoft.Extensions.DependencyInjection.Abstractions", "9.0.4"); 86 | } 87 | 88 | private static DirectoryInfo? BaseDir { get; } = new DirectoryInfo(Environment.CurrentDirectory)?.Parent?.Parent; 89 | 90 | private static IEnumerable GetExamplesFiles(string path) => Directory.GetFiles(Path.Combine(BaseDir?.FullName ?? "", path), "*.cs").Where(e => !e.Contains(".g.")); 91 | 92 | public static TheoryData GetExamples() 93 | { 94 | if (BaseDir == null) 95 | throw new Exception("BaseDir is null"); 96 | 97 | var data = new TheoryData(); 98 | 99 | foreach (var example in GetExamplesFiles("Examples")) 100 | { 101 | data.Add(new CodeFileTheoryData(example) with 102 | { 103 | IgnoredCompileDiagnostics = ["CS0414", "CS0169"] // Ignore unused fields 104 | }); 105 | } 106 | 107 | foreach (var guardExample in GetExamplesFiles("GuardExamples")) 108 | { 109 | data.Add(new CodeFileTheoryData(guardExample) with 110 | { 111 | Options = new() { { "build_property.AutoCtorGuards", "true" } } 112 | }); 113 | } 114 | 115 | foreach (var langExample in GetExamplesFiles("LangExamples")) 116 | { 117 | var verifiedName = string.Concat("Verified_", PreprocessorSymbols.Last().AsSpan(7)); 118 | data.Add(new CodeFileTheoryData(langExample) with 119 | { 120 | VerifiedDirectory = Path.Combine(Path.GetDirectoryName(langExample) ?? "", verifiedName), 121 | LangPreview = true, 122 | }); 123 | } 124 | 125 | return data; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/AbstractClassTest.ExamplesGeneratedCode#AbstractClassTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: AbstractClassTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class AbstractClassTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public AbstractClassTest(int item) 13 | { 14 | this._item = item; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/AbstractClassTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | [AutoConstruct] 4 | public abstract partial class AbstractClassTest 5 | { 6 | private readonly int _item; 7 | } 8 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/AllParametersSameTypeTest.ExamplesGeneratedCode#AllParametersAreSameTypeTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: AllParametersAreSameTypeTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class AllParametersAreSameTypeTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public AllParametersAreSameTypeTest(global::IService baseService, global::IService service) : base(baseService) 13 | { 14 | this._service = service; 15 | Initialize(service); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/AllParametersSameTypeTest.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | 3 | [AutoCtor.AutoConstruct] 4 | public partial class AllParametersAreSameTypeTest : BaseClass 5 | { 6 | private readonly IService _service; 7 | 8 | [AutoCtor.AutoPostConstruct] 9 | private void Initialize(IService service) 10 | { 11 | } 12 | } 13 | 14 | public abstract class BaseClass 15 | { 16 | public BaseClass(IService baseService) 17 | { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/AmbiguousMarkedMethods.ExamplesGeneratedCode#AmbiguousMarkedMethods.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: AmbiguousMarkedMethods.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class AmbiguousMarkedMethods 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public AmbiguousMarkedMethods(global::IService service) 13 | { 14 | this._service = service; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/AmbiguousMarkedMethods.ExamplesGeneratedCode.verified.txt: -------------------------------------------------------------------------------- 1 | { 2 | Diagnostics: [ 3 | { 4 | Location: /* 5 | [AutoCtor.AutoPostConstruct] 6 | private void Initialize() 7 | ^^^^^^^^^^ 8 | { 9 | */ 10 | : (9,17)-(9,27), 11 | Message: Only one method in a type should be marked with an [AutoPostConstruct] attribute, 12 | Severity: Warning, 13 | WarningLevel: 1, 14 | Descriptor: { 15 | Id: ACTR001, 16 | Title: Ambiguous marked post constructor method, 17 | MessageFormat: Only one method in a type should be marked with an [AutoPostConstruct] attribute, 18 | Category: AutoCtor, 19 | DefaultSeverity: Warning, 20 | IsEnabledByDefault: true 21 | } 22 | }, 23 | { 24 | Location: /* 25 | [AutoCtor.AutoPostConstruct] 26 | private void Initialize(IAnotherService anotherService) 27 | ^^^^^^^^^^ 28 | { 29 | */ 30 | : (14,17)-(14,27), 31 | Message: Only one method in a type should be marked with an [AutoPostConstruct] attribute, 32 | Severity: Warning, 33 | WarningLevel: 1, 34 | Descriptor: { 35 | Id: ACTR001, 36 | Title: Ambiguous marked post constructor method, 37 | MessageFormat: Only one method in a type should be marked with an [AutoPostConstruct] attribute, 38 | Category: AutoCtor, 39 | DefaultSeverity: Warning, 40 | IsEnabledByDefault: true 41 | } 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/AmbiguousMarkedMethods.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | public interface IAnotherService { } 3 | 4 | [AutoCtor.AutoConstruct] 5 | public partial class AmbiguousMarkedMethods 6 | { 7 | private readonly IService _service; 8 | 9 | [AutoCtor.AutoPostConstruct] 10 | private void Initialize() 11 | { 12 | } 13 | 14 | [AutoCtor.AutoPostConstruct] 15 | private void Initialize(IAnotherService anotherService) 16 | { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/BaseTest.ExamplesGeneratedCode#BaseBaseClass.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: BaseBaseClass.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class BaseBaseClass 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public BaseBaseClass(int number) 13 | { 14 | this._number = number; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/BaseTest.ExamplesGeneratedCode#BaseClass.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: BaseClass.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class BaseClass 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public BaseClass(int number, string text) : base(number) 13 | { 14 | this._text = text; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/BaseTest.ExamplesGeneratedCode#BaseTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: BaseTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class BaseTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public BaseTest(string text, int value) : base(text) 13 | { 14 | this._value = value; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/BaseTest.ExamplesGeneratedCode#ComplexBase.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: ComplexBase.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class ComplexBase 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public ComplexBase(string baseValue) 13 | { 14 | this._baseValue = baseValue; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/BaseTest.ExamplesGeneratedCode#ComplexTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: ComplexTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class ComplexTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public ComplexTest(string baseValue, string value) : base(baseValue) 13 | { 14 | this._value = value; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/BaseTest.ExamplesGeneratedCode#TheClass.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: TheClass.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class TheClass 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public TheClass(int number, string text, bool flag) : base(number, text) 13 | { 14 | this._flag = flag; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/BaseTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | public abstract class SimpleBase 4 | { 5 | protected SimpleBase(string text) 6 | { 7 | } 8 | } 9 | 10 | [AutoConstruct] 11 | public partial class BaseTest : SimpleBase 12 | { 13 | private readonly int _value; 14 | } 15 | 16 | [AutoConstruct] 17 | public abstract partial class ComplexBase 18 | { 19 | private readonly string _baseValue; 20 | } 21 | 22 | [AutoConstruct] 23 | public abstract partial class ComplexTest : ComplexBase 24 | { 25 | private readonly string _value; 26 | } 27 | 28 | [AutoConstruct] 29 | public partial class BaseBaseClass 30 | { 31 | private readonly int _number; 32 | } 33 | 34 | [AutoConstruct] 35 | public partial class BaseClass : BaseBaseClass 36 | { 37 | private readonly string _text; 38 | } 39 | 40 | [AutoConstruct] 41 | public partial class TheClass : BaseClass 42 | { 43 | private readonly bool _flag; 44 | } 45 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/BlankTest.cs: -------------------------------------------------------------------------------- 1 | [AutoCtor.AutoConstruct] 2 | public partial class Blank 3 | { 4 | } 5 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Broken251Release.ExamplesGeneratedCode#Broken251Release.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Broken251Release.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class Broken251Release 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public Broken251Release(global::IService service) 13 | { 14 | this._service = service; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Broken251Release.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | 3 | [AutoCtor.AutoConstruct] 4 | public partial class OtherClass 5 | { 6 | } 7 | 8 | [AutoCtor.AutoConstruct] 9 | public partial class Broken251Release 10 | { 11 | private readonly IService _service; 12 | } 13 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/ConflicingNames.ExamplesGeneratedCode#AClass.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: AClass.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class AClass 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public AClass(global::IServiceA service) 13 | { 14 | this._service = service; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/ConflicingNames.ExamplesGeneratedCode#BClass.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: BClass.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class BClass 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public BClass(global::IServiceA service, global::IServiceB service0) : base(service) 13 | { 14 | this._service = service0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/ConflicingNames.ExamplesGeneratedCode#CClass.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: CClass.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class CClass 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public CClass( 13 | global::IServiceA service, 14 | global::IServiceB service0, 15 | global::IServiceC service1 16 | ) : base(service, service0) 17 | { 18 | this._service = service1; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/ConflicingNames.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | public interface IServiceC { } 4 | 5 | [AutoCtor.AutoConstruct] 6 | public partial class AClass 7 | { 8 | private readonly IServiceA _service; 9 | } 10 | 11 | [AutoCtor.AutoConstruct] 12 | public partial class BClass : AClass 13 | { 14 | private readonly IServiceB _service; 15 | } 16 | 17 | [AutoCtor.AutoConstruct] 18 | public partial class CClass : BClass 19 | { 20 | private readonly IServiceC _service; 21 | } 22 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/DerivedExample.ExamplesGeneratedCode#Derived.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Derived.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class Derived 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public Derived(global::ILogger logger) : base(logger) 13 | { 14 | this.logger = logger; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/DerivedExample.cs: -------------------------------------------------------------------------------- 1 | public interface ILogger 2 | { 3 | } 4 | 5 | public class Base 6 | { 7 | public Base(ILogger logger) 8 | { 9 | } 10 | } 11 | 12 | [AutoCtor.AutoConstruct] 13 | public partial class Derived : Base 14 | { 15 | private readonly ILogger logger; 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/ExcludeStaticAndInitialisedFieldsTest.ExamplesGeneratedCode#ExcludeStaticAndInitialisedFieldsTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: ExcludeStaticAndInitialisedFieldsTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class ExcludeStaticAndInitialisedFieldsTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public ExcludeStaticAndInitialisedFieldsTest(int s) 13 | { 14 | this._s = s; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/ExcludeStaticAndInitialisedFieldsTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using AutoCtor; 3 | 4 | [AutoConstruct] 5 | public partial class ExcludeStaticAndInitialisedFieldsTest 6 | { 7 | private readonly static int S = 4; 8 | private readonly int _s; 9 | private const int C = 5; 10 | 11 | private readonly IList _list = new List(); 12 | } 13 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/FriendlyParameterNamesTest.ExamplesGeneratedCode#FriendlyParameterNamesTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: FriendlyParameterNamesTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class FriendlyParameterNamesTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public FriendlyParameterNamesTest(int underscorePrefix, int camelCase, int PascalCase) 13 | { 14 | this._underscorePrefix = underscorePrefix; 15 | this.camelCase = camelCase; 16 | this.PascalCase = PascalCase; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/FriendlyParameterNamesTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | [AutoConstruct] 4 | public partial class FriendlyParameterNamesTest 5 | { 6 | private readonly int _underscorePrefix; 7 | private readonly int camelCase; 8 | private readonly int PascalCase; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/GenericClassTest.ExamplesGeneratedCode#GenericClassTest[T].g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: GenericClassTest[T].g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class GenericClassTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public GenericClassTest(T item) 13 | { 14 | this._item = item; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/GenericClassTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | [AutoConstruct] 4 | public partial class GenericClassTest 5 | { 6 | private readonly T _item; 7 | } 8 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/GenericInheritanceTest.ExamplesGeneratedCode#ConcreteClass.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: ConcreteClass.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class ConcreteClass 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public ConcreteClass(global::IServiceA t) : base(t) 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/GenericInheritanceTest.ExamplesGeneratedCode#ConcreteClass1[T].g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: ConcreteClass1[T].g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class ConcreteClass1 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public ConcreteClass1(global::IServiceA t1, T t2) : base(t1, t2) 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/GenericInheritanceTest.ExamplesGeneratedCode#ConcreteClass2.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: ConcreteClass2.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class ConcreteClass2 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public ConcreteClass2(global::IServiceA t1, global::IServiceB t2) : base(t1, t2) 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/GenericInheritanceTest.ExamplesGeneratedCode#ConcreteClassWithAnotherField.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: ConcreteClassWithAnotherField.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class ConcreteClassWithAnotherField 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public ConcreteClassWithAnotherField(global::IServiceA t, global::IServiceB serviceb) : base(t) 13 | { 14 | this._serviceb = serviceb; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/GenericInheritanceTest.ExamplesGeneratedCode#ConcreteClassWithGenericArg[T2].g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: ConcreteClassWithGenericArg[T2].g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class ConcreteClassWithGenericArg 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public ConcreteClassWithGenericArg(T2 t) : base(t) 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/GenericInheritanceTest.ExamplesGeneratedCode#GenericBase2[T1, T2].g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: GenericBase2[T1, T2].g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class GenericBase2 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public GenericBase2(T1 t1, T2 t2) 13 | { 14 | this._t1 = t1; 15 | this._t2 = t2; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/GenericInheritanceTest.ExamplesGeneratedCode#GenericBase[T].g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: GenericBase[T].g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class GenericBase 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public GenericBase(T t) 13 | { 14 | this._t = t; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/GenericInheritanceTest.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | 4 | [AutoCtor.AutoConstruct] 5 | public partial class GenericBase 6 | { 7 | protected readonly T _t; 8 | } 9 | 10 | [AutoCtor.AutoConstruct] 11 | public partial class ConcreteClass : GenericBase 12 | { 13 | } 14 | 15 | [AutoCtor.AutoConstruct] 16 | public partial class ConcreteClassWithGenericArg : GenericBase 17 | { 18 | } 19 | 20 | [AutoCtor.AutoConstruct] 21 | public partial class ConcreteClassWithAnotherField : ConcreteClass 22 | { 23 | protected readonly IServiceB _serviceb; 24 | } 25 | 26 | [AutoCtor.AutoConstruct] 27 | public partial class GenericBase2 28 | { 29 | protected readonly T1 _t1; 30 | protected readonly T2 _t2; 31 | } 32 | 33 | [AutoCtor.AutoConstruct] 34 | public partial class ConcreteClass1 : GenericBase2 35 | { 36 | } 37 | 38 | [AutoCtor.AutoConstruct] 39 | public partial class ConcreteClass2 : ConcreteClass1 40 | { 41 | } 42 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Guard.ExamplesGeneratedCode#Guard.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Guard.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class Guard 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public Guard(string value) 13 | { 14 | this._value = value ?? throw new global::System.ArgumentNullException("value"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Guard.cs: -------------------------------------------------------------------------------- 1 | [AutoCtor.AutoConstruct(guard: AutoCtor.GuardSetting.Enabled)] 2 | internal partial class Guard 3 | { 4 | private readonly string _value; 5 | } 6 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/IgnoreField.cs: -------------------------------------------------------------------------------- 1 | [AutoCtor.AutoConstruct] 2 | public partial class IgnoreField 3 | { 4 | [AutoCtor.AutoConstructIgnore] 5 | private readonly string? _ignored; 6 | } 7 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/InheritanceTest.ExamplesGeneratedCode#A.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: A.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class A 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public A( 13 | global::IServiceE serviceE, 14 | global::IServiceD serviceD, 15 | global::IServiceC serviceC, 16 | global::IServiceB serviceB, 17 | global::IServiceA serviceA 18 | ) : base(serviceE, serviceD, serviceC, serviceB) 19 | { 20 | this._serviceA = serviceA; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/InheritanceTest.ExamplesGeneratedCode#B.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: B.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class B 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public B( 13 | global::IServiceE serviceE, 14 | global::IServiceD serviceD, 15 | global::IServiceC serviceC, 16 | global::IServiceB serviceB 17 | ) : base(serviceE, serviceD, serviceC) 18 | { 19 | this._serviceB = serviceB; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/InheritanceTest.ExamplesGeneratedCode#C.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: C.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class C 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public C( 13 | global::IServiceE serviceE, 14 | global::IServiceD serviceD, 15 | global::IServiceC serviceC 16 | ) : base(serviceE, serviceD) 17 | { 18 | this._serviceC = serviceC; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/InheritanceTest.ExamplesGeneratedCode#D.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: D.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class D 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public D(global::IServiceE serviceE, global::IServiceD serviceD) : base(serviceE) 13 | { 14 | this._serviceD = serviceD; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/InheritanceTest.ExamplesGeneratedCode#E.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: E.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class E 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public E(global::IServiceE serviceE) 13 | { 14 | this._serviceE = serviceE; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/InheritanceTest.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | public interface IServiceC { } 4 | public interface IServiceD { } 5 | public interface IServiceE { } 6 | 7 | [AutoCtor.AutoConstruct] 8 | public partial class A : B 9 | { 10 | private readonly IServiceA _serviceA; 11 | } 12 | 13 | [AutoCtor.AutoConstruct] 14 | public partial class B : C 15 | { 16 | private readonly IServiceB _serviceB; 17 | } 18 | 19 | [AutoCtor.AutoConstruct] 20 | public partial class C : D 21 | { 22 | private readonly IServiceC _serviceC; 23 | } 24 | 25 | [AutoCtor.AutoConstruct] 26 | public partial class D : E 27 | { 28 | private readonly IServiceD _serviceD; 29 | } 30 | 31 | [AutoCtor.AutoConstruct] 32 | public partial class E : F 33 | { 34 | private readonly IServiceE _serviceE; 35 | } 36 | 37 | public class F 38 | { 39 | } 40 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Issue125.ExamplesGeneratedCode#OrderRequest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: OrderRequest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial record OrderRequest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public OrderRequest(string Id) : base(Id) 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Issue125.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | internal abstract record RequestBase(string Id) 4 | { 5 | } 6 | 7 | [AutoConstruct] 8 | internal partial record OrderRequest : RequestBase 9 | { 10 | } 11 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Issue206.ExamplesGeneratedCode#Base[T2].g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Base[T2].g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class Base 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public Base(global::ILogger> logger) 13 | { 14 | this.Logger = logger; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Issue206.ExamplesGeneratedCode#Derived.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Derived.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class Derived 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public Derived(global::ILogger> logger) : base(logger) 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Issue206.cs: -------------------------------------------------------------------------------- 1 | public interface ILogger 2 | { 3 | } 4 | 5 | [AutoCtor.AutoConstruct] 6 | public partial class Base 7 | { 8 | protected ILogger> Logger { get; } 9 | } 10 | 11 | [AutoCtor.AutoConstruct] 12 | public partial class Derived : Base 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Issue299.ExamplesGeneratedCode#Issue299.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Issue299.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class Issue299 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public Issue299() 13 | { 14 | Inititialise(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/Issue299.cs: -------------------------------------------------------------------------------- 1 | [AutoCtor.AutoConstruct] 2 | public partial class Issue299 3 | { 4 | [AutoCtor.AutoPostConstruct] 5 | private void Inititialise() 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/KeyedServicesTest.ExamplesGeneratedCode#ChildKeyedServicesTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: ChildKeyedServicesTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class ChildKeyedServicesTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public ChildKeyedServicesTest( 13 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices(null)] global::IService @null, 14 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("key")] global::IService @string, 15 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices(0)] global::IService @int, 16 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices(true)] global::IService @bool, 17 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices(Keys.Default)] global::IService @enum, 18 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("generic")] global::IService generic, 19 | global::IService notKeyed 20 | ) : base(@null, @string, @int, @bool, @enum, generic, notKeyed) 21 | { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/KeyedServicesTest.ExamplesGeneratedCode#KeyedServicesTest[T].g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: KeyedServicesTest[T].g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class KeyedServicesTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public KeyedServicesTest( 13 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices(null)] global::IService @null, 14 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("key")] global::IService @string, 15 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices(0)] global::IService @int, 16 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices(true)] global::IService @bool, 17 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices(Keys.Default)] global::IService @enum, 18 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("generic")] global::IService generic, 19 | global::IService notKeyed 20 | ) 21 | { 22 | this._null = @null; 23 | this._string = @string; 24 | this._int = @int; 25 | this._bool = @bool; 26 | this._enum = @enum; 27 | this._generic = generic; 28 | this._notKeyed = notKeyed; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/KeyedServicesTest.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | public interface IService { } 3 | 4 | public enum Keys 5 | { 6 | Default 7 | } 8 | 9 | [AutoCtor.AutoConstruct] 10 | public partial class KeyedServicesTest 11 | { 12 | [AutoCtor.AutoKeyedServiceAttribute(null)] 13 | private readonly IService _null; 14 | [AutoCtor.AutoKeyedServiceAttribute("key")] 15 | private readonly IService _string; 16 | [AutoCtor.AutoKeyedServiceAttribute(0)] 17 | private readonly IService _int; 18 | [AutoCtor.AutoKeyedServiceAttribute(true)] 19 | private readonly IService _bool; 20 | [AutoCtor.AutoKeyedServiceAttribute(Keys.Default)] 21 | private readonly IService _enum; 22 | [AutoCtor.AutoKeyedServiceAttribute("generic")] 23 | private readonly IService _generic; 24 | private readonly IService _notKeyed; 25 | } 26 | 27 | [AutoCtor.AutoConstruct] 28 | public partial class ChildKeyedServicesTest : KeyedServicesTest 29 | { 30 | } 31 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/KeywordsTest.ExamplesGeneratedCode#KeywordsTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: KeywordsTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class KeywordsTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public KeywordsTest(int @base, int @int, int @class, int @private) 13 | { 14 | this.@base = @base; 15 | this.@int = @int; 16 | this.@class = @class; 17 | this._private = @private; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/KeywordsTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | [AutoConstruct] 4 | public partial class KeywordsTest 5 | { 6 | private readonly int @base; 7 | private readonly int @int; 8 | private readonly int @class; 9 | private readonly int _private; 10 | } 11 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/MixedNestedClassAndRecordTest.ExamplesGeneratedCode#OuterClass1.OuterRecord1.OuterClass2.MixedNestedClassAndRecordTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: OuterClass1.OuterRecord1.OuterClass2.MixedNestedClassAndRecordTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class OuterClass1 9 | { 10 | partial record OuterRecord1 11 | { 12 | partial class OuterClass2 13 | { 14 | partial record MixedNestedClassAndRecordTest 15 | { 16 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 17 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 18 | public MixedNestedClassAndRecordTest(int item) 19 | { 20 | this._item = item; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/MixedNestedClassAndRecordTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | public partial class OuterClass1 4 | { 5 | public partial record OuterRecord1 6 | { 7 | public partial class OuterClass2 8 | { 9 | [AutoConstruct] 10 | public partial record MixedNestedClassAndRecordTest 11 | { 12 | private readonly int _item; 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/MultipleGenericInheritance.ExamplesGeneratedCode#Example1.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Example1.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class Example1 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public Example1(global::IServiceA a, global::IServiceB b, global::IServiceC c) : base(a, b) 13 | { 14 | this.c = c; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/MultipleGenericInheritance.ExamplesGeneratedCode#Example2.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Example2.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class Example2 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public Example2(global::IServiceD a, global::IServiceE b, global::IServiceF f) : base(a, b) 13 | { 14 | this.f = f; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/MultipleGenericInheritance.ExamplesGeneratedCode#Generic[TA, TB].g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Generic[TA, TB].g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class Generic 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public Generic(TA a, TB b) 13 | { 14 | this.a = a; 15 | this.b = b; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/MultipleGenericInheritance.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | public interface IServiceC { } 4 | public interface IServiceD { } 5 | public interface IServiceE { } 6 | public interface IServiceF { } 7 | 8 | [AutoCtor.AutoConstruct] 9 | public partial class Generic 10 | { 11 | protected readonly TA a; 12 | protected readonly TB b; 13 | } 14 | 15 | [AutoCtor.AutoConstruct] 16 | public partial class Example1 : Generic 17 | { 18 | private readonly IServiceC c; 19 | } 20 | 21 | [AutoCtor.AutoConstruct] 22 | public partial class Example2 : Generic 23 | { 24 | private readonly IServiceF f; 25 | } 26 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/NamespaceDoubleNestedClassTest.ExamplesGeneratedCode#TestNamespace.OuterClass1.OuterClass2.NamespaceDoubleNestedClassTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: TestNamespace.OuterClass1.OuterClass2.NamespaceDoubleNestedClassTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | namespace TestNamespace 9 | { 10 | partial class OuterClass1 11 | { 12 | partial class OuterClass2 13 | { 14 | partial class NamespaceDoubleNestedClassTest 15 | { 16 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 17 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 18 | public NamespaceDoubleNestedClassTest(int item) 19 | { 20 | this._item = item; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/NamespaceDoubleNestedClassTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | namespace TestNamespace 4 | { 5 | public partial class OuterClass1 6 | { 7 | public partial class OuterClass2 8 | { 9 | [AutoConstruct] 10 | public partial class NamespaceDoubleNestedClassTest 11 | { 12 | private readonly int _item; 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/NamespaceTest.ExamplesGeneratedCode#TestNamespace.NamespaceTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: TestNamespace.NamespaceTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | namespace TestNamespace 9 | { 10 | partial class NamespaceTest 11 | { 12 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 13 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 14 | public NamespaceTest(int item) 15 | { 16 | this._item = item; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/NamespaceTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | namespace TestNamespace 4 | { 5 | [AutoConstruct] 6 | public partial class NamespaceTest 7 | { 8 | private readonly int _item; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/NullableAnnotationTest.ExamplesGeneratedCode#NullableAnnotationTests.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: NullableAnnotationTests.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class NullableAnnotationTests 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public NullableAnnotationTests( 13 | global::IServiceA nullableService, 14 | global::IServiceB guardedService 15 | ) 16 | { 17 | this._nullableService = nullableService; 18 | this._guardedService = guardedService ?? throw new global::System.ArgumentNullException("guardedService"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/NullableAnnotationTest.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | 4 | [AutoCtor.AutoConstruct(guard: AutoCtor.GuardSetting.Enabled)] 5 | public partial class NullableAnnotationTests 6 | { 7 | private readonly IServiceA? _nullableService; 8 | private readonly IServiceB _guardedService; 9 | } 10 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/ObsoleteBaseCtor.ExamplesGeneratedCode#AutoClass.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: AutoClass.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class AutoClass 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public AutoClass(string firstName, string lastName) : base(firstName, lastName) 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/ObsoleteBaseCtor.cs: -------------------------------------------------------------------------------- 1 | public class BaseWith2Constructors 2 | { 3 | [System.Obsolete] 4 | protected BaseWith2Constructors(string name) { } 5 | 6 | protected BaseWith2Constructors(string firstName, string lastName) { } 7 | } 8 | 9 | [AutoCtor.AutoConstruct] 10 | public partial class AutoClass : BaseWith2Constructors 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/OuterClass.ExamplesGeneratedCode#OuterClass.NestedClassTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: OuterClass.NestedClassTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class OuterClass 9 | { 10 | partial class NestedClassTest 11 | { 12 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 13 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 14 | public NestedClassTest(int item) 15 | { 16 | this._item = item; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/OuterClass.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | public partial class OuterClass 4 | { 5 | [AutoConstruct] 6 | public partial class NestedClassTest 7 | { 8 | private readonly int _item; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorAttributeTest.ExamplesGeneratedCode#PostCtorAttributeTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorAttributeTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorAttributeTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorAttributeTest(global::IService service) 13 | { 14 | this._service = service; 15 | Initialize(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorAttributeTest.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | 3 | [AutoCtor.AutoConstruct] 4 | public partial class PostCtorAttributeTest 5 | { 6 | private readonly IService _service; 7 | 8 | [AutoCtor.AutoPostConstruct] 9 | private void Initialize() 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorReturnsNonVoidTest.ExamplesGeneratedCode#PostCtorReturnsNonVoidTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorReturnsNonVoidTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorReturnsNonVoidTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorReturnsNonVoidTest(global::IService service) 13 | { 14 | this._service = service; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorReturnsNonVoidTest.ExamplesGeneratedCode.verified.txt: -------------------------------------------------------------------------------- 1 | { 2 | Diagnostics: [ 3 | { 4 | Location: /* 5 | [AutoCtor.AutoPostConstruct] 6 | private System.Threading.Tasks.Task InitAsync() => System.Threading.Tasks.Task.CompletedTask; 7 | ^^^^^^^^^ 8 | } 9 | */ 10 | : (8,40)-(8,49), 11 | Message: The method 'InitAsync' must return void to be used as the post construct method, 12 | Severity: Warning, 13 | WarningLevel: 1, 14 | Descriptor: { 15 | Id: ACTR002, 16 | Title: Post construct method must return void, 17 | MessageFormat: The method '{0}' must return void to be used as the post construct method, 18 | Category: AutoCtor, 19 | DefaultSeverity: Warning, 20 | IsEnabledByDefault: true 21 | } 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorReturnsNonVoidTest.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | 3 | [AutoCtor.AutoConstruct] 4 | public partial class PostCtorReturnsNonVoidTest 5 | { 6 | private readonly IService _service; 7 | 8 | [AutoCtor.AutoPostConstruct] 9 | private System.Threading.Tasks.Task InitAsync() => System.Threading.Tasks.Task.CompletedTask; 10 | } 11 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithArgumentsTest.ExamplesGeneratedCode#PostCtorWithArgumentsTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithArgumentsTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithArgumentsTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithArgumentsTest(global::IServiceA a, global::IServiceB b) 13 | { 14 | this.a = a; 15 | Initialize(b); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithArgumentsTest.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | 4 | [AutoCtor.AutoConstruct] 5 | public partial class PostCtorWithArgumentsTest 6 | { 7 | private readonly IServiceA a; 8 | 9 | [AutoCtor.AutoPostConstruct] 10 | private void Initialize(IServiceB b) 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithGenericTest.ExamplesGeneratedCode#PostCtorWithGenericTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithGenericTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithGenericTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithGenericTest(global::IService service) 13 | { 14 | this._service = service; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithGenericTest.ExamplesGeneratedCode.verified.txt: -------------------------------------------------------------------------------- 1 | { 2 | Diagnostics: [ 3 | { 4 | Location: /* 5 | [AutoCtor.AutoPostConstruct] 6 | private void Initialize(T t) 7 | ^^^^^^^^^^ 8 | { 9 | */ 10 | : (8,17)-(8,27), 11 | Message: The method 'Initialize' must not be generic to be used as the post construct method, 12 | Severity: Warning, 13 | WarningLevel: 1, 14 | Descriptor: { 15 | Id: ACTR004, 16 | Title: Post construct method must not be generic, 17 | MessageFormat: The method '{0}' must not be generic to be used as the post construct method, 18 | Category: AutoCtor, 19 | DefaultSeverity: Warning, 20 | IsEnabledByDefault: true 21 | } 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithGenericTest.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | 3 | [AutoCtor.AutoConstruct] 4 | public partial class PostCtorWithGenericTest 5 | { 6 | private readonly IService _service; 7 | 8 | [AutoCtor.AutoPostConstruct] 9 | private void Initialize(T t) 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithInArgumentTest.ExamplesGeneratedCode#PostCtorWithInArgumentTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithInArgumentTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithInArgumentTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithInArgumentTest( 13 | global::IServiceA serviceA, 14 | global::IServiceB serviceB, 15 | global::IServiceFactory serviceFactory 16 | ) 17 | { 18 | this._serviceA = serviceA; 19 | this._serviceB = serviceB; 20 | Initialize(serviceFactory, in serviceB); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithInArgumentTest.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | public interface IServiceFactory { IServiceB CreateService(); } 4 | 5 | [AutoCtor.AutoConstruct] 6 | public partial class PostCtorWithInArgumentTest 7 | { 8 | private readonly IServiceA _serviceA; 9 | private readonly IServiceB _serviceB; 10 | 11 | [AutoCtor.AutoPostConstruct] 12 | private void Initialize(IServiceFactory serviceFactory, in IServiceB serviceB) 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithKeyedOutParameterTest.ExamplesGeneratedCode#PostCtorWithKeyedOutParameterTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithKeyedOutParameterTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithKeyedOutParameterTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithKeyedOutParameterTest(global::IService service) 13 | { 14 | this._service = service; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithKeyedOutParameterTest.ExamplesGeneratedCode.verified.txt: -------------------------------------------------------------------------------- 1 | { 2 | Diagnostics: [ 3 | { 4 | Location: /* 5 | [AutoCtor.AutoPostConstruct] 6 | private void Initialize([AutoCtor.AutoKeyedService("keyed")] out IService service) 7 | ^^^^^^^ 8 | { 9 | */ 10 | : (8,78)-(8,85), 11 | Message: The parameter 'service' must not be a keyed service, or cannot be out or ref, 12 | Severity: Warning, 13 | WarningLevel: 1, 14 | Descriptor: { 15 | Id: ACTR005, 16 | Title: Post construct out or ref parameter must not be a keyed service, 17 | MessageFormat: The parameter '{0}' must not be a keyed service, or cannot be out or ref, 18 | Category: AutoCtor, 19 | DefaultSeverity: Warning, 20 | IsEnabledByDefault: true 21 | } 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithKeyedOutParameterTest.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | 3 | [AutoCtor.AutoConstruct] 4 | public partial class PostCtorWithKeyedOutParameterTest 5 | { 6 | private readonly IService _service; 7 | 8 | [AutoCtor.AutoPostConstruct] 9 | private void Initialize([AutoCtor.AutoKeyedService("keyed")] out IService service) 10 | { 11 | service = new Service(); 12 | } 13 | 14 | private class Service : IService { } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithKeyedServiceOutParameterTest.ExamplesGeneratedCode#PostCtorWithKeyedServiceOutParameterTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithKeyedServiceOutParameterTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithKeyedServiceOutParameterTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithKeyedServiceOutParameterTest() 13 | { 14 | Initialize(out this._service); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithKeyedServiceOutParameterTest.ExamplesGeneratedCode.verified.txt: -------------------------------------------------------------------------------- 1 | { 2 | Diagnostics: [ 3 | { 4 | Location: /* 5 | [AutoCtor.AutoKeyedService("keyed")] 6 | private readonly IService _service; 7 | ^^^^^^^^ 8 | 9 | */ 10 | : (6,30)-(6,38), 11 | Message: The field '_service' must not be a keyed service when used as a post construct out or ref parameter, 12 | Severity: Warning, 13 | WarningLevel: 1, 14 | Descriptor: { 15 | Id: ACTR006, 16 | Title: Post construct out or ref parameter must not match a keyed field, 17 | MessageFormat: The field '{0}' must not be a keyed service when used as a post construct out or ref parameter, 18 | Category: AutoCtor, 19 | DefaultSeverity: Warning, 20 | IsEnabledByDefault: true 21 | } 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithKeyedServiceOutParameterTest.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | 3 | [AutoCtor.AutoConstruct] 4 | public partial class PostCtorWithKeyedServiceOutParameterTest 5 | { 6 | [AutoCtor.AutoKeyedService("keyed")] 7 | private readonly IService _service; 8 | 9 | [AutoCtor.AutoPostConstruct] 10 | private void Initialize(out IService service) 11 | { 12 | service = new Service(); 13 | } 14 | 15 | private class Service : IService { } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithKeyedServiceTest.ExamplesGeneratedCode#BaseClass.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: BaseClass.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class BaseClass 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public BaseClass( 13 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("base")] global::IService service 14 | ) 15 | { 16 | this._service = service; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithKeyedServiceTest.ExamplesGeneratedCode#PostCtorWithKeyedServiceTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithKeyedServiceTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithKeyedServiceTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithKeyedServiceTest( 13 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("base")] global::IService service, 14 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("field")] global::IService service0, 15 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("postconstruct")] global::IService postConstructService 16 | ) : base(service) 17 | { 18 | this._service = service0; 19 | Initialize(postConstructService); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithKeyedServiceTest.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | 3 | [AutoCtor.AutoConstruct] 4 | public partial class BaseClass 5 | { 6 | [AutoCtor.AutoKeyedService("base")] 7 | private readonly IService _service; 8 | } 9 | 10 | [AutoCtor.AutoConstruct] 11 | public partial class PostCtorWithKeyedServiceTest : BaseClass 12 | { 13 | [AutoCtor.AutoKeyedService("field")] 14 | private readonly IService _service; 15 | 16 | [AutoCtor.AutoPostConstruct] 17 | private void Initialize([AutoCtor.AutoKeyedService("postconstruct")] IService postConstructService) 18 | { 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithMSKeyedServiceTest.ExamplesGeneratedCode#PostCtorWithMSKeyedServiceTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithMSKeyedServiceTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithMSKeyedServiceTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithMSKeyedServiceTest( 13 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("field")] global::IService service, 14 | [global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("postconstruct")] global::IService postConstructService 15 | ) 16 | { 17 | this._service = service; 18 | Initialize(postConstructService); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithMSKeyedServiceTest.cs: -------------------------------------------------------------------------------- 1 | public interface IService { } 2 | 3 | [AutoCtor.AutoConstruct] 4 | public partial class PostCtorWithMSKeyedServiceTest 5 | { 6 | [AutoCtor.AutoKeyedService("field")] 7 | private readonly IService _service; 8 | 9 | [AutoCtor.AutoPostConstruct] 10 | private void Initialize( 11 | [Microsoft.Extensions.DependencyInjection.FromKeyedServices("postconstruct")] 12 | IService postConstructService) 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithOptionalArgumentsTest.ExamplesGeneratedCode#PostCtorWithOptionalArgumentsTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithOptionalArgumentsTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithOptionalArgumentsTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithOptionalArgumentsTest(global::IServiceA serviceA) 13 | { 14 | this._serviceA = serviceA; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithOptionalArgumentsTest.ExamplesGeneratedCode.verified.txt: -------------------------------------------------------------------------------- 1 | { 2 | Diagnostics: [ 3 | { 4 | Location: /* 5 | [AutoCtor.AutoPostConstruct] 6 | private void Initialize(IServiceB? serviceB = null) 7 | ^^^^^^^^ 8 | { 9 | */ 10 | : (9,39)-(9,47), 11 | Message: The parameter 'serviceB' must not be optional, 12 | Severity: Warning, 13 | WarningLevel: 1, 14 | Descriptor: { 15 | Id: ACTR003, 16 | Title: Post construct method must not have any optional arguments, 17 | MessageFormat: The parameter '{0}' must not be optional, 18 | Category: AutoCtor, 19 | DefaultSeverity: Warning, 20 | IsEnabledByDefault: true 21 | } 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithOptionalArgumentsTest.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | 4 | [AutoCtor.AutoConstruct] 5 | public partial class PostCtorWithOptionalArgumentsTest 6 | { 7 | private readonly IServiceA _serviceA; 8 | 9 | [AutoCtor.AutoPostConstruct] 10 | private void Initialize(IServiceB? serviceB = null) 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithOutArgumentTest.ExamplesGeneratedCode#PostCtorWithOutArgumentTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithOutArgumentTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithOutArgumentTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithOutArgumentTest( 13 | global::IServiceA serviceA, 14 | global::IServiceFactory serviceFactory 15 | ) 16 | { 17 | this._serviceA = serviceA; 18 | Initialize(serviceFactory, out this._serviceB); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithOutArgumentTest.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | public interface IServiceFactory { IServiceB CreateService(); } 4 | 5 | [AutoCtor.AutoConstruct] 6 | public partial class PostCtorWithOutArgumentTest 7 | { 8 | private readonly IServiceA _serviceA; 9 | private readonly IServiceB _serviceB; 10 | 11 | [AutoCtor.AutoPostConstruct] 12 | private void Initialize(IServiceFactory serviceFactory, out IServiceB serviceB) 13 | { 14 | serviceB = serviceFactory.CreateService(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithRefArgumentTest.ExamplesGeneratedCode#PostCtorWithRefArgumentTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithRefArgumentTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithRefArgumentTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithRefArgumentTest( 13 | global::IServiceA serviceA, 14 | global::IServiceFactory serviceFactory 15 | ) 16 | { 17 | this._serviceA = serviceA; 18 | Initialize(serviceFactory, ref this._serviceB); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithRefArgumentTest.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | public interface IServiceFactory { IServiceB CreateService(); } 4 | 5 | [AutoCtor.AutoConstruct] 6 | public partial class PostCtorWithRefArgumentTest 7 | { 8 | private readonly IServiceA _serviceA; 9 | private readonly IServiceB _serviceB; 10 | 11 | [AutoCtor.AutoPostConstruct] 12 | private void Initialize(IServiceFactory serviceFactory, ref IServiceB serviceB) 13 | { 14 | serviceB = serviceFactory.CreateService(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithRefReadonlyArgumentTest.ExamplesGeneratedCode#PostCtorWithRefReadonlyArgumentTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PostCtorWithRefReadonlyArgumentTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PostCtorWithRefReadonlyArgumentTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PostCtorWithRefReadonlyArgumentTest( 13 | global::IServiceA serviceA, 14 | global::IServiceB serviceB, 15 | global::IServiceFactory serviceFactory 16 | ) 17 | { 18 | this._serviceA = serviceA; 19 | this._serviceB = serviceB; 20 | Initialize(serviceFactory, in serviceB); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/PostCtorWithRefReadonlyArgumentTest.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | public interface IServiceFactory { IServiceB CreateService(); } 4 | 5 | [AutoCtor.AutoConstruct] 6 | public partial class PostCtorWithRefReadonlyArgumentTest 7 | { 8 | private readonly IServiceA _serviceA; 9 | private readonly IServiceB _serviceB; 10 | 11 | [AutoCtor.AutoPostConstruct] 12 | private void Initialize(IServiceFactory serviceFactory, ref readonly IServiceB serviceB) 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/RecordTest.ExamplesGeneratedCode#RecordStructTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: RecordStructTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial record struct RecordStructTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public RecordStructTest(int item) 13 | { 14 | this._item = item; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/RecordTest.ExamplesGeneratedCode#RecordTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: RecordTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial record RecordTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public RecordTest(int item) 13 | { 14 | this._item = item; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/RecordTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | [AutoConstruct] 4 | public partial record RecordTest 5 | { 6 | private readonly int _item; 7 | } 8 | 9 | [AutoConstruct] 10 | public partial record struct RecordStructTest 11 | { 12 | private readonly int _item; 13 | } 14 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/SealedTest.ExamplesGeneratedCode#SealedTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: SealedTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class SealedTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public SealedTest(int item) 13 | { 14 | this._item = item; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/SealedTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | [AutoConstruct] 4 | public sealed partial class SealedTest 5 | { 6 | private readonly int _item; 7 | } 8 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/StructTest.ExamplesGeneratedCode#StructTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: StructTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial struct StructTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public StructTest(int item) 13 | { 14 | this._item = item; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/StructTest.cs: -------------------------------------------------------------------------------- 1 | using AutoCtor; 2 | 3 | [AutoConstruct] 4 | public partial struct StructTest 5 | { 6 | private readonly int _item; 7 | } 8 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/UniqueNameTest.ExamplesGeneratedCode#UniqueNameTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: UniqueNameTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class UniqueNameTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public UniqueNameTest( 13 | global::IServiceC serviceC, 14 | global::IServiceA serviceA, 15 | global::IServiceB serviceB 16 | ) : base(serviceC) 17 | { 18 | this._serviceA = serviceA; 19 | Initialize(serviceB); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Examples/UniqueNameTest.cs: -------------------------------------------------------------------------------- 1 | public interface IServiceA { } 2 | public interface IServiceB { } 3 | public interface IServiceC { } 4 | 5 | [AutoCtor.AutoConstruct] 6 | public partial class UniqueNameTest : BaseClass 7 | { 8 | private readonly IServiceA _serviceA; 9 | 10 | [AutoCtor.AutoPostConstruct] 11 | private void Initialize(IServiceB serviceB) 12 | { 13 | } 14 | } 15 | 16 | public abstract class BaseClass 17 | { 18 | public BaseClass(IServiceC serviceC) 19 | { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/GeneratedAttributeTests.AttributeGeneratedCode#AutoConstructAttribute.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: AutoConstructAttribute.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | #if AUTOCTOR_EMBED_ATTRIBUTES 9 | namespace AutoCtor 10 | { 11 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 12 | internal enum GuardSetting 13 | { 14 | Default, 15 | Disabled, 16 | Enabled 17 | } 18 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 19 | [global::System.AttributeUsage(global::System.AttributeTargets.Class | global::System.AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] 20 | internal sealed class AutoConstructAttribute : global::System.Attribute 21 | { 22 | public AutoConstructAttribute(GuardSetting guard = GuardSetting.Default) 23 | { 24 | } 25 | } 26 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 27 | [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false, Inherited = false)] 28 | internal sealed class AutoPostConstructAttribute : global::System.Attribute 29 | { 30 | } 31 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 32 | [global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false, Inherited = false)] 33 | internal sealed class AutoConstructIgnoreAttribute : global::System.Attribute 34 | { 35 | } 36 | } 37 | #endif 38 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/GeneratedAttributeTests.cs: -------------------------------------------------------------------------------- 1 | namespace AutoCtor.Tests; 2 | 3 | public class GeneratedAttributeTests 4 | { 5 | [Fact] 6 | public async Task AttributeGeneratedCode() 7 | { 8 | var builder = new CompilationBuilder() 9 | .AddNetCoreReference() 10 | .WithPreprocessorSymbols(["AUTOCTOR_EMBED_ATTRIBUTES"]); 11 | var compilation = await builder.Build(nameof(GeneratedAttributeTests)); 12 | var driver = new GeneratorDriverBuilder() 13 | .AddGenerator(new AttributeSourceGenerator()) 14 | .Build(builder.ParseOptions) 15 | .RunGenerators(compilation, TestContext.Current.CancellationToken); 16 | 17 | await Verify(driver); 18 | } 19 | 20 | [Fact] 21 | public async Task AttributeCompilesProperly() 22 | { 23 | var builder = new CompilationBuilder() 24 | .AddNetCoreReference() 25 | .WithPreprocessorSymbols(["AUTOCTOR_EMBED_ATTRIBUTES"]); 26 | var compilation = await builder.Build(nameof(GeneratedAttributeTests)); 27 | var driver = new GeneratorDriverBuilder() 28 | .AddGenerator(new AttributeSourceGenerator()) 29 | .Build(builder.ParseOptions) 30 | .RunGeneratorsAndUpdateCompilation( 31 | compilation, 32 | out var outputCompilation, 33 | out var diagnostics, 34 | TestContext.Current.CancellationToken); 35 | 36 | Assert.Empty(diagnostics); 37 | Assert.Empty(outputCompilation.GetDiagnostics(TestContext.Current.CancellationToken)); 38 | } 39 | 40 | [Fact] 41 | public async Task PreserveAttributesTest() 42 | { 43 | var builder = new CompilationBuilder() 44 | .AddNetCoreReference() 45 | .AddCode("[AutoCtor.AutoConstruct] public partial class Test { }") 46 | .WithPreprocessorSymbols(["AUTOCTOR_EMBED_ATTRIBUTES", "AUTOCTOR_USAGES"]); 47 | var compilation = await builder.Build(nameof(GeneratedAttributeTests)); 48 | 49 | var driver = new GeneratorDriverBuilder() 50 | .AddGenerator(new AttributeSourceGenerator()) 51 | .AddGenerator(new AutoConstructSourceGenerator()) 52 | .Build(builder.ParseOptions) 53 | .RunGeneratorsAndUpdateCompilation( 54 | compilation, 55 | out var outputCompilation, 56 | out var diagnostics, 57 | TestContext.Current.CancellationToken); 58 | 59 | Assert.Empty(diagnostics); 60 | Assert.Empty(outputCompilation.GetDiagnostics(TestContext.Current.CancellationToken)); 61 | } 62 | 63 | [Fact] 64 | public async Task EnsureGeneratedAttributesAreNotExternallyVisible() 65 | { 66 | // Issue 312 67 | var compileBuilder = new CompilationBuilder() 68 | .AddNetCoreReference() 69 | .WithPreprocessorSymbols(["AUTOCTOR_EMBED_ATTRIBUTES"]); 70 | 71 | var genDriver = new GeneratorDriverBuilder() 72 | .AddGenerator(new AttributeSourceGenerator()) 73 | .Build(compileBuilder.ParseOptions); 74 | 75 | var projectA = await compileBuilder 76 | .Build("ProjectA"); 77 | 78 | genDriver = genDriver.RunGeneratorsAndUpdateCompilation(projectA, out var genProjectA, out _, TestContext.Current.CancellationToken); 79 | 80 | var projectB = await compileBuilder 81 | .AddCompilationReference(genProjectA) 82 | .Build("ProjectB"); 83 | 84 | genDriver.RunGeneratorsAndUpdateCompilation( 85 | projectB, 86 | out var outputCompilation, 87 | out var diagnostics, 88 | TestContext.Current.CancellationToken); 89 | 90 | Assert.Empty(diagnostics); 91 | Assert.Empty(outputCompilation.GetDiagnostics(TestContext.Current.CancellationToken)); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/GuardExamples/DisabledGuard.ExamplesGeneratedCode#DisabledGuard.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: DisabledGuard.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class DisabledGuard 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public DisabledGuard(string value) 13 | { 14 | this._value = value; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/GuardExamples/DisabledGuard.cs: -------------------------------------------------------------------------------- 1 | [AutoCtor.AutoConstruct(guard: AutoCtor.GuardSetting.Disabled)] 2 | public partial class DisabledGuard 3 | { 4 | private readonly string _value; 5 | } 6 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/GuardExamples/Guard.ExamplesGeneratedCode#Guard.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Guard.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class Guard 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public Guard(string value) 13 | { 14 | this._value = value ?? throw new global::System.ArgumentNullException("value"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/GuardExamples/Guard.cs: -------------------------------------------------------------------------------- 1 | [AutoCtor.AutoConstruct] 2 | public partial class Guard 3 | { 4 | private readonly string _value; 5 | } 6 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/GuardExamples/NullableTypes.ExamplesGeneratedCode#NullableTypes.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: NullableTypes.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class NullableTypes 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public NullableTypes(global::Service structService) 13 | { 14 | this._structService = structService; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/GuardExamples/NullableTypes.cs: -------------------------------------------------------------------------------- 1 | public struct Service 2 | { 3 | } 4 | 5 | [AutoCtor.AutoConstruct] 6 | public partial class NullableTypes 7 | { 8 | private readonly Service _structService; 9 | } 10 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Issue73.VerifyGeneratedCode#B.TheClass.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: B.TheClass.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | namespace B 9 | { 10 | partial class TheClass 11 | { 12 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 13 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 14 | public TheClass(global::A.Interface i) : base(i) 15 | { 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Issue73.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | 4 | namespace AutoCtor.Tests; 5 | 6 | public class Issue73 7 | { 8 | [Fact] 9 | public async Task VerifyGeneratedCode() 10 | { 11 | var common = Common(); 12 | var compilation = await Compile(common); 13 | var driver = new GeneratorDriverBuilder() 14 | .AddGenerator(new AutoConstructSourceGenerator()) 15 | .Build(common.ParseOptions) 16 | .RunGenerators(compilation, TestContext.Current.CancellationToken); 17 | 18 | await Verify(driver); 19 | } 20 | 21 | [Fact] 22 | public async Task CodeCompilesWithoutErrors() 23 | { 24 | string[] ignoredWarnings = ["CS0414"]; // Ignore unused fields 25 | 26 | var common = Common(); 27 | var compilation = await Compile(common); 28 | new GeneratorDriverBuilder() 29 | .AddGenerator(new AutoConstructSourceGenerator()) 30 | .Build(common.ParseOptions) 31 | .RunGeneratorsAndUpdateCompilation( 32 | compilation, 33 | out var outputCompilation, 34 | out var diagnostics, 35 | TestContext.Current.CancellationToken); 36 | 37 | Assert.Empty(diagnostics); 38 | Assert.Empty(outputCompilation.GetDiagnostics(TestContext.Current.CancellationToken) 39 | .Where(d => !ignoredWarnings.Contains(d.Id))); 40 | } 41 | 42 | private static CompilationBuilder Common() 43 | { 44 | return new CompilationBuilder() 45 | .AddNetCoreReference() 46 | .AddAssemblyReference(); 47 | } 48 | 49 | private static async Task Compile(CompilationBuilder common) 50 | { 51 | var projectACode = @" 52 | namespace A 53 | { 54 | public interface Interface{} 55 | } 56 | "; 57 | var projectBCode = @" 58 | using AutoCtor; 59 | using A; 60 | namespace B 61 | { 62 | public abstract class BaseClass 63 | { 64 | private readonly Interface _interface; 65 | public BaseClass(Interface i) => _interface = i; 66 | } 67 | [AutoConstruct] 68 | public sealed partial class TheClass : BaseClass{} 69 | } 70 | "; 71 | var projectA = await common 72 | .AddCode(projectACode) 73 | .Build("ProjectA"); 74 | 75 | var projectB = await common 76 | .AddCompilationReference(projectA) 77 | .AddCode(projectBCode) 78 | .Build("ProjectB"); 79 | 80 | return projectB; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/LangExamples/PropertiesTest.cs: -------------------------------------------------------------------------------- 1 | [AutoCtor.AutoConstruct] 2 | public partial class PropertiesTest 3 | { 4 | // Included 5 | public string GetProperty { get; } 6 | protected string ProtectedProperty { get; } 7 | public string InitProperty { get; init; } 8 | 9 | #if ROSLYN_4_4 10 | public required string RequiredProperty { get; set; } 11 | #endif 12 | 13 | // Ignored 14 | public string InitializerProperty { get; } = "Constant"; 15 | public string GetSetProperty { get; set; } 16 | public string FixedProperty => "Constant"; 17 | public string RedirectedProperty => InitializerProperty; 18 | 19 | [AutoCtor.AutoConstructIgnore] 20 | public string IgnoredProperty { get; } 21 | 22 | public string FieldExpressionBodyProperty => field ??= "Constant"; 23 | 24 | public string FieldProperty 25 | { 26 | get 27 | { 28 | if (string.IsNullOrEmpty(field)) 29 | field = "Constant"; 30 | return field; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/LangExamples/Verified_3_11/PropertiesTest.ExamplesGeneratedCode#PropertiesTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PropertiesTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PropertiesTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PropertiesTest( 13 | string getProperty, 14 | string protectedProperty, 15 | string initProperty 16 | ) 17 | { 18 | this.GetProperty = getProperty; 19 | this.ProtectedProperty = protectedProperty; 20 | this.InitProperty = initProperty; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/LangExamples/Verified_4_0/PropertiesTest.ExamplesGeneratedCode#PropertiesTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PropertiesTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PropertiesTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PropertiesTest( 13 | string getProperty, 14 | string protectedProperty, 15 | string initProperty 16 | ) 17 | { 18 | this.GetProperty = getProperty; 19 | this.ProtectedProperty = protectedProperty; 20 | this.InitProperty = initProperty; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/LangExamples/Verified_4_4/PropertiesTest.ExamplesGeneratedCode#PropertiesTest.g.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: PropertiesTest.g.cs 2 | //------------------------------------------------------------------------------ 3 | // 4 | // This code was generated by https://github.com/distantcam/AutoCtor 5 | // 6 | //------------------------------------------------------------------------------ 7 | 8 | partial class PropertiesTest 9 | { 10 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute] 11 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 12 | public PropertiesTest( 13 | string getProperty, 14 | string protectedProperty, 15 | string initProperty, 16 | string requiredProperty 17 | ) 18 | { 19 | this.GetProperty = getProperty; 20 | this.ProtectedProperty = protectedProperty; 21 | this.InitProperty = initProperty; 22 | this.RequiredProperty = requiredProperty; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Utilities/CodeFileTheoryData.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using Microsoft.CodeAnalysis; 3 | using Xunit.Sdk; 4 | 5 | public record CodeFileTheoryData : IXunitSerializable 6 | { 7 | public required string Name { get; set; } 8 | public required string[] Codes { get; set; } 9 | public required string VerifiedDirectory { get; set; } 10 | 11 | public Dictionary Options { get; set; } = []; 12 | public bool LangPreview { get; set; } 13 | public string[] IgnoredCompileDiagnostics { get; set; } = []; 14 | 15 | [SetsRequiredMembers] 16 | public CodeFileTheoryData(string file, params string[] codes) 17 | { 18 | Name = Path.GetFileNameWithoutExtension(file); 19 | Codes = [File.ReadAllText(file), .. codes]; 20 | VerifiedDirectory = Path.GetDirectoryName(file) ?? ""; 21 | } 22 | 23 | public CodeFileTheoryData() { } 24 | 25 | public void Deserialize(IXunitSerializationInfo info) 26 | { 27 | Name = info.GetValue(nameof(Name)) 28 | ?? throw new Exception($"Missing {nameof(Name)} in theory serialization"); 29 | Codes = info.GetValue(nameof(Codes)) 30 | ?? throw new Exception($"Missing {nameof(Codes)} in theory serialization"); 31 | VerifiedDirectory = info.GetValue(nameof(VerifiedDirectory)) 32 | ?? throw new Exception($"Missing {nameof(VerifiedDirectory)} in theory serialization"); 33 | Options = info.GetValue(nameof(Options))? 34 | .Select(o => o.Split('|')) 35 | .ToDictionary(o => o[0], o => o[1]) 36 | ?? throw new Exception($"Missing {nameof(Options)} in theory serialization"); 37 | LangPreview = info.GetValue(nameof(LangPreview)); 38 | IgnoredCompileDiagnostics = info.GetValue(nameof(IgnoredCompileDiagnostics)) 39 | ?? throw new Exception($"Missing {nameof(IgnoredCompileDiagnostics)} in theory serialization"); 40 | } 41 | 42 | public void Serialize(IXunitSerializationInfo info) 43 | { 44 | info.AddValue(nameof(Name), Name); 45 | info.AddValue(nameof(Codes), Codes); 46 | info.AddValue(nameof(VerifiedDirectory), VerifiedDirectory); 47 | info.AddValue(nameof(Options), Options.Select(o => $"{o.Key}|{o.Value}").ToArray()); 48 | info.AddValue(nameof(LangPreview), LangPreview); 49 | info.AddValue(nameof(IgnoredCompileDiagnostics), IgnoredCompileDiagnostics); 50 | } 51 | 52 | public override string ToString() => Name + ".cs"; 53 | } 54 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Utilities/CompilationBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp; 4 | using Microsoft.CodeAnalysis.Testing; 5 | 6 | internal class CompilationBuilder 7 | { 8 | private ImmutableArray _nugetReferences; 9 | private ImmutableArray _references; 10 | private ImmutableArray _codes; 11 | 12 | private CSharpParseOptions _parseOptions; 13 | private CSharpCompilationOptions _compilationOptions; 14 | 15 | private string _defaultTargetFramework = "net9.0"; 16 | 17 | public CSharpParseOptions ParseOptions => _parseOptions; 18 | 19 | public CompilationBuilder() 20 | { 21 | _nugetReferences = []; 22 | _references = []; 23 | _codes = []; 24 | 25 | _parseOptions = CSharpParseOptions.Default; 26 | _compilationOptions = new(OutputKind.DynamicallyLinkedLibrary); 27 | } 28 | 29 | private CompilationBuilder(CompilationBuilder other) 30 | { 31 | _nugetReferences = other._nugetReferences; 32 | _references = other._references; 33 | _codes = other._codes; 34 | 35 | _parseOptions = other._parseOptions; 36 | _compilationOptions = other._compilationOptions; 37 | } 38 | 39 | public async Task Build(string assemblyName) 40 | { 41 | var refTasks = _nugetReferences.Select(r => r.ResolveAsync(null, CancellationToken.None)); 42 | await Task.WhenAll(refTasks); 43 | var nugetReferences = refTasks.SelectMany(t => t.Result); 44 | 45 | return CSharpCompilation.Create(assemblyName) 46 | .AddReferences(nugetReferences) 47 | .AddReferences(_references) 48 | .AddSyntaxTrees(_codes.Select(c => CSharpSyntaxTree.ParseText(c, _parseOptions))) 49 | .WithOptions(_compilationOptions); 50 | } 51 | 52 | public CompilationBuilder AddNugetReference(string id, string version, string targetFramework = "", string path = "") 53 | { 54 | var framework = string.IsNullOrEmpty(targetFramework) ? _defaultTargetFramework : targetFramework; 55 | 56 | return new(this) 57 | { 58 | _nugetReferences = _nugetReferences.Add(new( 59 | framework, 60 | new(id, version), 61 | Path.Join(string.IsNullOrEmpty(path) ? "lib" : path, framework) 62 | )) 63 | }; 64 | } 65 | 66 | public CompilationBuilder AddNetCoreReference(string targetFramework = "", string version = "9.0.4") 67 | => AddNugetReference( 68 | "Microsoft.NETCore.App.Ref", 69 | version, 70 | targetFramework, 71 | "ref"); 72 | 73 | public CompilationBuilder AddAssemblyReference() 74 | { 75 | return new(this) 76 | { 77 | _references = _references.Add(MetadataReference.CreateFromFile(typeof(T).Assembly.Location)) 78 | }; 79 | } 80 | 81 | public CompilationBuilder AddCompilationReference(Compilation compilation) 82 | { 83 | return new(this) 84 | { 85 | _references = _references.Add(compilation.ToMetadataReference()) 86 | }; 87 | } 88 | 89 | public CompilationBuilder AddCode(string code) 90 | { 91 | return new(this) 92 | { 93 | _codes = _codes.Add(code) 94 | }; 95 | } 96 | 97 | public CompilationBuilder AddCodes(IEnumerable codes) 98 | { 99 | return new(this) 100 | { 101 | _codes = _codes.AddRange(codes) 102 | }; 103 | } 104 | 105 | public CompilationBuilder WithNullableContextOptions(NullableContextOptions options) 106 | { 107 | return new(this) 108 | { 109 | _compilationOptions = _compilationOptions.WithNullableContextOptions(options) 110 | }; 111 | } 112 | 113 | public CompilationBuilder WithPreprocessorSymbols(IEnumerable? preprocessorSymbols) 114 | { 115 | return new(this) 116 | { 117 | _parseOptions = _parseOptions.WithPreprocessorSymbols(preprocessorSymbols) 118 | }; 119 | } 120 | 121 | public CompilationBuilder WithLanguageVersion(LanguageVersion langVersion) 122 | { 123 | return new(this) 124 | { 125 | _parseOptions = _parseOptions.WithLanguageVersion(langVersion) 126 | }; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Utilities/ExampleTestsHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp; 4 | 5 | internal static class ExampleTestsHelper 6 | { 7 | public static readonly IEnumerable PreprocessorSymbols = [ 8 | #if ROSLYN_3 9 | "ROSLYN_3", 10 | #endif 11 | #if ROSLYN_3_11 12 | "ROSLYN_3_11", 13 | #endif 14 | #if ROSLYN_4 15 | "ROSLYN_4", 16 | #endif 17 | #if ROSLYN_4_0 18 | "ROSLYN_4_0", 19 | #endif 20 | #if ROSLYN_4_4 21 | "ROSLYN_4_4", 22 | #endif 23 | ]; 24 | 25 | public static CompilationBuilder CreateCompilation(CodeFileTheoryData theoryData) 26 | { 27 | var builder = new CompilationBuilder() 28 | .AddNetCoreReference() 29 | .AddAssemblyReference() 30 | .WithNullableContextOptions(NullableContextOptions.Enable) 31 | .WithPreprocessorSymbols(PreprocessorSymbols) 32 | .AddCodes(theoryData.Codes); 33 | 34 | if (theoryData.LangPreview) 35 | { 36 | builder = builder.WithLanguageVersion(LanguageVersion.Preview); 37 | } 38 | 39 | return builder; 40 | } 41 | 42 | #if ROSLYN_4 43 | public static void AssertRunsEqual( 44 | GeneratorDriverRunResult runResult1, 45 | GeneratorDriverRunResult runResult2, 46 | IEnumerable trackingNames) 47 | { 48 | // We're given all the tracking names, but not all the 49 | // stages will necessarily execute, so extract all the 50 | // output steps, and filter to ones we know about 51 | var trackedSteps1 = GetTrackedSteps(runResult1, trackingNames); 52 | var trackedSteps2 = GetTrackedSteps(runResult2, trackingNames); 53 | 54 | // Both runs should have the same tracked steps 55 | Assert.NotEmpty(trackedSteps1); 56 | Assert.Equal(trackedSteps1.Count, trackedSteps2.Count); 57 | Assert.Equal(trackedSteps1.Keys, trackedSteps2.Keys); 58 | 59 | // Get the IncrementalGeneratorRunStep collection for each run 60 | foreach (var (trackingName, runSteps1) in trackedSteps1) 61 | { 62 | // Assert that both runs produced the same outputs 63 | var runSteps2 = trackedSteps2[trackingName]; 64 | AssertStepsEqual(runSteps1, runSteps2, trackingName); 65 | } 66 | 67 | return; 68 | 69 | // Local function that extracts the tracked steps 70 | static Dictionary> GetTrackedSteps( 71 | GeneratorDriverRunResult runResult, IEnumerable trackingNames) 72 | => runResult 73 | .Results[0] // We're only running a single generator, so this is safe 74 | .TrackedSteps // Get the pipeline outputs 75 | .Where(step => trackingNames.Contains(step.Key)) // filter to known steps 76 | .ToDictionary(x => x.Key, x => x.Value); // Convert to a dictionary 77 | } 78 | 79 | private static void AssertStepsEqual( 80 | ImmutableArray runSteps1, 81 | ImmutableArray runSteps2, 82 | string stepName) 83 | { 84 | Assert.Equal(runSteps1.Length, runSteps2.Length); 85 | 86 | for (var i = 0; i < runSteps1.Length; i++) 87 | { 88 | var runStep1 = runSteps1[i]; 89 | var runStep2 = runSteps2[i]; 90 | 91 | // The outputs should be equal between different runs 92 | var outputs1 = runStep1.Outputs.Select(x => x.Value); 93 | var outputs2 = runStep2.Outputs.Select(x => x.Value); 94 | 95 | WithMessage(() => Assert.Equal(outputs1, outputs2), 96 | $"because step {stepName} should produce cacheable outputs"); 97 | 98 | // Therefore, on the second run the results should always be cached or unchanged! 99 | // - Unchanged is when the _input_ has changed, but the output hasn't 100 | // - Cached is when the the input has not changed, so the cached output is used 101 | IEnumerable acceptableReasons = 102 | [IncrementalStepRunReason.Cached, IncrementalStepRunReason.Unchanged]; 103 | foreach (var step in runStep2.Outputs) 104 | { 105 | Assert.Contains(step.Reason, acceptableReasons); 106 | } 107 | } 108 | } 109 | 110 | private static void WithMessage(Action action, string message) 111 | { 112 | try 113 | { 114 | action(); 115 | } 116 | catch (Exception ex) 117 | { 118 | throw new AssertMessageException(message, ex); 119 | } 120 | } 121 | 122 | [Serializable] 123 | public class AssertMessageException(string message, Exception inner) : Exception(message, inner); 124 | #endif 125 | } 126 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Utilities/GeneratorDriverBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using System.Diagnostics.CodeAnalysis; 3 | using Microsoft.CodeAnalysis; 4 | using Microsoft.CodeAnalysis.CSharp; 5 | using Microsoft.CodeAnalysis.Diagnostics; 6 | 7 | internal class GeneratorDriverBuilder 8 | { 9 | private ImmutableArray _generators; 10 | private ImmutableDictionary _analyzerOptions; 11 | 12 | public GeneratorDriverBuilder() 13 | { 14 | _generators = []; 15 | _analyzerOptions = ImmutableDictionary.Create(); 16 | } 17 | 18 | private GeneratorDriverBuilder(GeneratorDriverBuilder other) 19 | { 20 | _generators = other._generators; 21 | _analyzerOptions = other._analyzerOptions; 22 | } 23 | 24 | public GeneratorDriverBuilder AddGenerator(ISourceGenerator generator) 25 | { 26 | return new(this) 27 | { 28 | _generators = _generators.Add(generator) 29 | }; 30 | } 31 | 32 | public GeneratorDriverBuilder AddGenerator(IIncrementalGenerator generator) 33 | { 34 | return new(this) 35 | { 36 | _generators = _generators.Add(generator.AsSourceGenerator()) 37 | }; 38 | } 39 | 40 | public GeneratorDriverBuilder WithAnalyzerOptions(IDictionary analyzerOptions) 41 | { 42 | return new(this) 43 | { 44 | _analyzerOptions = analyzerOptions.ToImmutableDictionary() 45 | }; 46 | } 47 | 48 | public GeneratorDriver Build(CSharpParseOptions parseOptions) 49 | { 50 | #if ROSLYN_3 51 | return CSharpGeneratorDriver.Create(_generators, 52 | parseOptions: parseOptions, 53 | optionsProvider: new TestAnalyzerConfigOptionsProvider(_analyzerOptions) 54 | ); 55 | #elif ROSLYN_4_0 56 | return CSharpGeneratorDriver.Create(_generators, 57 | parseOptions: parseOptions, 58 | optionsProvider: new TestAnalyzerConfigOptionsProvider(_analyzerOptions), 59 | driverOptions: new GeneratorDriverOptions( 60 | disabledOutputs: IncrementalGeneratorOutputKind.None 61 | )); 62 | #elif ROSLYN_4_4 63 | return CSharpGeneratorDriver.Create(_generators, 64 | parseOptions: parseOptions, 65 | optionsProvider: new TestAnalyzerConfigOptionsProvider(_analyzerOptions), 66 | driverOptions: new GeneratorDriverOptions( 67 | disabledOutputs: IncrementalGeneratorOutputKind.None, 68 | trackIncrementalGeneratorSteps: true 69 | )); 70 | #endif 71 | } 72 | 73 | private class TestAnalyzerConfigOptionsProvider( 74 | ImmutableDictionary analyzerConfigOptions 75 | ) : AnalyzerConfigOptionsProvider 76 | { 77 | public override AnalyzerConfigOptions GlobalOptions { get; } = new TestAnalyzerConfigOptions(analyzerConfigOptions); 78 | public override AnalyzerConfigOptions GetOptions(SyntaxTree tree) => GlobalOptions; 79 | public override AnalyzerConfigOptions GetOptions(AdditionalText textFile) => GlobalOptions; 80 | } 81 | 82 | private class TestAnalyzerConfigOptions( 83 | ImmutableDictionary analyzerConfigOptions 84 | ) : AnalyzerConfigOptions 85 | { 86 | public override bool TryGetValue(string key, [NotNullWhen(true)] out string? value) 87 | => analyzerConfigOptions.TryGetValue(key, out value); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Utilities/ModuleInitializer.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | public static class ModuleInitializer 4 | { 5 | [ModuleInitializer] 6 | public static void Init() 7 | { 8 | VerifyDiffPlex.Initialize(); 9 | VerifySourceGenerators.Initialize(); 10 | 11 | VerifierSettings.ScrubLinesContaining("Version:", "SHA:", "GeneratedCodeAttribute"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/Utilities/Shim.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.CodeAnalysis; 2 | 3 | internal static class Shim 4 | { 5 | public static ISourceGenerator AsSourceGenerator(this ISourceGenerator generator) => generator; 6 | } 7 | -------------------------------------------------------------------------------- /src/AutoCtor.Tests/VerifyChecksTests.cs: -------------------------------------------------------------------------------- 1 | namespace AutoCtor.Tests; 2 | 3 | public class VerifyChecksTests 4 | { 5 | [Fact] 6 | public Task Run() => 7 | VerifyChecks.Run(); 8 | } 9 | -------------------------------------------------------------------------------- /src/Common.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AutoCtor 5 | AutoCtor 6 | 7 | true 8 | false 9 | true 10 | 11 | 0.0.0 12 | abc 13 | https://github.com/distantcam/AutoCtor 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | latest 5 | true 6 | enable 7 | enable 8 | NU5128 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Directory.Packages.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | false 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "9.0.0", 4 | "rollForward": "latestFeature" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/nugetfiles/AutoCtor.badcompat.targets: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/nugetfiles/AutoCtor.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/nugetfiles/AutoCtor.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <_AutoCtorAnalyzer Include="@(Analyzer)" Condition="'%(Analyzer.NuGetPackageId)' == 'AutoCtor'" /> 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | --------------------------------------------------------------------------------