From 54ada61cbfeb9f9c723faf72427fbce27414a719 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 21 Dec 2025 12:30:57 +0100 Subject: [PATCH 01/67] chore: migration to .NET 8 --- src/ExampleProject/ExampleProject.csproj | 2 +- .../M31.FluentApi.Generator.csproj | 2 +- .../FluentApiComments/FluentApiCommentsProvider.cs | 2 +- .../SourceGenerators/SymbolInfoCreator.cs | 2 +- .../M31.FluentApi.Storybook.csproj | 2 +- .../FluentApiCommentsProviderTests.cs | 8 ++++---- .../Helpers/AnalyzerAndCodeFixVerifier.cs | 8 ++++---- src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj | 10 +++++----- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/ExampleProject/ExampleProject.csproj b/src/ExampleProject/ExampleProject.csproj index ef23671..97ff9de 100644 --- a/src/ExampleProject/ExampleProject.csproj +++ b/src/ExampleProject/ExampleProject.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 enable enable diff --git a/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj b/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj index 7fd666f..906b08a 100644 --- a/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj +++ b/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj @@ -24,7 +24,7 @@ - + all diff --git a/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiComments/FluentApiCommentsProvider.cs b/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiComments/FluentApiCommentsProvider.cs index 45167f6..badbe80 100644 --- a/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiComments/FluentApiCommentsProvider.cs +++ b/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiComments/FluentApiCommentsProvider.cs @@ -164,7 +164,7 @@ private static string GetPadding(SyntaxTriviaList leadingTrivia) { const string fallback = " "; SyntaxTrivia? first = leadingTrivia.FirstOrDefault(); - if (first == null || first.Value.Kind() != SyntaxKind.WhitespaceTrivia) + if (first == null || !first.Value.IsKind(SyntaxKind.WhitespaceTrivia)) { return fallback; } diff --git a/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs b/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs index 0e41c91..a7b3865 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs @@ -228,7 +228,7 @@ private static Comments GetFluentSymbolComments(ISymbol symbol) } } - string comments = string.Join(Environment.NewLine, commentLines); + string comments = string.Join(SourceGenerator.GeneratorConfig.NewLineString, commentLines); return FluentCommentsParser.Parse(comments); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Storybook/M31.FluentApi.Storybook.csproj b/src/M31.FluentApi.Storybook/M31.FluentApi.Storybook.csproj index 33b1729..f086922 100644 --- a/src/M31.FluentApi.Storybook/M31.FluentApi.Storybook.csproj +++ b/src/M31.FluentApi.Storybook/M31.FluentApi.Storybook.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 enable enable false diff --git a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs index af0c6ad..aa17bbd 100644 --- a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs +++ b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs @@ -35,11 +35,11 @@ public async Task CanProvideFluentApiComments( { TestCode = source.Source.SelectSpan(selectedSpan), FixedCode = source.FixedSource!, -#if NET6_0 +#if NET8_0 ReferenceAssemblies = new ReferenceAssemblies( - "net6.0", - new PackageIdentity("Microsoft.NETCore.App.Ref", "6.0.0"), - Path.Combine("ref", "net6.0")), + "net8.0", + new PackageIdentity("Microsoft.NETCore.App.Ref", "8.0.0"), + Path.Combine("ref", "net8.0")), #else throw new NotSupportedException(); #endif diff --git a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs index 2c9db80..e7b8415 100644 --- a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs +++ b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs @@ -57,11 +57,11 @@ internal CodeFixTest( ExpectedDiagnostics.AddRange(expected); -#if NET6_0 +#if NET8_0 ReferenceAssemblies = new ReferenceAssemblies( - "net6.0", - new PackageIdentity("Microsoft.NETCore.App.Ref", "6.0.0"), - Path.Combine("ref", "net6.0")); + "net8.0", + new PackageIdentity("Microsoft.NETCore.App.Ref", "8.0.0"), + Path.Combine("ref", "net8.0")); #else throw new NotSupportedException(); #endif diff --git a/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj b/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj index c8f01bc..d26a147 100644 --- a/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj +++ b/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj @@ -1,19 +1,19 @@ - net6.0 + net8.0 enable false M31.FluentApi.Tests - - + + - + @@ -30,4 +30,4 @@ - + \ No newline at end of file From 30ab43e131ed7470a8582b9e86f45f5d7c2a90d9 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 21 Dec 2025 19:09:21 +0100 Subject: [PATCH 02/67] test: ThreePrivateMembersClass with UnsafeAccessor --- .../CreateStudent.expected.txt | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt index 10e4cc1..e2ad6d2 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt @@ -6,9 +6,9 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; -namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreePrivateMembersClass; +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreePrivateMembersClass;; public class CreateStudent : CreateStudent.ICreateStudent, @@ -17,22 +17,21 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - private static readonly PropertyInfo semesterPropertyInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - dateOfBirthPropertyInfo = typeof(Student).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.Public)!; - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { student = new Student(); } + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Student student, DateOnly value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + public static ICreateStudent InitialStep() { return new CreateStudent(); @@ -41,25 +40,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.dateOfBirthPropertyInfo.SetValue(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } From 4cd92572c4e2d267fa7bcb02507084884b597f1c Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 21 Dec 2025 21:47:42 +0100 Subject: [PATCH 03/67] fix: remove requires reflection --- .../CodeBoardElements/FluentApiSymbolInfo.cs | 6 +--- .../CodeBoardElements/MemberSymbolInfo.cs | 3 +- .../CodeBoardElements/MethodSymbolInfo.cs | 3 +- .../SourceGenerators/SymbolInfoCreator.cs | 33 ------------------- 4 files changed, 3 insertions(+), 42 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs index 1ef3654..38e5045 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs @@ -10,14 +10,12 @@ internal FluentApiSymbolInfo( string name, string declaringClassNameWithTypeParameters, Accessibility accessibility, - bool requiresReflection, Comments comments) { Name = name; NameInCamelCase = Name.TrimStart('_').FirstCharToLower(); DeclaringClassNameWithTypeParameters = declaringClassNameWithTypeParameters; Accessibility = accessibility; - RequiresReflection = requiresReflection; Comments = comments; } @@ -25,7 +23,6 @@ internal FluentApiSymbolInfo( internal string NameInCamelCase { get; } internal string DeclaringClassNameWithTypeParameters { get; } internal Accessibility Accessibility { get; } - internal bool RequiresReflection { get; } internal Comments Comments { get; } protected bool Equals(FluentApiSymbolInfo other) @@ -33,7 +30,6 @@ protected bool Equals(FluentApiSymbolInfo other) return Name == other.Name && DeclaringClassNameWithTypeParameters == other.DeclaringClassNameWithTypeParameters && Accessibility == other.Accessibility && - RequiresReflection == other.RequiresReflection && Comments.Equals(other.Comments); } @@ -48,6 +44,6 @@ public override bool Equals(object? obj) public override int GetHashCode() { return new HashCode() - .Add(Name, DeclaringClassNameWithTypeParameters, Accessibility, RequiresReflection, Comments); + .Add(Name, DeclaringClassNameWithTypeParameters, Accessibility, Comments); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs index cd19d0e..509e556 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs @@ -12,13 +12,12 @@ internal MemberSymbolInfo( string type, string declaringClassNameWithTypeParameters, Accessibility accessibility, - bool requiresReflection, string typeForCodeGeneration, bool isNullable, bool isProperty, CollectionType? collectionType, Comments comments) - : base(name, declaringClassNameWithTypeParameters, accessibility, requiresReflection, comments) + : base(name, declaringClassNameWithTypeParameters, accessibility, comments) { Type = type; TypeForCodeGeneration = typeForCodeGeneration; diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs index fd10609..2f664bf 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs @@ -11,12 +11,11 @@ internal MethodSymbolInfo( string name, string declaringClassNameWithTypeParameters, Accessibility accessibility, - bool requiresReflection, GenericInfo? genericInfo, IReadOnlyCollection parameterInfos, string returnType, Comments comments) - : base(name, declaringClassNameWithTypeParameters, accessibility, requiresReflection, comments) + : base(name, declaringClassNameWithTypeParameters, accessibility, comments) { GenericInfo = genericInfo; ParameterInfos = parameterInfos; diff --git a/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs b/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs index a7b3865..5ca4395 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs @@ -2,7 +2,6 @@ using M31.FluentApi.Generator.CodeBuilding; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements.FluentApiComments; -using M31.FluentApi.Generator.Commons; using M31.FluentApi.Generator.SourceGenerators.Collections; using M31.FluentApi.Generator.SourceGenerators.Generics; using Microsoft.CodeAnalysis; @@ -38,7 +37,6 @@ private static MemberSymbolInfo CreateMemberSymbolInfo( fieldSymbol.Type.ToString(), declaringClassNameWithTypeParameters, fieldSymbol.DeclaredAccessibility, - RequiresReflection(fieldSymbol), CodeTypeExtractor.GetTypeForCodeGeneration(fieldSymbol.Type), fieldSymbol.NullableAnnotation == NullableAnnotation.Annotated, false, @@ -55,7 +53,6 @@ private static MemberSymbolInfo CreateMemberSymbolInfo( propertySymbol.Type.ToString(), declaringClassNameWithTypeParameters, propertySymbol.DeclaredAccessibility, - RequiresReflection(propertySymbol), CodeTypeExtractor.GetTypeForCodeGeneration(propertySymbol.Type), propertySymbol.NullableAnnotation == NullableAnnotation.Annotated, true, @@ -80,7 +77,6 @@ private static MethodSymbolInfo CreateMethodSymbolInfo( methodSymbol.Name, declaringClassNameWithTypeParameters, methodSymbol.DeclaredAccessibility, - RequiresReflection(methodSymbol), genericInfo, parameterInfos, CodeTypeExtractor.GetTypeForCodeGeneration(methodSymbol.ReturnType), @@ -92,35 +88,6 @@ private static MethodSymbolInfo CreateMethodSymbolInfo( return methodSymbol.IsGenericMethod ? GenericInfo.Create(methodSymbol.TypeParameters) : null; } - private static bool RequiresReflection(IFieldSymbol fieldSymbol) - { - bool isWritable = !fieldSymbol.IsReadOnly; - return RequiresReflection(fieldSymbol.DeclaredAccessibility, isWritable); - } - - private static bool RequiresReflection(IMethodSymbol methodSymbol) - { - return !methodSymbol.DeclaredAccessibility.IsPublicOrInternal(); - } - - private static bool RequiresReflection(IPropertySymbol propertySymbol) - { - bool isWritable = false; - - if (propertySymbol.SetMethod != null) - { - isWritable = propertySymbol.SetMethod.DeclaredAccessibility.IsPublicOrInternal() && - !propertySymbol.SetMethod.IsInitOnly; - } - - return RequiresReflection(propertySymbol.DeclaredAccessibility, isWritable); - } - - private static bool RequiresReflection(Accessibility declaredAccessibility, bool isWritable) - { - return !declaredAccessibility.IsPublicOrInternal() || !isWritable; - } - private static ParameterSymbolInfo CreateParameterSymbolInfo( IParameterSymbol parameterSymbol, Dictionary typeParameterNameToTypeParameterPosition) From e1974e6a7fcb8786557d9ec939915d49bce08511 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 22 Dec 2025 18:55:57 +0100 Subject: [PATCH 04/67] wip: use unsafe accessor --- .../CodeBuilding/Class.cs | 9 +++ .../CodeBuilding/MethodSignature.cs | 8 ++ .../CodeBoardActors/ConstructorGenerator.cs | 15 ---- .../InnerBodyGeneration/InnerBodyCreator.cs | 8 +- .../InnerBodyForMemberGenerator.cs | 21 +---- .../InnerBodyForMethodGenerator.cs | 80 ++----------------- .../InnerBodyGeneratorBase.cs | 61 +++++++------- .../CodeBoardElements/FluentApiSymbolInfo.cs | 2 + 8 files changed, 63 insertions(+), 141 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeBuilding/Class.cs b/src/M31.FluentApi.Generator/CodeBuilding/Class.cs index 5d6a47d..b1b8de4 100644 --- a/src/M31.FluentApi.Generator/CodeBuilding/Class.cs +++ b/src/M31.FluentApi.Generator/CodeBuilding/Class.cs @@ -4,6 +4,7 @@ internal class Class : ICode { private readonly List fields; private readonly List methods; + private readonly List methodSignatures; private readonly List properties; private readonly List interfaces; private readonly List definitions; @@ -15,6 +16,7 @@ internal Class(string name) Modifiers = new Modifiers(); fields = new List(); methods = new List(); + methodSignatures = new List(); properties = new List(); interfaces = new List(); definitions = new List(); @@ -26,6 +28,7 @@ internal Class(string name) internal Modifiers Modifiers { get; } internal IReadOnlyCollection Fields => fields; internal IReadOnlyCollection Methods => methods; + internal IReadOnlyCollection MethodSignatures => methodSignatures; internal IReadOnlyCollection Properties => properties; internal IReadOnlyCollection Interfaces => interfaces; internal IReadOnlyCollection Definitions => definitions; @@ -55,6 +58,11 @@ internal void AddMethod(Method method) methods.Add(method); } + internal void AddMethodSignature(MethodSignature methodSignature) + { + methodSignatures.Add(methodSignature); + } + internal void AddProperty(Property property) { properties.Add(property); @@ -111,6 +119,7 @@ public CodeBuilder AppendCode(CodeBuilder codeBuilder) .BlankLine() .Append(properties) .BlankLine() + .AppendWithBlankLines(methodSignatures) .AppendWithBlankLines(methods) .AppendWithBlankLines(definitions) .CloseBlock(); diff --git a/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs b/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs index 38249d1..da7e28e 100644 --- a/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs +++ b/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs @@ -15,6 +15,7 @@ private MethodSignature( Generics = new Generics(); Parameters = new Parameters(); Modifiers = new Modifiers(); + Attributes = new List(); } private MethodSignature(MethodSignature methodSignature, bool isSignatureForInterface) @@ -26,6 +27,7 @@ private MethodSignature(MethodSignature methodSignature, bool isSignatureForInte Generics = new Generics(methodSignature.Generics); Parameters = new Parameters(methodSignature.Parameters); Modifiers = new Modifiers(methodSignature.Modifiers); + Attributes = new List(methodSignature.Attributes); } internal static MethodSignature Create( @@ -49,6 +51,7 @@ internal static MethodSignature CreateConstructorSignature(string className) internal Generics Generics { get; } internal Parameters Parameters { get; } internal Modifiers Modifiers { get; } + internal List Attributes { get; } internal bool IsSignatureForMethodBody => !IsSignatureForInterface; internal bool IsExplicitInterfaceImplementation => ExplicitInterfacePrefix != null; @@ -72,6 +75,11 @@ internal void AddModifiers(params string[] modifiers) Modifiers.Add(modifiers); } + internal void AddAttribute(string attribute) + { + Attributes.Add(attribute); + } + internal MethodSignature ToSignatureForInterface() { return new MethodSignature(this, true); diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs index 846a280..c7d4948 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs @@ -10,13 +10,6 @@ public void Modify(CodeBoard codeBoard) string instanceName = codeBoard.Info.ClassInstanceName; string classNameWithTypeParameters = codeBoard.Info.FluentApiClassNameWithTypeParameters; - if (codeBoard.FluentApiInfos.Any(i => i.SymbolInfo.RequiresReflection)) - { - Method staticConstructor = CreateStaticConstructor(codeBoard.Info.BuilderClassName); - codeBoard.StaticConstructor = staticConstructor; - codeBoard.BuilderClass.AddMethod(staticConstructor); - } - Method constructor = CreateConstructor(codeBoard.Info.BuilderClassName); int nofParameters = codeBoard.Info.FluentApiTypeConstructorInfo.NumberOfParameters; @@ -59,14 +52,6 @@ public void Modify(CodeBoard codeBoard) codeBoard.BuilderClass.AddMethod(constructor); } - private static Method CreateStaticConstructor(string builderClassName) - { - // static CreateStudent() - MethodSignature signature = MethodSignature.CreateConstructorSignature(builderClassName); - signature.AddModifiers("static"); - return new Method(signature); - } - private static Method CreateConstructor(string builderClassName) { // private CreateStudent() diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyCreator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyCreator.cs index add3975..d4b1ff2 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyCreator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyCreator.cs @@ -31,14 +31,14 @@ public void Modify(CodeBoard codeBoard) } } - if (innerBodyForMemberGenerator.ReflectionRequired || innerBodyForMethodGenerator.ReflectionRequired) + if (innerBodyForMemberGenerator.UnsafeAccessors || innerBodyForMethodGenerator.UnsafeAccessors) { - ImportReflectionNamespace(codeBoard); + ImportCompilerServices(codeBoard); } } - private static void ImportReflectionNamespace(CodeBoard codeBoard) + private static void ImportCompilerServices(CodeBoard codeBoard) { - codeBoard.CodeFile.AddUsing("System.Reflection"); + codeBoard.CodeFile.AddUsing("using System.Runtime.CompilerServices"); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs index c1a7f25..e3ebb4a 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs @@ -14,7 +14,7 @@ protected override string SymbolType(MemberSymbolInfo symbolInfo) return symbolInfo.IsProperty ? "Property" : "Field"; } - protected override void GenerateInnerBodyWithoutReflection(MemberSymbolInfo symbolInfo) + protected override void GenerateInnerBodyForPublicSymbol(MemberSymbolInfo symbolInfo) { // createStudent.student.Semester = semester; SetMemberCode setMemberCode = @@ -28,25 +28,12 @@ string GetPostfix(string value) } } - protected override void GenerateInnerBodyWithReflection(MemberSymbolInfo symbolInfo, string infoFieldName) + protected override void GenerateInnerBodyForPrivateSymbol(MemberSymbolInfo symbolInfo, string setMethodName) { - // CreateStudent.semesterPropertyInfo.SetValue(createStudent.student, semester); + // SetName(createStudent.student, name); SetMemberCode setMemberCode = new SetMemberCode((instancePrefix, value) => - $"{CodeBoard.Info.BuilderClassNameWithTypeParameters}.{infoFieldName}" + - $".SetValue({instancePrefix}{CodeBoard.Info.ClassInstanceName}, {value});"); + $"{setMethodName}({instancePrefix}{CodeBoard.Info.ClassInstanceName}, {value});"); CodeBoard.InnerBodyCreationDelegates.AssignSetMemberCode(symbolInfo.Name, setMemberCode); } - - protected override void InitializeInfoField(string fieldName, MemberSymbolInfo symbolInfo) - { - // semesterPropertyInfo = typeof(Student) - // .GetProperty("Semester", BindingFlags.Instance | BindingFlags.NonPublic);); - string code = $"{fieldName} =" + - $" typeof({symbolInfo.DeclaringClassNameWithTypeParameters})" + - $".Get{SymbolType(symbolInfo)}(\"{symbolInfo.Name}\", " + - $"{InfoFieldBindingFlagsArgument(symbolInfo)})!;"; - - CodeBoard.StaticConstructor!.AppendBodyLine(code); - } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index bad8118..f5f9eb8 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -19,7 +19,7 @@ protected override string SymbolType(MethodSymbolInfo symbolInfo) return "Method"; } - protected override void GenerateInnerBodyWithoutReflection(MethodSymbolInfo symbolInfo) + protected override void GenerateInnerBodyForPublicSymbol(MethodSymbolInfo symbolInfo) { CallMethodCode callMethodCode = new CallMethodCode(BuildCallMethodCode, CodeBoard.NewLineString); CodeBoard.InnerBodyCreationDelegates.AssignCallMethodCode(symbolInfo, callMethodCode); @@ -50,7 +50,7 @@ static string CreateArgument(Parameter outerMethodParameter) } } - protected override void GenerateInnerBodyWithReflection(MethodSymbolInfo symbolInfo, string infoFieldName) + protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbolInfo, string setMethodName) { CallMethodCode callMethodCode = new CallMethodCode(BuildCallMethodCode, CodeBoard.NewLineString); CodeBoard.InnerBodyCreationDelegates.AssignCallMethodCode(symbolInfo, callMethodCode); @@ -64,14 +64,14 @@ List BuildCallMethodCode( return outerMethodParameters.Any(p => p.HasAnnotation(ParameterKinds.Ref) || p.HasAnnotation(ParameterKinds.Out)) ? BuildReflectionCodeWithRefAndOutParameters( - infoFieldName, + setMethodName, instancePrefix, symbolInfo.GenericInfo, outerMethodParameters, reservedVariableNames, returnType) : BuildDefaultReflectionCode( - infoFieldName, + setMethodName, instancePrefix, symbolInfo.GenericInfo, outerMethodParameters, @@ -80,7 +80,7 @@ List BuildCallMethodCode( } private List BuildReflectionCodeWithRefAndOutParameters( - string infoFieldName, + string setMethodName, string instancePrefix, GenericInfo? genericInfo, IReadOnlyCollection outerMethodParameters, @@ -106,7 +106,7 @@ private List BuildReflectionCodeWithRefAndOutParameters( lines.Add(CodeBoard.NewCodeBuilder() .Append($"{returnType} {variableName} = ({returnType}) ", returnResult) .Append( - $"{CodeBoard.Info.BuilderClassNameWithTypeParameters}.{infoFieldName}.{MakeGenericMethod(genericInfo)}") + $"{CodeBoard.Info.BuilderClassNameWithTypeParameters}.{setMethodName}.{MakeGenericMethod(genericInfo)}") .Append($"Invoke({instancePrefix}{CodeBoard.Info.ClassInstanceName}, args){suppressNullability};") .ToString()); @@ -139,7 +139,7 @@ string AssignValueToArgument(int index, Parameter parameter) } private List BuildDefaultReflectionCode( - string infoFieldName, + string setMethodName, string instancePrefix, GenericInfo? genericInfo, IReadOnlyCollection outerMethodParameters, @@ -155,7 +155,7 @@ private List BuildDefaultReflectionCode( // .Invoke(createStudent.student, new object[] { semester }); CodeBoard.NewCodeBuilder() .Append($"return ({returnType}) ", returnResult) - .Append($"{CodeBoard.Info.BuilderClassNameWithTypeParameters}.{infoFieldName}" + + .Append($"{CodeBoard.Info.BuilderClassNameWithTypeParameters}.{setMethodName}" + $".{MakeGenericMethod(genericInfo)}") .Append($"Invoke({instancePrefix}{CodeBoard.Info.ClassInstanceName}, ") .Append($"new object?[] {{ {string.Join(", ", outerMethodParameters.Select(p => p.Name))} }})" + @@ -174,70 +174,6 @@ private static string MakeGenericMethod(GenericInfo? genericInfo) return $"MakeGenericMethod({string.Join(", ", genericInfo.ParameterStrings.Select(p => $"typeof({p})"))})."; } - protected override void InitializeInfoField(string fieldName, MethodSymbolInfo symbolInfo) - { - Method staticConstructor = CodeBoard.StaticConstructor!; - const string indentation = CodeBuilder.OneLevelIndentation; - - string typeArguments = - @$"new Type[] {{ {string.Join(", ", - symbolInfo.ParameterInfos.Select(CreateMethodParameter))} }}"; - - // withNameMethodInfo = typeof(Student).GetMethod( - // "WithName", - // 0, -> generic parameter count - // BindingFlags.Instance | BindingFlags.NonPublic, - // null -> binder - // new Type[] { typeof(string) }, - // null)!; -> modifiers - // - // Generic types are created via Type.MakeGenericMethodParameter(int position). In addition, a ref type is - // specified via MakeByRefType(). - staticConstructor.AppendBodyLine($"{fieldName} = " + - $"typeof({symbolInfo.DeclaringClassNameWithTypeParameters}).GetMethod("); - staticConstructor.AppendBodyLine($"{indentation}\"{symbolInfo.Name}\","); - staticConstructor.AppendBodyLine($"{indentation}{GetGenericParameterCount(symbolInfo.GenericInfo)},"); - staticConstructor.AppendBodyLine($"{indentation}{InfoFieldBindingFlagsArgument(symbolInfo)},"); - staticConstructor.AppendBodyLine($"{indentation}null,"); - staticConstructor.AppendBodyLine($"{indentation}{typeArguments},"); - staticConstructor.AppendBodyLine($"{indentation}null)!;"); - - CodeBoard.CodeFile.AddUsing("System"); - - static string CreateMethodParameter(ParameterSymbolInfo parameterInfo) - { - return parameterInfo.IsGenericParameter - ? $"Type.MakeGenericMethodParameter({parameterInfo.GenericTypeParameterPosition!.Value})" + - $"{MakeByRefType(parameterInfo.ParameterKinds)}" - : $"typeof({GetTypeOfArgument(parameterInfo)}){MakeByRefType(parameterInfo.ParameterKinds)}"; - - static string GetTypeOfArgument(ParameterSymbolInfo parameterInfo) - { - if (parameterInfo.IsReferenceType && parameterInfo.TypeForCodeGeneration.EndsWith("?")) - { - return parameterInfo.TypeForCodeGeneration - .Substring(0, parameterInfo.TypeForCodeGeneration.Length - 1); - } - - return parameterInfo.TypeForCodeGeneration; - } - - static string MakeByRefType(ParameterKinds parameterKinds) - { - return parameterKinds.HasFlag(ParameterKinds.In) || - parameterKinds.HasFlag(ParameterKinds.Out) || - parameterKinds.HasFlag(ParameterKinds.Ref) - ? ".MakeByRefType()" - : string.Empty; - } - } - - static string GetGenericParameterCount(GenericInfo? genericInfo) - { - return genericInfo == null ? "0" : genericInfo.ParameterCount.ToString(); - } - } - private static bool IsNoneOrVoid(string? returnType) { return returnType is null or "void"; diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs index d48ab2a..50d5fcc 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs @@ -11,58 +11,53 @@ internal abstract class InnerBodyGeneratorBase internal InnerBodyGeneratorBase(CodeBoard codeBoard) { - this.CodeBoard = codeBoard; - ReflectionRequired = false; + CodeBoard = codeBoard; + UnsafeAccessors = false; } - internal bool ReflectionRequired { get; private set; } + internal bool UnsafeAccessors { get; private set; } internal void GenerateInnerBody(TSymbolInfo symbolInfo) { - if (!symbolInfo.RequiresReflection) + if (symbolInfo.Accessibility.IsPublicOrInternal()) { - GenerateInnerBodyWithoutReflection(symbolInfo); + GenerateInnerBodyForPublicSymbol(symbolInfo); } else { - GenerateInnerBodyWithReflectionAndFields(symbolInfo); - ReflectionRequired = true; + GenerateUnsafeAccessorAndInnerBodyForPrivateSymbol(symbolInfo); + UnsafeAccessors = true; } } protected abstract string SymbolType(TSymbolInfo symbolInfo); - protected abstract void GenerateInnerBodyWithoutReflection(TSymbolInfo symbolInfo); - protected abstract void GenerateInnerBodyWithReflection(TSymbolInfo symbolInfo, string infoFieldName); - protected abstract void InitializeInfoField(string fieldName, TSymbolInfo symbolInfo); + protected abstract void GenerateInnerBodyForPublicSymbol(TSymbolInfo symbolInfo); + protected abstract void GenerateInnerBodyForPrivateSymbol(TSymbolInfo symbolInfo, string setMethodName); - private void GenerateInnerBodyWithReflectionAndFields(TSymbolInfo symbolInfo) + private void GenerateUnsafeAccessorAndInnerBodyForPrivateSymbol(TSymbolInfo symbolInfo) { - string symbolType = SymbolType(symbolInfo); + if (symbolInfo is not MemberSymbolInfo memberSymbolInfo) // todo: method + { + return; + } - // semesterPropertyInfo / semesterFieldInfo / semesterMethodInfo - string infoFieldName = $"{symbolInfo.NameInCamelCase}{symbolType}Info"; - infoFieldName = CodeBoard.ReservedVariableNames.GetNewGlobalVariableName(infoFieldName); + string setMethodName = $"Set{symbolInfo.NameInPascalCase}"; - GenerateInfoField(symbolType, infoFieldName); - InitializeInfoField(infoFieldName, symbolInfo); + // [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + // private static extern void SetName(Student student, string value); + MethodSignature methodSignature = + MethodSignature.Create("void", setMethodName, null, false); + methodSignature.AddModifiers("private", "static", "extern"); - GenerateInnerBodyWithReflection(symbolInfo, infoFieldName); - } + methodSignature.AddParameter( + CodeBoard.Info.FluentApiClassNameWithTypeParameters, + CodeBoard.Info.ClassInstanceName); // Student student + methodSignature.AddParameter(memberSymbolInfo.TypeForCodeGeneration, "value"); // string value - private void GenerateInfoField(string symbolType, string fieldName) - { - // private static readonly PropertyInfo semesterPropertyInfo; - Field field = new Field($"{symbolType}Info", fieldName); - field.AddModifiers("private", "static", "readonly"); - CodeBoard.BuilderClass.AddField(field); - } - - protected string InfoFieldBindingFlagsArgument(TSymbolInfo symbolInfo) - { - string accessibilityBindingFlag = symbolInfo.Accessibility.IsPublicOrInternal() - ? "BindingFlags.Public" - : "BindingFlags.NonPublic"; + methodSignature.AddAttribute( + $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"set_{symbolInfo.NameInPascalCase}\")]"); + CodeBoard.BuilderClass.AddMethodSignature(methodSignature); - return $"BindingFlags.Instance | {accessibilityBindingFlag}"; + GenerateInnerBodyForPrivateSymbol(symbolInfo, setMethodName); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs index 38e5045..b564916 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs @@ -14,6 +14,7 @@ internal FluentApiSymbolInfo( { Name = name; NameInCamelCase = Name.TrimStart('_').FirstCharToLower(); + NameInPascalCase = Name.TrimStart('_').FirstCharToUpper(); DeclaringClassNameWithTypeParameters = declaringClassNameWithTypeParameters; Accessibility = accessibility; Comments = comments; @@ -21,6 +22,7 @@ internal FluentApiSymbolInfo( internal string Name { get; } internal string NameInCamelCase { get; } + internal string NameInPascalCase { get; } internal string DeclaringClassNameWithTypeParameters { get; } internal Accessibility Accessibility { get; } internal Comments Comments { get; } From 8f675f623862de30af617400d31b80cb70a246a0 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 22 Dec 2025 20:05:28 +0100 Subject: [PATCH 05/67] fix: publiclyWritable --- .../CodeBoardElements/FluentApiSymbolInfo.cs | 8 +++-- .../CodeBoardElements/MemberSymbolInfo.cs | 3 +- .../CodeBoardElements/MethodSymbolInfo.cs | 3 +- .../SourceGenerators/SymbolInfoCreator.cs | 33 +++++++++++++++++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs index b564916..8acf082 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs @@ -10,6 +10,7 @@ internal FluentApiSymbolInfo( string name, string declaringClassNameWithTypeParameters, Accessibility accessibility, + bool publiclyWritable, Comments comments) { Name = name; @@ -17,6 +18,7 @@ internal FluentApiSymbolInfo( NameInPascalCase = Name.TrimStart('_').FirstCharToUpper(); DeclaringClassNameWithTypeParameters = declaringClassNameWithTypeParameters; Accessibility = accessibility; + PubliclyWritable = publiclyWritable; Comments = comments; } @@ -25,6 +27,7 @@ internal FluentApiSymbolInfo( internal string NameInPascalCase { get; } internal string DeclaringClassNameWithTypeParameters { get; } internal Accessibility Accessibility { get; } + internal bool PubliclyWritable { get; } internal Comments Comments { get; } protected bool Equals(FluentApiSymbolInfo other) @@ -32,6 +35,7 @@ protected bool Equals(FluentApiSymbolInfo other) return Name == other.Name && DeclaringClassNameWithTypeParameters == other.DeclaringClassNameWithTypeParameters && Accessibility == other.Accessibility && + PubliclyWritable == other.PubliclyWritable && Comments.Equals(other.Comments); } @@ -39,13 +43,13 @@ public override bool Equals(object? obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; + if (obj.GetType() != GetType()) return false; return Equals((FluentApiSymbolInfo)obj); } public override int GetHashCode() { return new HashCode() - .Add(Name, DeclaringClassNameWithTypeParameters, Accessibility, Comments); + .Add(Name, DeclaringClassNameWithTypeParameters, Accessibility, PubliclyWritable, Comments); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs index 509e556..2b5b9aa 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs @@ -12,12 +12,13 @@ internal MemberSymbolInfo( string type, string declaringClassNameWithTypeParameters, Accessibility accessibility, + bool publiclyWritable, string typeForCodeGeneration, bool isNullable, bool isProperty, CollectionType? collectionType, Comments comments) - : base(name, declaringClassNameWithTypeParameters, accessibility, comments) + : base(name, declaringClassNameWithTypeParameters, accessibility, publiclyWritable, comments) { Type = type; TypeForCodeGeneration = typeForCodeGeneration; diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs index 2f664bf..124410e 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs @@ -11,11 +11,12 @@ internal MethodSymbolInfo( string name, string declaringClassNameWithTypeParameters, Accessibility accessibility, + bool publiclyWritable, GenericInfo? genericInfo, IReadOnlyCollection parameterInfos, string returnType, Comments comments) - : base(name, declaringClassNameWithTypeParameters, accessibility, comments) + : base(name, declaringClassNameWithTypeParameters, accessibility, publiclyWritable, comments) { GenericInfo = genericInfo; ParameterInfos = parameterInfos; diff --git a/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs b/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs index 5ca4395..f8ec07f 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs @@ -2,6 +2,7 @@ using M31.FluentApi.Generator.CodeBuilding; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements.FluentApiComments; +using M31.FluentApi.Generator.Commons; using M31.FluentApi.Generator.SourceGenerators.Collections; using M31.FluentApi.Generator.SourceGenerators.Generics; using Microsoft.CodeAnalysis; @@ -37,6 +38,7 @@ private static MemberSymbolInfo CreateMemberSymbolInfo( fieldSymbol.Type.ToString(), declaringClassNameWithTypeParameters, fieldSymbol.DeclaredAccessibility, + PubliclyWritable(fieldSymbol), CodeTypeExtractor.GetTypeForCodeGeneration(fieldSymbol.Type), fieldSymbol.NullableAnnotation == NullableAnnotation.Annotated, false, @@ -53,6 +55,7 @@ private static MemberSymbolInfo CreateMemberSymbolInfo( propertySymbol.Type.ToString(), declaringClassNameWithTypeParameters, propertySymbol.DeclaredAccessibility, + PubliclyWritable(propertySymbol), CodeTypeExtractor.GetTypeForCodeGeneration(propertySymbol.Type), propertySymbol.NullableAnnotation == NullableAnnotation.Annotated, true, @@ -77,6 +80,7 @@ private static MethodSymbolInfo CreateMethodSymbolInfo( methodSymbol.Name, declaringClassNameWithTypeParameters, methodSymbol.DeclaredAccessibility, + PubliclyWritable(methodSymbol), genericInfo, parameterInfos, CodeTypeExtractor.GetTypeForCodeGeneration(methodSymbol.ReturnType), @@ -88,6 +92,35 @@ private static MethodSymbolInfo CreateMethodSymbolInfo( return methodSymbol.IsGenericMethod ? GenericInfo.Create(methodSymbol.TypeParameters) : null; } + private static bool PubliclyWritable(IFieldSymbol fieldSymbol) + { + bool isWritable = !fieldSymbol.IsReadOnly; + return PubliclyWritable(fieldSymbol.DeclaredAccessibility, isWritable); + } + + private static bool PubliclyWritable(IMethodSymbol methodSymbol) + { + return methodSymbol.DeclaredAccessibility.IsPublicOrInternal(); + } + + private static bool PubliclyWritable(IPropertySymbol propertySymbol) + { + bool isWritable = false; + + if (propertySymbol.SetMethod != null) + { + isWritable = propertySymbol.SetMethod.DeclaredAccessibility.IsPublicOrInternal() && + !propertySymbol.SetMethod.IsInitOnly; + } + + return PubliclyWritable(propertySymbol.DeclaredAccessibility, isWritable); + } + + private static bool PubliclyWritable(Accessibility declaredAccessibility, bool isWritable) + { + return declaredAccessibility.IsPublicOrInternal() && isWritable; + } + private static ParameterSymbolInfo CreateParameterSymbolInfo( IParameterSymbol parameterSymbol, Dictionary typeParameterNameToTypeParameterPosition) From 19dce114ef23b18335527335802c1739f1a473cd Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 23 Dec 2025 08:28:52 +0100 Subject: [PATCH 06/67] wip: unsafe accessor --- .../CodeBuilding/Class.cs | 3 ++- .../CodeBuilding/Interface.cs | 2 +- .../CodeBuilding/Method.cs | 1 + .../CodeBuilding/MethodSignature.cs | 18 ++++++++++-------- .../InnerBodyGeneration/InnerBodyCreator.cs | 2 +- .../InnerBodyGeneratorBase.cs | 6 +++--- .../CreateStudent.expected.txt | 2 +- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeBuilding/Class.cs b/src/M31.FluentApi.Generator/CodeBuilding/Class.cs index b1b8de4..346d4a2 100644 --- a/src/M31.FluentApi.Generator/CodeBuilding/Class.cs +++ b/src/M31.FluentApi.Generator/CodeBuilding/Class.cs @@ -119,8 +119,9 @@ public CodeBuilder AppendCode(CodeBuilder codeBuilder) .BlankLine() .Append(properties) .BlankLine() + .AppendWithBlankLines(methods.Where(m => m.IsConstructor)) .AppendWithBlankLines(methodSignatures) - .AppendWithBlankLines(methods) + .AppendWithBlankLines(methods.Where(m => !m.IsConstructor)) .AppendWithBlankLines(definitions) .CloseBlock(); } diff --git a/src/M31.FluentApi.Generator/CodeBuilding/Interface.cs b/src/M31.FluentApi.Generator/CodeBuilding/Interface.cs index 5b916e3..4d7e206 100644 --- a/src/M31.FluentApi.Generator/CodeBuilding/Interface.cs +++ b/src/M31.FluentApi.Generator/CodeBuilding/Interface.cs @@ -22,7 +22,7 @@ internal Interface(string accessModifier, string name) internal void AddMethodSignature(CommentedMethodSignature methodSignature) { - if (!methodSignature.MethodSignature.IsSignatureForInterface) + if (!methodSignature.MethodSignature.IsStandaloneSignature) { throw new ArgumentException("Expected a stand-alone method signature."); } diff --git a/src/M31.FluentApi.Generator/CodeBuilding/Method.cs b/src/M31.FluentApi.Generator/CodeBuilding/Method.cs index 4bc2c5f..90060fa 100644 --- a/src/M31.FluentApi.Generator/CodeBuilding/Method.cs +++ b/src/M31.FluentApi.Generator/CodeBuilding/Method.cs @@ -19,6 +19,7 @@ internal Method(MethodComments methodComments, MethodSignature methodSignature, internal MethodComments MethodComments { get; } internal MethodSignature MethodSignature { get; } internal MethodBody MethodBody { get; } + internal bool IsConstructor => MethodSignature.IsConstructor; internal void AddCommentLine(string commentLine) { diff --git a/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs b/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs index da7e28e..18eed4b 100644 --- a/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs +++ b/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs @@ -6,24 +6,24 @@ private MethodSignature( string? returnType, string methodName, string? explicitInterfacePrefix, - bool isSignatureForInterface) + bool isStandaloneSignature) { ReturnType = returnType; MethodName = methodName; ExplicitInterfacePrefix = explicitInterfacePrefix; - IsSignatureForInterface = isSignatureForInterface; + IsStandaloneSignature = isStandaloneSignature; Generics = new Generics(); Parameters = new Parameters(); Modifiers = new Modifiers(); Attributes = new List(); } - private MethodSignature(MethodSignature methodSignature, bool isSignatureForInterface) + private MethodSignature(MethodSignature methodSignature, bool isStandaloneSignature) { ReturnType = methodSignature.ReturnType; MethodName = methodSignature.MethodName; ExplicitInterfacePrefix = methodSignature.ExplicitInterfacePrefix; - IsSignatureForInterface = isSignatureForInterface; + IsStandaloneSignature = isStandaloneSignature; Generics = new Generics(methodSignature.Generics); Parameters = new Parameters(methodSignature.Parameters); Modifiers = new Modifiers(methodSignature.Modifiers); @@ -47,13 +47,14 @@ internal static MethodSignature CreateConstructorSignature(string className) internal string? ReturnType { get; } internal string MethodName { get; } internal string? ExplicitInterfacePrefix { get; } - internal bool IsSignatureForInterface { get; } + internal bool IsStandaloneSignature { get; } internal Generics Generics { get; } internal Parameters Parameters { get; } internal Modifiers Modifiers { get; } internal List Attributes { get; } - internal bool IsSignatureForMethodBody => !IsSignatureForInterface; + internal bool IsSignatureForMethodBody => !IsStandaloneSignature; internal bool IsExplicitInterfaceImplementation => ExplicitInterfacePrefix != null; + internal bool IsConstructor => ReturnType == null; internal void AddGenericParameter(string parameter, IEnumerable constraints) { @@ -93,6 +94,7 @@ internal MethodSignature ToSignatureForMethodBody() public CodeBuilder AppendCode(CodeBuilder codeBuilder) { codeBuilder + .AppendLines(Attributes) .StartLine() .Append(Modifiers, IsSignatureForMethodBody && !IsExplicitInterfaceImplementation) .Append($"{ReturnType} ", ReturnType != null) @@ -104,7 +106,7 @@ public CodeBuilder AppendCode(CodeBuilder codeBuilder) if (Generics.Constraints.Count == 0 || (IsSignatureForMethodBody && IsExplicitInterfaceImplementation)) { - return codeBuilder.Append(IsSignatureForInterface ? ";" : null).EndLine(); + return codeBuilder.Append(IsStandaloneSignature ? ";" : null).EndLine(); } else { @@ -112,7 +114,7 @@ public CodeBuilder AppendCode(CodeBuilder codeBuilder) .EndLine() .Indent() .Append(Generics.Constraints) - .Append(IsSignatureForInterface ? ";" : null) + .Append(IsStandaloneSignature ? ";" : null) .EndLine() .Unindent(); } diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyCreator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyCreator.cs index d4b1ff2..1afe34e 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyCreator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyCreator.cs @@ -39,6 +39,6 @@ public void Modify(CodeBoard codeBoard) private static void ImportCompilerServices(CodeBoard codeBoard) { - codeBoard.CodeFile.AddUsing("using System.Runtime.CompilerServices"); + codeBoard.CodeFile.AddUsing("System.Runtime.CompilerServices"); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs index 50d5fcc..de2d2eb 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs @@ -19,7 +19,7 @@ internal InnerBodyGeneratorBase(CodeBoard codeBoard) internal void GenerateInnerBody(TSymbolInfo symbolInfo) { - if (symbolInfo.Accessibility.IsPublicOrInternal()) + if (symbolInfo.PubliclyWritable) { GenerateInnerBodyForPublicSymbol(symbolInfo); } @@ -46,8 +46,8 @@ private void GenerateUnsafeAccessorAndInnerBodyForPrivateSymbol(TSymbolInfo symb // [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] // private static extern void SetName(Student student, string value); MethodSignature methodSignature = - MethodSignature.Create("void", setMethodName, null, false); - methodSignature.AddModifiers("private", "static", "extern"); + MethodSignature.Create("void", setMethodName, null, true); + methodSignature.AddModifiers("private", "static", "extern"); // todo: modifiers dont work. methodSignature.AddParameter( CodeBoard.Info.FluentApiClassNameWithTypeParameters, diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt index e2ad6d2..981cadd 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt @@ -8,7 +8,7 @@ using System; using System.Runtime.CompilerServices; -namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreePrivateMembersClass;; +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreePrivateMembersClass; public class CreateStudent : CreateStudent.ICreateStudent, From 07b7e10da974c5e0cf51df3455f33798c71bdfd3 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 23 Dec 2025 12:03:04 +0100 Subject: [PATCH 07/67] fix: ThreePrivateMembersClass test --- .../CodeBuilding/MethodSignature.cs | 4 ++- .../CreateStudent.expected.txt | 2 +- .../CreateStudent.g.cs | 29 +++++++++---------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs b/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs index 18eed4b..708a4a3 100644 --- a/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs +++ b/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs @@ -96,7 +96,9 @@ public CodeBuilder AppendCode(CodeBuilder codeBuilder) codeBuilder .AppendLines(Attributes) .StartLine() - .Append(Modifiers, IsSignatureForMethodBody && !IsExplicitInterfaceImplementation) + .Append( + Modifiers, + Modifiers.Contains("extern") || (IsSignatureForMethodBody && !IsExplicitInterfaceImplementation)) .Append($"{ReturnType} ", ReturnType != null) .Append($"{ExplicitInterfacePrefix}.", IsSignatureForMethodBody && IsExplicitInterfaceImplementation) .Append(MethodName) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt index 981cadd..12b74e8 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt @@ -27,7 +27,7 @@ public class CreateStudent : private static extern void SetName(Student student, string value); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] - private static extern void SetDateOfBirth(Student student, DateOnly value); + private static extern void SetDateOfBirth(Student student, System.DateOnly value); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] private static extern void SetSemester(Student student, int value); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs index 10e4cc1..12b74e8 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreePrivateMembersClass; @@ -17,22 +17,21 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - private static readonly PropertyInfo semesterPropertyInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - dateOfBirthPropertyInfo = typeof(Student).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.Public)!; - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { student = new Student(); } + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Student student, System.DateOnly value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + public static ICreateStudent InitialStep() { return new CreateStudent(); @@ -41,25 +40,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.dateOfBirthPropertyInfo.SetValue(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } From 2e7c16f02ced2eeec144f728a34179cb626f07d8 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 23 Dec 2025 12:14:13 +0100 Subject: [PATCH 08/67] test: failing PrivateFluentMethodClass test --- .../CreateStudent.expected.txt | 47 ++++++------------- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.expected.txt index d4e01ba..451b429 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.expected.txt @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFluentMethodClass; @@ -17,40 +17,21 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly MethodInfo withNameMethodInfo; - private static readonly MethodInfo bornOnMethodInfo; - private static readonly MethodInfo inSemesterMethodInfo; - - static CreateStudent() - { - withNameMethodInfo = typeof(Student).GetMethod( - "WithName", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - bornOnMethodInfo = typeof(Student).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - inSemesterMethodInfo = typeof(Student).GetMethod( - "InSemester", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int) }, - null)!; - } private CreateStudent() { student = new Student(); } + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] + private static extern void CallWithName(Student student, string name); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Student student, System.DateOnly date); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "InSemester")] + private static extern void CallInSemester(Student student, int semester); + public static ICreateStudent InitialStep() { return new CreateStudent(); @@ -59,25 +40,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.withNameMethodInfo.Invoke(createStudent.student, new object?[] { name }); + CallWithName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.withNameMethodInfo.Invoke(student, new object?[] { name }); + CallWithName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly date) { - CreateStudent.bornOnMethodInfo.Invoke(student, new object?[] { date }); + CallBornOn(student, date); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.inSemesterMethodInfo.Invoke(student, new object?[] { semester }); + CallInSemester(student, semester); return student; } From cf320a3bff4b87ebc9b430a3b18fcc2dda211b8b Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Thu, 25 Dec 2025 22:07:46 +0100 Subject: [PATCH 09/67] feat: InnerBodyForMethodGenerator --- .../InnerBodyForMemberGenerator.cs | 25 ++- .../InnerBodyForMethodGenerator.cs | 161 +++++------------- .../InnerBodyGeneratorBase.cs | 34 +--- .../CreateStudent.g.cs | 47 ++--- 4 files changed, 77 insertions(+), 190 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs index e3ebb4a..0c8e169 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs @@ -1,3 +1,4 @@ +using M31.FluentApi.Generator.CodeBuilding; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; namespace M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.InnerBodyGeneration; @@ -9,11 +10,6 @@ internal InnerBodyForMemberGenerator(CodeBoard codeBoard) { } - protected override string SymbolType(MemberSymbolInfo symbolInfo) - { - return symbolInfo.IsProperty ? "Property" : "Field"; - } - protected override void GenerateInnerBodyForPublicSymbol(MemberSymbolInfo symbolInfo) { // createStudent.student.Semester = semester; @@ -28,8 +24,25 @@ string GetPostfix(string value) } } - protected override void GenerateInnerBodyForPrivateSymbol(MemberSymbolInfo symbolInfo, string setMethodName) + protected override void GenerateInnerBodyForPrivateSymbol(MemberSymbolInfo symbolInfo) { + string setMethodName = $"Set{symbolInfo.NameInPascalCase}"; + + // [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + // private static extern void SetName(Student student, string value); + MethodSignature methodSignature = + MethodSignature.Create("void", setMethodName, null, true); + methodSignature.AddModifiers("private", "static", "extern"); + + methodSignature.AddParameter( + CodeBoard.Info.FluentApiClassNameWithTypeParameters, + CodeBoard.Info.ClassInstanceName); // Student student + methodSignature.AddParameter(symbolInfo.TypeForCodeGeneration, "value"); // string value + + methodSignature.AddAttribute( + $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"set_{symbolInfo.NameInPascalCase}\")]"); + CodeBoard.BuilderClass.AddMethodSignature(methodSignature); + // SetName(createStudent.student, name); SetMemberCode setMemberCode = new SetMemberCode((instancePrefix, value) => diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index f5f9eb8..37773b2 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -3,7 +3,7 @@ using M31.FluentApi.Generator.CodeBuilding; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; -using M31.FluentApi.Generator.SourceGenerators.Generics; +using M31.FluentApi.Generator.SourceGenerators.Generics; // todo: remove if not needed namespace M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.InnerBodyGeneration; @@ -14,11 +14,6 @@ internal InnerBodyForMethodGenerator(CodeBoard codeBoard) { } - protected override string SymbolType(MethodSymbolInfo symbolInfo) - { - return "Method"; - } - protected override void GenerateInnerBodyForPublicSymbol(MethodSymbolInfo symbolInfo) { CallMethodCode callMethodCode = new CallMethodCode(BuildCallMethodCode, CodeBoard.NewLineString); @@ -42,16 +37,37 @@ List BuildCallMethodCode( .ToString(), }; } - - static string CreateArgument(Parameter outerMethodParameter) - { - // ref/in/out semester - return $"{outerMethodParameter.ParameterAnnotations?.ToCallsiteAnnotations()}{outerMethodParameter.Name}"; - } } - protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbolInfo, string setMethodName) + protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbolInfo) { + string callMethodName = $"Call{symbolInfo.NameInPascalCase}"; + + // [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] + // private static extern void CallWithName(Student student, string name); + MethodSignature methodSignature = + MethodSignature.Create("void", callMethodName, null, true); + methodSignature.AddModifiers("private", "static", "extern"); + + methodSignature.AddParameter( + new Parameter(CodeBoard.Info.FluentApiClassNameWithTypeParameters, CodeBoard.Info.ClassInstanceName)); + // todo: test generic case + + List parameters = symbolInfo.ParameterInfos // todo: extract method from BuilderMethodFactory. + .Select(i => new Parameter( + i.TypeForCodeGeneration, + i.ParameterName, + i.DefaultValue, + i.GenericTypeParameterPosition, + new ParameterAnnotations(i.ParameterKinds))) + .ToList(); + + parameters.ForEach(methodSignature.AddParameter); // todo: add generic parameters + + methodSignature.AddAttribute( + $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"{symbolInfo.NameInPascalCase}\")]"); + CodeBoard.BuilderClass.AddMethodSignature(methodSignature); + CallMethodCode callMethodCode = new CallMethodCode(BuildCallMethodCode, CodeBoard.NewLineString); CodeBoard.InnerBodyCreationDelegates.AssignCallMethodCode(symbolInfo, callMethodCode); @@ -61,117 +77,24 @@ List BuildCallMethodCode( ReservedVariableNames reservedVariableNames, string? returnType) { - return outerMethodParameters.Any(p => - p.HasAnnotation(ParameterKinds.Ref) || p.HasAnnotation(ParameterKinds.Out)) - ? BuildReflectionCodeWithRefAndOutParameters( - setMethodName, - instancePrefix, - symbolInfo.GenericInfo, - outerMethodParameters, - reservedVariableNames, - returnType) - : BuildDefaultReflectionCode( - setMethodName, - instancePrefix, - symbolInfo.GenericInfo, - outerMethodParameters, - returnType); - } - } - - private List BuildReflectionCodeWithRefAndOutParameters( - string setMethodName, - string instancePrefix, - GenericInfo? genericInfo, - IReadOnlyCollection outerMethodParameters, - ReservedVariableNames reservedVariableNames, - string? returnType) - { - bool returnResult = !IsNoneOrVoid(returnType); - string variableName = returnResult - ? reservedVariableNames.GetNewLocalVariableName("result") - : string.Empty; - string suppressNullability = returnResult ? "!" : string.Empty; - - List lines = new List(); - - // object?[] args = new object?[] { semester }; - lines.Add( - $"object?[] args = new object?[] {{ {string.Join(", ", outerMethodParameters.Select(GetArgument))} }};"); - - // CreateStudent.semesterMethodInfo.Invoke(createStudent.student, args) or - // CreateStudent.semesterMethodInfo.MakeGenericInfo(typeof(T1), typeof(T2)) - // .Invoke(createStudent.student, args) or - // string result = (string) toJsonMethodInfo.Invoke(createStudent.student, args) - lines.Add(CodeBoard.NewCodeBuilder() - .Append($"{returnType} {variableName} = ({returnType}) ", returnResult) - .Append( - $"{CodeBoard.Info.BuilderClassNameWithTypeParameters}.{setMethodName}.{MakeGenericMethod(genericInfo)}") - .Append($"Invoke({instancePrefix}{CodeBoard.Info.ClassInstanceName}, args){suppressNullability};") - .ToString()); - - foreach (var parameter in outerMethodParameters.Select((p, i) => new { Value = p, Index = i })) - { - if (parameter.Value.HasAnnotation(ParameterKinds.Ref) || parameter.Value.HasAnnotation(ParameterKinds.Out)) + return new List() { - lines.Add(AssignValueToArgument(parameter.Index, parameter.Value)); - } - } - - if (returnResult) - { - lines.Add($"return {variableName};"); - } - - return lines; - - string GetArgument(Parameter parameter) - { - return parameter.HasAnnotation(ParameterKinds.Out) ? "null" : parameter.Name; - } - - string AssignValueToArgument(int index, Parameter parameter) - { - // For out and ref parameters, the invoke method writes the result values into the args array. - // semester = (int) args[0]; - return $"{parameter.Name} = ({parameter.Type}) args[{index}]!;"; + // CallWithName(student, name); // todo: better example + CodeBoard.NewCodeBuilder() + .Append("return ", !IsNoneOrVoid(returnType)) + .Append($"{callMethodName}") + .Append(symbolInfo.GenericInfo?.ParameterListInAngleBrackets) + .Append($"({instancePrefix}{CodeBoard.Info.ClassInstanceName}, ") + .Append($"{string.Join(", ", outerMethodParameters.Select(CreateArgument))});") + .ToString(), + }; } } - private List BuildDefaultReflectionCode( - string setMethodName, - string instancePrefix, - GenericInfo? genericInfo, - IReadOnlyCollection outerMethodParameters, - string? returnType) + private static string CreateArgument(Parameter outerMethodParameter) { - bool returnResult = !IsNoneOrVoid(returnType); - string suppressNullability = returnResult ? "!" : string.Empty; - - return new List() - { - // CreateStudent.semesterMethodInfo.Invoke(createStudent.student, new object[] { semester }); or - // CreateStudent.semesterMethodInfo.MakeGenericMethod(typeof(T1), typeof(T2)) - // .Invoke(createStudent.student, new object[] { semester }); - CodeBoard.NewCodeBuilder() - .Append($"return ({returnType}) ", returnResult) - .Append($"{CodeBoard.Info.BuilderClassNameWithTypeParameters}.{setMethodName}" + - $".{MakeGenericMethod(genericInfo)}") - .Append($"Invoke({instancePrefix}{CodeBoard.Info.ClassInstanceName}, ") - .Append($"new object?[] {{ {string.Join(", ", outerMethodParameters.Select(p => p.Name))} }})" + - $"{suppressNullability};") - .ToString(), - }; - } - - private static string MakeGenericMethod(GenericInfo? genericInfo) - { - if (genericInfo == null) - { - return string.Empty; - } - - return $"MakeGenericMethod({string.Join(", ", genericInfo.ParameterStrings.Select(p => $"typeof({p})"))})."; + // ref/in/out semester + return $"{outerMethodParameter.ParameterAnnotations?.ToCallsiteAnnotations()}{outerMethodParameter.Name}"; } private static bool IsNoneOrVoid(string? returnType) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs index de2d2eb..b5e1252 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyGeneratorBase.cs @@ -1,6 +1,4 @@ -using M31.FluentApi.Generator.CodeBuilding; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; -using M31.FluentApi.Generator.Commons; namespace M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.InnerBodyGeneration; @@ -25,39 +23,11 @@ internal void GenerateInnerBody(TSymbolInfo symbolInfo) } else { - GenerateUnsafeAccessorAndInnerBodyForPrivateSymbol(symbolInfo); + GenerateInnerBodyForPrivateSymbol(symbolInfo); UnsafeAccessors = true; } } - protected abstract string SymbolType(TSymbolInfo symbolInfo); protected abstract void GenerateInnerBodyForPublicSymbol(TSymbolInfo symbolInfo); - protected abstract void GenerateInnerBodyForPrivateSymbol(TSymbolInfo symbolInfo, string setMethodName); - - private void GenerateUnsafeAccessorAndInnerBodyForPrivateSymbol(TSymbolInfo symbolInfo) - { - if (symbolInfo is not MemberSymbolInfo memberSymbolInfo) // todo: method - { - return; - } - - string setMethodName = $"Set{symbolInfo.NameInPascalCase}"; - - // [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] - // private static extern void SetName(Student student, string value); - MethodSignature methodSignature = - MethodSignature.Create("void", setMethodName, null, true); - methodSignature.AddModifiers("private", "static", "extern"); // todo: modifiers dont work. - - methodSignature.AddParameter( - CodeBoard.Info.FluentApiClassNameWithTypeParameters, - CodeBoard.Info.ClassInstanceName); // Student student - methodSignature.AddParameter(memberSymbolInfo.TypeForCodeGeneration, "value"); // string value - - methodSignature.AddAttribute( - $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"set_{symbolInfo.NameInPascalCase}\")]"); - CodeBoard.BuilderClass.AddMethodSignature(methodSignature); - - GenerateInnerBodyForPrivateSymbol(symbolInfo, setMethodName); - } + protected abstract void GenerateInnerBodyForPrivateSymbol(TSymbolInfo symbolInfo); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.g.cs index d4e01ba..451b429 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFluentMethodClass; @@ -17,40 +17,21 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly MethodInfo withNameMethodInfo; - private static readonly MethodInfo bornOnMethodInfo; - private static readonly MethodInfo inSemesterMethodInfo; - - static CreateStudent() - { - withNameMethodInfo = typeof(Student).GetMethod( - "WithName", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - bornOnMethodInfo = typeof(Student).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - inSemesterMethodInfo = typeof(Student).GetMethod( - "InSemester", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int) }, - null)!; - } private CreateStudent() { student = new Student(); } + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] + private static extern void CallWithName(Student student, string name); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Student student, System.DateOnly date); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "InSemester")] + private static extern void CallInSemester(Student student, int semester); + public static ICreateStudent InitialStep() { return new CreateStudent(); @@ -59,25 +40,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.withNameMethodInfo.Invoke(createStudent.student, new object?[] { name }); + CallWithName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.withNameMethodInfo.Invoke(student, new object?[] { name }); + CallWithName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly date) { - CreateStudent.bornOnMethodInfo.Invoke(student, new object?[] { date }); + CallBornOn(student, date); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.inSemesterMethodInfo.Invoke(student, new object?[] { semester }); + CallInSemester(student, semester); return student; } From 2680dd01f2fda448d96cef4b0c4a30f0f02b47ad Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Fri, 26 Dec 2025 20:38:00 +0100 Subject: [PATCH 10/67] test: FluentReturnMultiStepPrivateMethodsClass --- .../CodeBuilding/Class.cs | 5 +- .../InnerBodyForMethodGenerator.cs | 8 ++- .../CreateStudent.expected.txt | 71 ++++++------------- .../CreateStudent.g.cs | 71 ++++++------------- .../CreateStudent.expected.txt | 18 ++--- .../CreateStudent.g.cs | 18 ++--- .../CreateStudent.expected.txt | 18 ++--- .../CreateStudent.g.cs | 18 ++--- 8 files changed, 87 insertions(+), 140 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeBuilding/Class.cs b/src/M31.FluentApi.Generator/CodeBuilding/Class.cs index 346d4a2..8bb1d31 100644 --- a/src/M31.FluentApi.Generator/CodeBuilding/Class.cs +++ b/src/M31.FluentApi.Generator/CodeBuilding/Class.cs @@ -119,10 +119,9 @@ public CodeBuilder AppendCode(CodeBuilder codeBuilder) .BlankLine() .Append(properties) .BlankLine() - .AppendWithBlankLines(methods.Where(m => m.IsConstructor)) - .AppendWithBlankLines(methodSignatures) - .AppendWithBlankLines(methods.Where(m => !m.IsConstructor)) + .AppendWithBlankLines(methods) .AppendWithBlankLines(definitions) + .AppendWithBlankLines(methodSignatures) .CloseBlock(); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index 37773b2..1a2657a 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -46,7 +46,7 @@ protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbo // [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] // private static extern void CallWithName(Student student, string name); MethodSignature methodSignature = - MethodSignature.Create("void", callMethodName, null, true); + MethodSignature.Create(symbolInfo.ReturnType, callMethodName, null, true); methodSignature.AddModifiers("private", "static", "extern"); methodSignature.AddParameter( @@ -77,6 +77,9 @@ List BuildCallMethodCode( ReservedVariableNames reservedVariableNames, string? returnType) { + string firstArgument = $"{instancePrefix}{CodeBoard.Info.ClassInstanceName}"; + IEnumerable otherArguments = outerMethodParameters.Select(CreateArgument); + return new List() { // CallWithName(student, name); // todo: better example @@ -84,8 +87,7 @@ List BuildCallMethodCode( .Append("return ", !IsNoneOrVoid(returnType)) .Append($"{callMethodName}") .Append(symbolInfo.GenericInfo?.ParameterListInAngleBrackets) - .Append($"({instancePrefix}{CodeBoard.Info.ClassInstanceName}, ") - .Append($"{string.Join(", ", outerMethodParameters.Select(CreateArgument))});") + .Append($"({string.Join(", ", new[] { firstArgument }.Concat(otherArguments))});") .ToString(), }; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.expected.txt index a6ca1af..cdc9552 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.expected.txt @@ -6,8 +6,7 @@ #nullable enable using System.Collections.Generic; -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass; @@ -17,44 +16,6 @@ public class CreateStudent : CreateStudent.IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - private static readonly MethodInfo returnVoidMethodMethodInfo; - private static readonly MethodInfo returnIntMethodMethodInfo; - private static readonly MethodInfo returnListMethodMethodInfo; - private static readonly MethodInfo returnIntMethodWithRefParameterMethodInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - returnVoidMethodMethodInfo = typeof(Student).GetMethod( - "ReturnVoidMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnIntMethodMethodInfo = typeof(Student).GetMethod( - "ReturnIntMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnListMethodMethodInfo = typeof(Student).GetMethod( - "ReturnListMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnIntMethodWithRefParameterMethodInfo = typeof(Student).GetMethod( - "ReturnIntMethodWithRefParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string).MakeByRefType() }, - null)!; - } private CreateStudent() { @@ -69,37 +30,34 @@ public class CreateStudent : public static IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } void IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnVoidMethod() { - CreateStudent.returnVoidMethodMethodInfo.Invoke(student, new object?[] { }); + CallReturnVoidMethod(student); } int IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnIntMethod() { - return (int) CreateStudent.returnIntMethodMethodInfo.Invoke(student, new object?[] { })!; + return CallReturnIntMethod(student); } System.Collections.Generic.List IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnListMethod() { - return (System.Collections.Generic.List) CreateStudent.returnListMethodMethodInfo.Invoke(student, new object?[] { })!; + return CallReturnListMethod(student); } int IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnIntMethodWithRefParameter(ref string s) { - object?[] args = new object?[] { s }; - int result = (int) CreateStudent.returnIntMethodWithRefParameterMethodInfo.Invoke(student, args)!; - s = (string) args[0]!; - return result; + return CallReturnIntMethodWithRefParameter(student, ref s); } public interface ICreateStudent : IWithName @@ -121,4 +79,19 @@ public class CreateStudent : int ReturnIntMethodWithRefParameter(ref string s); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnVoidMethod")] + private static extern void CallReturnVoidMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnIntMethod")] + private static extern int CallReturnIntMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnListMethod")] + private static extern System.Collections.Generic.List CallReturnListMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnIntMethodWithRefParameter")] + private static extern int CallReturnIntMethodWithRefParameter(Student student, ref string s); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.g.cs index a6ca1af..cdc9552 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.g.cs @@ -6,8 +6,7 @@ #nullable enable using System.Collections.Generic; -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass; @@ -17,44 +16,6 @@ public class CreateStudent : CreateStudent.IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - private static readonly MethodInfo returnVoidMethodMethodInfo; - private static readonly MethodInfo returnIntMethodMethodInfo; - private static readonly MethodInfo returnListMethodMethodInfo; - private static readonly MethodInfo returnIntMethodWithRefParameterMethodInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - returnVoidMethodMethodInfo = typeof(Student).GetMethod( - "ReturnVoidMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnIntMethodMethodInfo = typeof(Student).GetMethod( - "ReturnIntMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnListMethodMethodInfo = typeof(Student).GetMethod( - "ReturnListMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnIntMethodWithRefParameterMethodInfo = typeof(Student).GetMethod( - "ReturnIntMethodWithRefParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string).MakeByRefType() }, - null)!; - } private CreateStudent() { @@ -69,37 +30,34 @@ public static ICreateStudent InitialStep() public static IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } void IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnVoidMethod() { - CreateStudent.returnVoidMethodMethodInfo.Invoke(student, new object?[] { }); + CallReturnVoidMethod(student); } int IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnIntMethod() { - return (int) CreateStudent.returnIntMethodMethodInfo.Invoke(student, new object?[] { })!; + return CallReturnIntMethod(student); } System.Collections.Generic.List IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnListMethod() { - return (System.Collections.Generic.List) CreateStudent.returnListMethodMethodInfo.Invoke(student, new object?[] { })!; + return CallReturnListMethod(student); } int IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnIntMethodWithRefParameter(ref string s) { - object?[] args = new object?[] { s }; - int result = (int) CreateStudent.returnIntMethodWithRefParameterMethodInfo.Invoke(student, args)!; - s = (string) args[0]!; - return result; + return CallReturnIntMethodWithRefParameter(student, ref s); } public interface ICreateStudent : IWithName @@ -121,4 +79,19 @@ public interface IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethod int ReturnIntMethodWithRefParameter(ref string s); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnVoidMethod")] + private static extern void CallReturnVoidMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnIntMethod")] + private static extern int CallReturnIntMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnListMethod")] + private static extern System.Collections.Generic.List CallReturnListMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnIntMethodWithRefParameter")] + private static extern int CallReturnIntMethodWithRefParameter(Student student, ref string s); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.expected.txt index 451b429..52a82c3 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.expected.txt @@ -23,15 +23,6 @@ public class CreateStudent : student = new Student(); } - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] - private static extern void CallWithName(Student student, string name); - - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] - private static extern void CallBornOn(Student student, System.DateOnly date); - - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "InSemester")] - private static extern void CallInSemester(Student student, int semester); - public static ICreateStudent InitialStep() { return new CreateStudent(); @@ -80,4 +71,13 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] + private static extern void CallWithName(Student student, string name); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Student student, System.DateOnly date); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "InSemester")] + private static extern void CallInSemester(Student student, int semester); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.g.cs index 451b429..52a82c3 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/CreateStudent.g.cs @@ -23,15 +23,6 @@ private CreateStudent() student = new Student(); } - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] - private static extern void CallWithName(Student student, string name); - - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] - private static extern void CallBornOn(Student student, System.DateOnly date); - - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "InSemester")] - private static extern void CallInSemester(Student student, int semester); - public static ICreateStudent InitialStep() { return new CreateStudent(); @@ -80,4 +71,13 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] + private static extern void CallWithName(Student student, string name); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Student student, System.DateOnly date); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "InSemester")] + private static extern void CallInSemester(Student student, int semester); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt index 12b74e8..e6fc7ae 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt @@ -23,15 +23,6 @@ public class CreateStudent : student = new Student(); } - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] - private static extern void SetName(Student student, string value); - - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] - private static extern void SetDateOfBirth(Student student, System.DateOnly value); - - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] - private static extern void SetSemester(Student student, int value); - public static ICreateStudent InitialStep() { return new CreateStudent(); @@ -80,4 +71,13 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Student student, System.DateOnly value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs index 12b74e8..e6fc7ae 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs @@ -23,15 +23,6 @@ private CreateStudent() student = new Student(); } - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] - private static extern void SetName(Student student, string value); - - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] - private static extern void SetDateOfBirth(Student student, System.DateOnly value); - - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] - private static extern void SetSemester(Student student, int value); - public static ICreateStudent InitialStep() { return new CreateStudent(); @@ -80,4 +71,13 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Student student, System.DateOnly value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); } \ No newline at end of file From 5062217964d1880229ef26d0f8997a7833b01bd7 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 09:48:30 +0100 Subject: [PATCH 11/67] test: PrivateConstructorClass --- .../CodeBuilding/MethodSignature.cs | 4 +- .../BuilderStepMethod.cs | 11 +- .../Commons/CodeBuildingHelpers.cs | 22 ++++ .../CodeBoardActors/ConstructorGenerator.cs | 101 ++++++++++++++---- .../InnerBodyForMemberGenerator.cs | 12 +-- .../InnerBodyForMethodGenerator.cs | 23 ++-- .../CodeBoardElements/ParameterSymbolInfo.cs | 5 + .../SourceGenerators/ClassInfoFactory.cs | 4 +- .../SourceGenerators/ConstructorInfo.cs | 9 +- .../SourceGenerators/SymbolInfoCreator.cs | 33 ++++-- .../CreateStudent.expected.txt | 7 +- .../CreateStudent.g.cs | 7 +- 12 files changed, 169 insertions(+), 69 deletions(-) create mode 100644 src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/CodeBuildingHelpers.cs diff --git a/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs b/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs index 708a4a3..3f7e9b9 100644 --- a/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs +++ b/src/M31.FluentApi.Generator/CodeBuilding/MethodSignature.cs @@ -34,9 +34,9 @@ internal static MethodSignature Create( string returnType, string methodName, string? prefix, - bool isSignatureForInterface) + bool isStandaloneSignature) { - return new MethodSignature(returnType, methodName, prefix, isSignatureForInterface); + return new MethodSignature(returnType, methodName, prefix, isStandaloneSignature); } internal static MethodSignature CreateConstructorSignature(string className) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/BuilderMethodsGeneration/BuilderStepMethod.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/BuilderMethodsGeneration/BuilderStepMethod.cs index 076647c..c436c92 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/BuilderMethodsGeneration/BuilderStepMethod.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/BuilderMethodsGeneration/BuilderStepMethod.cs @@ -50,16 +50,7 @@ private MethodSignature CreateMethodSignature( MethodSignature signature = MethodSignature.Create(returnType, MethodName, explicitInterfacePrefix, false); signature.AddModifiers(modifiers); - - if (GenericInfo != null) - { - foreach (GenericTypeParameter genericTypeParameter in GenericInfo.Parameters) - { - signature.AddGenericParameter( - genericTypeParameter.ParameterName, - genericTypeParameter.Constraints.GetConstraintsForCodeGeneration()); - } - } + CodeBuildingHelpers.AddGenericParameters(signature, GenericInfo); foreach (Parameter parameter in Parameters) { diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/CodeBuildingHelpers.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/CodeBuildingHelpers.cs new file mode 100644 index 0000000..ad072c6 --- /dev/null +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/CodeBuildingHelpers.cs @@ -0,0 +1,22 @@ +using M31.FluentApi.Generator.CodeBuilding; +using M31.FluentApi.Generator.SourceGenerators.Generics; + +namespace M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.Commons; + +internal static class CodeBuildingHelpers +{ + internal static void AddGenericParameters(MethodSignature methodSignature, GenericInfo? genericInfo) + { + if (genericInfo == null) + { + return; + } + + foreach (GenericTypeParameter genericTypeParameter in genericInfo.Parameters) + { + methodSignature.AddGenericParameter( + genericTypeParameter.ParameterName, + genericTypeParameter.Constraints.GetConstraintsForCodeGeneration()); + } + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs index c7d4948..5cdda7e 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs @@ -1,5 +1,7 @@ using M31.FluentApi.Generator.CodeBuilding; +using M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.Commons; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; +using M31.FluentApi.Generator.SourceGenerators; namespace M31.FluentApi.Generator.CodeGeneration.CodeBoardActors; @@ -11,40 +13,63 @@ public void Modify(CodeBoard codeBoard) string classNameWithTypeParameters = codeBoard.Info.FluentApiClassNameWithTypeParameters; Method constructor = CreateConstructor(codeBoard.Info.BuilderClassName); - int nofParameters = codeBoard.Info.FluentApiTypeConstructorInfo.NumberOfParameters; + ConstructorInfo constructorInfo = codeBoard.Info.FluentApiTypeConstructorInfo; if (codeBoard.Info.FluentApiTypeConstructorInfo.ConstructorIsNonPublic) { - if (nofParameters == 0) - { - // student = (Student) Activator.CreateInstance(typeof(Student), true)!; - constructor.AppendBodyLine( - $"{instanceName} = ({classNameWithTypeParameters}) " + - $"Activator.CreateInstance(typeof({classNameWithTypeParameters}), true)!;"); + string unsafeAccessorName = $"Create{codeBoard.Info.FluentApiClassName}Instance"; + MethodSignature unsafeAccessorSignature = MethodSignature.Create( + classNameWithTypeParameters, + unsafeAccessorName, + null, + true); - codeBoard.CodeFile.AddUsing("System"); - } - else + CodeBuildingHelpers.AddGenericParameters(unsafeAccessorSignature, codeBoard.Info.GenericInfo); + + List parameters = constructorInfo.ParameterInfos // todo: extract x3 + .Select(i => new Parameter( + i.TypeForCodeGeneration, + i.ParameterName, + i.DefaultValue, + i.GenericTypeParameterPosition, + new ParameterAnnotations(i.ParameterKinds))) + .ToList(); + + parameters.ForEach(unsafeAccessorSignature.AddParameter); + + unsafeAccessorSignature.AddModifiers("private", "static", "extern"); + unsafeAccessorSignature.AddAttribute("[UnsafeAccessor(UnsafeAccessorKind.Constructor)]"); + codeBoard.BuilderClass.AddMethodSignature(unsafeAccessorSignature); + codeBoard.CodeFile.AddUsing("System.Runtime.CompilerServices"); + + ReservedVariableNames reservedVariableNames = codeBoard.ReservedVariableNames.NewLocalScope(); + List requiredAssignments = new List(); + List arguments = new List(); + CodeBuilder codeBuilder = new CodeBuilder(codeBoard.NewLineString); + codeBuilder + .Append($"{instanceName} = {unsafeAccessorName}") + .Append(codeBoard.Info.GenericInfo?.ParameterListInAngleBrackets); + + foreach (ParameterSymbolInfo parameterInfo in constructorInfo.ParameterInfos) { - // student = (Student) Activator.CreateInstance(typeof(Student), BindingFlags.Instance | - // BindingFlags.NonPublic, null, new object?[] { null, null }, null)!; - string parameters = - $"new object?[] {{ {string.Join(", ", Enumerable.Repeat("null", nofParameters))} }}"; - - constructor.AppendBodyLine( - $"{instanceName} = ({classNameWithTypeParameters}) " + - $"Activator.CreateInstance(" + - $"typeof({classNameWithTypeParameters}), BindingFlags.Instance | BindingFlags.NonPublic, null, {parameters}, null)!;"); - - codeBoard.CodeFile.AddUsing("System.Reflection"); - codeBoard.CodeFile.AddUsing("System"); + string argument = CreateArgument(parameterInfo, reservedVariableNames, out string? requiredAssignment); + arguments.Add(argument); + if (requiredAssignment != null) + { + requiredAssignments.Add(requiredAssignment); + } } + + codeBuilder.Append($"({string.Join(", ", arguments)});"); + requiredAssignments.ForEach(constructor.AppendBodyLine); + constructor.AppendBodyLine(codeBuilder.ToString()); + // todo: test constructor in generic class. } else { // student = new Student(default!, default!); string parameters = string.Join(", ", - Enumerable.Repeat("default!", nofParameters)); + Enumerable.Repeat("default!", constructorInfo.NumberOfParameters)); constructor.AppendBodyLine($"{instanceName} = new {classNameWithTypeParameters}({parameters});"); } @@ -52,6 +77,36 @@ public void Modify(CodeBoard codeBoard) codeBoard.BuilderClass.AddMethod(constructor); } + private static string CreateArgument( + ParameterSymbolInfo parameter, + ReservedVariableNames reservedVariableNames, + out string? requiredAssignment) + { + requiredAssignment = null; + + if (parameter.HasAnnotation(ParameterKinds.Out)) + { + return "out _"; + } + + if (parameter.HasAnnotation(ParameterKinds.Ref)) + { + string variableName = reservedVariableNames.GetNewLocalVariableName("v"); + requiredAssignment = $"var {variableName} = default!;"; + return $"ref {variableName}"; + } + + if(parameter.HasAnnotation(ParameterKinds.In)) + { + string variableName = reservedVariableNames.GetNewLocalVariableName("v"); + requiredAssignment = $"var {variableName} = default!;"; + return $"in {variableName}"; + } + + return "default!"; + // todo: test constructor with ref, in, out parameter + } + private static Method CreateConstructor(string builderClassName) { // private CreateStudent() diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs index 0c8e169..c8411fd 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs @@ -30,18 +30,18 @@ protected override void GenerateInnerBodyForPrivateSymbol(MemberSymbolInfo symbo // [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] // private static extern void SetName(Student student, string value); - MethodSignature methodSignature = + MethodSignature unsafeAccessorSignature = MethodSignature.Create("void", setMethodName, null, true); - methodSignature.AddModifiers("private", "static", "extern"); + unsafeAccessorSignature.AddModifiers("private", "static", "extern"); - methodSignature.AddParameter( + unsafeAccessorSignature.AddParameter( CodeBoard.Info.FluentApiClassNameWithTypeParameters, CodeBoard.Info.ClassInstanceName); // Student student - methodSignature.AddParameter(symbolInfo.TypeForCodeGeneration, "value"); // string value + unsafeAccessorSignature.AddParameter(symbolInfo.TypeForCodeGeneration, "value"); // string value - methodSignature.AddAttribute( + unsafeAccessorSignature.AddAttribute( $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"set_{symbolInfo.NameInPascalCase}\")]"); - CodeBoard.BuilderClass.AddMethodSignature(methodSignature); + CodeBoard.BuilderClass.AddMethodSignature(unsafeAccessorSignature); // SetName(createStudent.student, name); SetMemberCode setMemberCode = diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index 1a2657a..561e87e 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -2,6 +2,7 @@ #pragma warning disable SA1513 using M31.FluentApi.Generator.CodeBuilding; +using M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.Commons; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; using M31.FluentApi.Generator.SourceGenerators.Generics; // todo: remove if not needed @@ -33,7 +34,7 @@ List BuildCallMethodCode( .Append($"return ", !IsNoneOrVoid(returnType)) .Append($"{instancePrefix}{CodeBoard.Info.ClassInstanceName}.{symbolInfo.Name}") .Append(symbolInfo.GenericInfo?.ParameterListInAngleBrackets) - .Append($"({string.Join(", ", outerMethodParameters.Select(CreateArgument))});") + .Append($"({string.Join(", ", outerMethodParameters.Select(CreateParameter))});") .ToString(), }; } @@ -45,13 +46,14 @@ protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbo // [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] // private static extern void CallWithName(Student student, string name); - MethodSignature methodSignature = + MethodSignature unsafeAccessorSignature = MethodSignature.Create(symbolInfo.ReturnType, callMethodName, null, true); - methodSignature.AddModifiers("private", "static", "extern"); + // todo: generic constraints handled correctly for generic return type? + unsafeAccessorSignature.AddModifiers("private", "static", "extern"); - methodSignature.AddParameter( + unsafeAccessorSignature.AddParameter( new Parameter(CodeBoard.Info.FluentApiClassNameWithTypeParameters, CodeBoard.Info.ClassInstanceName)); - // todo: test generic case + CodeBuildingHelpers.AddGenericParameters(unsafeAccessorSignature, CodeBoard.Info.GenericInfo); // todo: test generic case List parameters = symbolInfo.ParameterInfos // todo: extract method from BuilderMethodFactory. .Select(i => new Parameter( @@ -62,11 +64,12 @@ protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbo new ParameterAnnotations(i.ParameterKinds))) .ToList(); - parameters.ForEach(methodSignature.AddParameter); // todo: add generic parameters + parameters.ForEach(unsafeAccessorSignature.AddParameter); + CodeBuildingHelpers.AddGenericParameters(unsafeAccessorSignature, symbolInfo.GenericInfo); - methodSignature.AddAttribute( + unsafeAccessorSignature.AddAttribute( $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"{symbolInfo.NameInPascalCase}\")]"); - CodeBoard.BuilderClass.AddMethodSignature(methodSignature); + CodeBoard.BuilderClass.AddMethodSignature(unsafeAccessorSignature); CallMethodCode callMethodCode = new CallMethodCode(BuildCallMethodCode, CodeBoard.NewLineString); CodeBoard.InnerBodyCreationDelegates.AssignCallMethodCode(symbolInfo, callMethodCode); @@ -78,7 +81,7 @@ List BuildCallMethodCode( string? returnType) { string firstArgument = $"{instancePrefix}{CodeBoard.Info.ClassInstanceName}"; - IEnumerable otherArguments = outerMethodParameters.Select(CreateArgument); + IEnumerable otherArguments = outerMethodParameters.Select(CreateParameter); return new List() { @@ -93,7 +96,7 @@ List BuildCallMethodCode( } } - private static string CreateArgument(Parameter outerMethodParameter) + private static string CreateParameter(Parameter outerMethodParameter) { // ref/in/out semester return $"{outerMethodParameter.ParameterAnnotations?.ToCallsiteAnnotations()}{outerMethodParameter.Name}"; diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/ParameterSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/ParameterSymbolInfo.cs index e6d2f13..a3a5acf 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/ParameterSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/ParameterSymbolInfo.cs @@ -32,6 +32,11 @@ internal ParameterSymbolInfo( internal ParameterKinds ParameterKinds { get; } internal bool IsGenericParameter => GenericTypeParameterPosition.HasValue; + internal bool HasAnnotation(ParameterKinds parameterKinds) + { + return ParameterKinds.HasFlag(parameterKinds); + } + protected bool Equals(ParameterSymbolInfo other) { return ParameterName == other.ParameterName && diff --git a/src/M31.FluentApi.Generator/SourceGenerators/ClassInfoFactory.cs b/src/M31.FluentApi.Generator/SourceGenerators/ClassInfoFactory.cs index 7137f75..e92149a 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/ClassInfoFactory.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/ClassInfoFactory.cs @@ -197,9 +197,7 @@ with the fewest parameters that is explicitly declared. */ return null; } - return new ConstructorInfo( - constructors[0].Parameters.Length, - constructors[0].DeclaredAccessibility != Accessibility.Public); + return SymbolInfoCreator.CreateConstructorInfo(constructors[0]); } private FluentApiInfo? TryCreateFluentApiInfo( diff --git a/src/M31.FluentApi.Generator/SourceGenerators/ConstructorInfo.cs b/src/M31.FluentApi.Generator/SourceGenerators/ConstructorInfo.cs index b7ddedb..7999fb1 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/ConstructorInfo.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/ConstructorInfo.cs @@ -1,13 +1,16 @@ +using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; + namespace M31.FluentApi.Generator.SourceGenerators; internal record ConstructorInfo { - public ConstructorInfo(int numberOfParameters, bool constructorIsNonPublic) + public ConstructorInfo(IReadOnlyCollection parameterInfos, bool constructorIsNonPublic) { - NumberOfParameters = numberOfParameters; + ParameterInfos = parameterInfos; ConstructorIsNonPublic = constructorIsNonPublic; } - internal int NumberOfParameters { get; } + internal IReadOnlyCollection ParameterInfos { get; } internal bool ConstructorIsNonPublic { get; } + internal int NumberOfParameters => ParameterInfos.Count; } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs b/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs index f8ec07f..6f35fb0 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs @@ -29,6 +29,16 @@ internal static FluentApiSymbolInfo Create(ISymbol symbol, string declaringClass }; } + internal static ConstructorInfo CreateConstructorInfo(IMethodSymbol constructor) + { + // Constructor can't be generic => genericInfo = null. + IReadOnlyCollection parameterInfos = GetParameterInfos(constructor, null); + + return new ConstructorInfo( + parameterInfos, + constructor.DeclaredAccessibility != Accessibility.Public); + } + private static MemberSymbolInfo CreateMemberSymbolInfo( IFieldSymbol fieldSymbol, string declaringClassNameWithTypeParameters) @@ -68,13 +78,6 @@ private static MethodSymbolInfo CreateMethodSymbolInfo( string declaringClassNameWithTypeParameters) { GenericInfo? genericInfo = GetGenericInfo(methodSymbol); - Dictionary typeParameterNameToTypeParameterPosition = genericInfo == null - ? new Dictionary() - : genericInfo.Parameters.ToDictionary(p => p.ParameterName, p => p.ParameterPosition); - - IReadOnlyCollection parameterInfos = - methodSymbol.Parameters.Select(p => CreateParameterSymbolInfo(p, typeParameterNameToTypeParameterPosition)) - .ToArray(); return new MethodSymbolInfo( methodSymbol.Name, @@ -82,7 +85,7 @@ private static MethodSymbolInfo CreateMethodSymbolInfo( methodSymbol.DeclaredAccessibility, PubliclyWritable(methodSymbol), genericInfo, - parameterInfos, + GetParameterInfos(methodSymbol, genericInfo), CodeTypeExtractor.GetTypeForCodeGeneration(methodSymbol.ReturnType), GetFluentSymbolComments(methodSymbol)); } @@ -92,6 +95,19 @@ private static MethodSymbolInfo CreateMethodSymbolInfo( return methodSymbol.IsGenericMethod ? GenericInfo.Create(methodSymbol.TypeParameters) : null; } + private static IReadOnlyCollection GetParameterInfos( + IMethodSymbol methodSymbol, + GenericInfo? genericInfo) + { + Dictionary typeParameterNameToTypeParameterPosition = genericInfo == null + ? new Dictionary() + : genericInfo.Parameters.ToDictionary(p => p.ParameterName, p => p.ParameterPosition); + + return methodSymbol.Parameters + .Select(p => CreateParameterSymbolInfo(p, typeParameterNameToTypeParameterPosition)) + .ToArray(); + } + private static bool PubliclyWritable(IFieldSymbol fieldSymbol) { bool isWritable = !fieldSymbol.IsReadOnly; @@ -201,6 +217,7 @@ private static ParameterKinds GetParameterKinds(IParameterSymbol parameterSymbol } private static readonly Regex fluentApiCommentStart = new Regex(@"^\s*////(?!/)", RegexOptions.Compiled); + private static Comments GetFluentSymbolComments(ISymbol symbol) { SyntaxReference? syntaxRef = symbol.DeclaringSyntaxReferences.FirstOrDefault(); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/CreateStudent.expected.txt index cc5417c..b6d9589 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateConstructorClass; @@ -17,7 +17,7 @@ public class CreateStudent : private CreateStudent() { - student = (Student) Activator.CreateInstance(typeof(Student), true)!; + student = CreateStudentInstance(); } public static ICreateStudent InitialStep() @@ -46,4 +46,7 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] + private static extern Student CreateStudentInstance(); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/CreateStudent.g.cs index cc5417c..b6d9589 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateConstructorClass; @@ -17,7 +17,7 @@ public class CreateStudent : private CreateStudent() { - student = (Student) Activator.CreateInstance(typeof(Student), true)!; + student = CreateStudentInstance(); } public static ICreateStudent InitialStep() @@ -46,4 +46,7 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] + private static extern Student CreateStudentInstance(); } \ No newline at end of file From a56072635cb1b7d553b070f3a260f9bdc33b397a Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 10:10:03 +0100 Subject: [PATCH 12/67] test: GenericClassPrivateConstructor --- .../CodeBoardActors/ConstructorGenerator.cs | 5 +---- .../CreateStudent.expected.txt | 8 +++++--- .../GenericClassPrivateConstructor/CreateStudent.g.cs | 8 +++++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs index 5cdda7e..f180045 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs @@ -24,8 +24,6 @@ public void Modify(CodeBoard codeBoard) null, true); - CodeBuildingHelpers.AddGenericParameters(unsafeAccessorSignature, codeBoard.Info.GenericInfo); - List parameters = constructorInfo.ParameterInfos // todo: extract x3 .Select(i => new Parameter( i.TypeForCodeGeneration, @@ -47,8 +45,7 @@ public void Modify(CodeBoard codeBoard) List arguments = new List(); CodeBuilder codeBuilder = new CodeBuilder(codeBoard.NewLineString); codeBuilder - .Append($"{instanceName} = {unsafeAccessorName}") - .Append(codeBoard.Info.GenericInfo?.ParameterListInAngleBrackets); + .Append($"{instanceName} = {unsafeAccessorName}"); foreach (ParameterSymbolInfo parameterInfo in constructorInfo.ParameterInfos) { diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/CreateStudent.expected.txt index aeee832..8435f14 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/CreateStudent.expected.txt @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; -using System; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassPrivateConstructor; @@ -18,7 +17,7 @@ public class CreateStudent : private CreateStudent() { - student = (Student) Activator.CreateInstance(typeof(Student), BindingFlags.Instance | BindingFlags.NonPublic, null, new object?[] { null, null }, null)!; + student = CreateStudentInstance(default!, default!); } public static ICreateStudent InitialStep() @@ -62,4 +61,7 @@ public class CreateStudent : Student WithProperty2(T2 property2); } + + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] + private static extern Student CreateStudentInstance(T1 property1, T2 property2); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/CreateStudent.g.cs index aeee832..8435f14 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/CreateStudent.g.cs @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; -using System; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassPrivateConstructor; @@ -18,7 +17,7 @@ public class CreateStudent : private CreateStudent() { - student = (Student) Activator.CreateInstance(typeof(Student), BindingFlags.Instance | BindingFlags.NonPublic, null, new object?[] { null, null }, null)!; + student = CreateStudentInstance(default!, default!); } public static ICreateStudent InitialStep() @@ -62,4 +61,7 @@ public interface IWithProperty1WithProperty2 Student WithProperty2(T2 property2); } + + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] + private static extern Student CreateStudentInstance(T1 property1, T2 property2); } \ No newline at end of file From a958c7688b63c77f466b8cc41ecd699523cbbd43 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 10:12:55 +0100 Subject: [PATCH 13/67] test: ThreeMemberRecordPrimaryConstructor --- .../CreateStudent.expected.txt | 29 +++++++++---------- .../CreateStudent.g.cs | 29 +++++++++---------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt index 5e768fa..1c7cbcf 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt @@ -7,7 +7,7 @@ using System; using System.Reflection.Metadata; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor; @@ -18,16 +18,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - private static readonly PropertyInfo semesterPropertyInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("name", BindingFlags.Instance | BindingFlags.Public)!; - dateOfBirthPropertyInfo = typeof(Student).GetProperty("dateOfBirth", BindingFlags.Instance | BindingFlags.Public)!; - semesterPropertyInfo = typeof(Student).GetProperty("semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -42,25 +32,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.dateOfBirthPropertyInfo.SetValue(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -82,4 +72,13 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Student student, System.DateOnly value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs index 5e768fa..1c7cbcf 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs @@ -7,7 +7,7 @@ using System; using System.Reflection.Metadata; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor; @@ -18,16 +18,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - private static readonly PropertyInfo semesterPropertyInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("name", BindingFlags.Instance | BindingFlags.Public)!; - dateOfBirthPropertyInfo = typeof(Student).GetProperty("dateOfBirth", BindingFlags.Instance | BindingFlags.Public)!; - semesterPropertyInfo = typeof(Student).GetProperty("semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -42,25 +32,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.dateOfBirthPropertyInfo.SetValue(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -82,4 +72,13 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Student student, System.DateOnly value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); } \ No newline at end of file From a55103b3e56a78d2f86ed518c6edffa652381b09 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 10:23:03 +0100 Subject: [PATCH 14/67] test: CanExecuteThreeMemberRecordPrimaryConstructor --- .../CreateStudent.g.cs | 9 ++++---- .../UsageTest.cs | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs index 1c7cbcf..941508c 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs @@ -6,7 +6,6 @@ #nullable enable using System; -using System.Reflection.Metadata; using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor; @@ -73,12 +72,12 @@ public interface IInSemester Student InSemester(int semester); } - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_name")] private static extern void SetName(Student student, string value); - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] - private static extern void SetDateOfBirth(Student student, System.DateOnly value); + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_dateOfBirth")] + private static extern void SetDateOfBirth(Student student, DateOnly value); - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_semester")] private static extern void SetSemester(Student student, int value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs new file mode 100644 index 0000000..8e51d39 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs @@ -0,0 +1,23 @@ +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor; + +public class CodeGenerationTests +{ + [Fact, Priority(1)] + public void CanExecuteThreeMemberRecordPrimaryConstructor() + { + var student = CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.name); + Assert.Equal(new DateOnly(2002, 8, 3), student.dateOfBirth); + Assert.Equal(2, student.semester); + } +} \ No newline at end of file From 1c3fd645da4119809ce4316287adb99f799a30dc Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 10:23:50 +0100 Subject: [PATCH 15/67] fix: ThreeMemberRecordPrimaryConstructor expected --- .../CreateStudent.expected.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt index 1c7cbcf..941508c 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt @@ -6,7 +6,6 @@ #nullable enable using System; -using System.Reflection.Metadata; using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor; @@ -73,12 +72,12 @@ public class CreateStudent : Student InSemester(int semester); } - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_name")] private static extern void SetName(Student student, string value); - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] - private static extern void SetDateOfBirth(Student student, System.DateOnly value); + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_dateOfBirth")] + private static extern void SetDateOfBirth(Student student, DateOnly value); - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_semester")] private static extern void SetSemester(Student student, int value); } \ No newline at end of file From b9f9a5fb3615276710b52521356c631ca448e7fd Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 13:28:27 +0100 Subject: [PATCH 16/67] test: ThreeMemberRecordPrimaryConstructor --- .../InnerBodyGeneration/InnerBodyForMemberGenerator.cs | 2 +- .../CreateStudent.expected.txt | 2 +- .../ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs | 2 +- .../Abstract/ThreeMemberRecordPrimaryConstructor/Student.cs | 1 - .../ThreeMemberRecordPrimaryConstructor/UsageTest.cs | 6 +++++- src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj | 1 + 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs index c8411fd..9eae26f 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs @@ -40,7 +40,7 @@ protected override void GenerateInnerBodyForPrivateSymbol(MemberSymbolInfo symbo unsafeAccessorSignature.AddParameter(symbolInfo.TypeForCodeGeneration, "value"); // string value unsafeAccessorSignature.AddAttribute( - $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"set_{symbolInfo.NameInPascalCase}\")]"); + $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"set_{symbolInfo.Name}\")]"); CodeBoard.BuilderClass.AddMethodSignature(unsafeAccessorSignature); // SetName(createStudent.student, name); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt index 941508c..b4f33f1 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt @@ -76,7 +76,7 @@ public class CreateStudent : private static extern void SetName(Student student, string value); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_dateOfBirth")] - private static extern void SetDateOfBirth(Student student, DateOnly value); + private static extern void SetDateOfBirth(Student student, System.DateOnly value); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_semester")] private static extern void SetSemester(Student student, int value); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs index 941508c..b4f33f1 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs @@ -76,7 +76,7 @@ public interface IInSemester private static extern void SetName(Student student, string value); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_dateOfBirth")] - private static extern void SetDateOfBirth(Student student, DateOnly value); + private static extern void SetDateOfBirth(Student student, System.DateOnly value); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_semester")] private static extern void SetSemester(Student student, int value); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/Student.cs index c3f25db..86c8753 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/Student.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/Student.cs @@ -3,7 +3,6 @@ // ReSharper disable All using System; -using System.Reflection.Metadata; using M31.FluentApi.Attributes; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor; diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs index 8e51d39..e03a025 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs @@ -1,3 +1,5 @@ +#if TEST_GENERATED_CODE + // ReSharper disable NotAccessedVariable using System; @@ -20,4 +22,6 @@ public void CanExecuteThreeMemberRecordPrimaryConstructor() Assert.Equal(new DateOnly(2002, 8, 3), student.dateOfBirth); Assert.Equal(2, student.semester); } -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj b/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj index d26a147..d038570 100644 --- a/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj +++ b/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj @@ -5,6 +5,7 @@ enable false M31.FluentApi.Tests + TEST_GENERATED_CODE From e93a406eace8126fdfbfb2e8af6c60e4acc24d89 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 13:50:00 +0100 Subject: [PATCH 17/67] fix: equality tests --- .../SourceGenerators/ConstructorInfo.cs | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/M31.FluentApi.Generator/SourceGenerators/ConstructorInfo.cs b/src/M31.FluentApi.Generator/SourceGenerators/ConstructorInfo.cs index 7999fb1..279ef86 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/ConstructorInfo.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/ConstructorInfo.cs @@ -1,10 +1,11 @@ using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; +using M31.FluentApi.Generator.Commons; namespace M31.FluentApi.Generator.SourceGenerators; -internal record ConstructorInfo +internal class ConstructorInfo { - public ConstructorInfo(IReadOnlyCollection parameterInfos, bool constructorIsNonPublic) + internal ConstructorInfo(IReadOnlyCollection parameterInfos, bool constructorIsNonPublic) { ParameterInfos = parameterInfos; ConstructorIsNonPublic = constructorIsNonPublic; @@ -13,4 +14,25 @@ public ConstructorInfo(IReadOnlyCollection parameterInfos, internal IReadOnlyCollection ParameterInfos { get; } internal bool ConstructorIsNonPublic { get; } internal int NumberOfParameters => ParameterInfos.Count; + + protected bool Equals(ConstructorInfo other) + { + return ParameterInfos.SequenceEqual(other.ParameterInfos) && + ConstructorIsNonPublic == other.ConstructorIsNonPublic; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((ConstructorInfo)obj); + } + + public override int GetHashCode() + { + return new HashCode() + .AddSequence(ParameterInfos) + .Add(ConstructorIsNonPublic); + } } \ No newline at end of file From ad9f6df79f0325dba8e63740c74b6ab6612dc53c Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 13:52:07 +0100 Subject: [PATCH 18/67] test: GenericClassPrivateDefaultConstructor --- .../CreateStudent.expected.txt | 7 +++++-- .../CreateStudent.g.cs | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/CreateStudent.expected.txt index 9a2b765..1c13124 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassPrivateDefaultConstructor; @@ -17,7 +17,7 @@ public class CreateStudent : private CreateStudent() { - student = (Student) Activator.CreateInstance(typeof(Student), true)!; + student = CreateStudentInstance(); } public static ICreateStudent InitialStep() @@ -61,4 +61,7 @@ public class CreateStudent : Student WithProperty2(T2 property2); } + + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] + private static extern Student CreateStudentInstance(); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/CreateStudent.g.cs index 9a2b765..1c13124 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassPrivateDefaultConstructor; @@ -17,7 +17,7 @@ public class CreateStudent : private CreateStudent() { - student = (Student) Activator.CreateInstance(typeof(Student), true)!; + student = CreateStudentInstance(); } public static ICreateStudent InitialStep() @@ -61,4 +61,7 @@ public interface IWithProperty1WithProperty2 Student WithProperty2(T2 property2); } + + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] + private static extern Student CreateStudentInstance(); } \ No newline at end of file From 87b93d64f2fd20d7eb8a2b6517444d1987c00c26 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 13:56:51 +0100 Subject: [PATCH 19/67] wip: UsageTests --- .../UsageTests.cs | 31 +++++++++++++++++++ .../{UsageTest.cs => UsageTests.cs} | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/UsageTests.cs rename src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/{UsageTest.cs => UsageTests.cs} (95%) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/UsageTests.cs new file mode 100644 index 0000000..42ef54c --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateDefaultConstructor/UsageTests.cs @@ -0,0 +1,31 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassPrivateDefaultConstructor; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteGenericClassPrivateDefaultConstructorTest1() + { + var student = CreateStudent + .WithProperty1(22); + + Assert.Equal(22, student.Property1); + } + + [Fact, Priority(1)] + public void CanExecuteGenericClassPrivateDefaultConstructorTest2() + { + var student = CreateStudent + .WithProperty2("hello world"); + + Assert.Equal("hello world", student.Property2); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTests.cs similarity index 95% rename from src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs rename to src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTests.cs index e03a025..e3115c8 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTest.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/UsageTests.cs @@ -8,7 +8,7 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor; -public class CodeGenerationTests +public class UsageTests { [Fact, Priority(1)] public void CanExecuteThreeMemberRecordPrimaryConstructor() From 3adf104810bcf08d381e60c7897da9fefaf54a99 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 14:10:05 +0100 Subject: [PATCH 20/67] test: add GenericClassPrivateConstructor failing usage test --- .../UsageTests.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/UsageTests.cs new file mode 100644 index 0000000..d2bdbf5 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassPrivateConstructor/UsageTests.cs @@ -0,0 +1,31 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassPrivateConstructor; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteGenericClassPrivateConstructorTest1() + { + var student = CreateStudent + .WithProperty1(22); + + Assert.Equal(22, student.Property1); + } + + [Fact, Priority(1)] + public void CanExecuteGenericClassPrivateConstructorTest2() + { + var student = CreateStudent + .WithProperty2("hello world"); + + Assert.Equal("hello world", student.Property2); + } +} + +#endif \ No newline at end of file From 447ffe5c39977c1cca945616293d21981c089735 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 14:10:16 +0100 Subject: [PATCH 21/67] wip: enabled tests --- .../CodeGenerationExecutionTests.cs | 1449 ++++++++--------- .../CodeGeneration/TestDataProvider.cs | 194 +-- 2 files changed, 816 insertions(+), 827 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs index f75069f..d017bb4 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs @@ -1,730 +1,719 @@ -#define TEST_GENERATED_CODE -#if TEST_GENERATED_CODE - -// ReSharper disable NotAccessedVariable - -using System; -using System.Collections.Generic; -using System.Reflection; -using M31.FluentApi.Tests.CodeGeneration.Helpers; -using Xunit; -using Xunit.Priority; - -namespace M31.FluentApi.Tests.CodeGeneration; - -public partial class CodeGenerationTests -{ - [Fact, Priority(1)] - public void CanExecuteContinueWithInForkClass() - { - { - var student = TestClasses.Abstract.ContinueWithInForkClass - .CreateStudent - .WithMember1("1") - .WithMember2A("2A") - .WithMember3("3") - .WithMember4("4"); - - Assert.Equal("1", student.Member1); - Assert.Equal("2A", student.Member2A); - Assert.Null(student.Member2B); - Assert.Equal("3", student.Member3); - Assert.Equal("4", student.Member4); - } - { - var student = TestClasses.Abstract.ContinueWithInForkClass - .CreateStudent - .WithMember1("1") - .WithMember2B("2B") - .WithMember4("4"); - - Assert.Equal("1", student.Member1); - Assert.Null(student.Member2A); - Assert.Equal("2B", student.Member2B); - Assert.Null(student.Member3); - Assert.Equal("4", student.Member4); - } - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaClass() - { - var student = TestClasses.Abstract.FluentLambdaClass - .CreateStudent - .WithName("Alice") - .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); - - Assert.Equal("Alice", student.Name); - Assert.Equal("23", student.Address.HouseNumber); - Assert.Equal("Market Street", student.Address.Street); - Assert.Equal("San Francisco", student.Address.City); - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaCollectionClass() - { - var student = TestClasses.Abstract.FluentLambdaCollectionClass - .CreateStudent - .WithName("Alice") - .WithAddresses( - a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), - a => a.WithHouseNumber("108").WithStreet("5th Avenue").InCity("New York")); - - Assert.Equal("Alice", student.Name); - Assert.Equal(2, student.Addresses.Count); - Assert.Equal("23", student.Addresses[0].HouseNumber); - Assert.Equal("Market Street", student.Addresses[0].Street); - Assert.Equal("San Francisco", student.Addresses[0].City); - Assert.Equal("108", student.Addresses[1].HouseNumber); - Assert.Equal("5th Avenue", student.Addresses[1].Street); - Assert.Equal("New York", student.Addresses[1].City); - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaCompoundClass() - { - var student = TestClasses.Abstract.FluentLambdaCompoundClass - .CreateStudent - .WithName("Alice") - .WithDetails( - a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), - p => p.WithNumber("222-222-2222").WithUsage("CELL")); - - Assert.Equal("Alice", student.Name); - Assert.Equal("23", student.Address.HouseNumber); - Assert.Equal("Market Street", student.Address.Street); - Assert.Equal("San Francisco", student.Address.City); - Assert.Equal("222-222-2222", student.Phone.Number); - Assert.Equal("CELL", student.Phone.Usage); - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaManyCollectionsClass() - { - { - var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesE(createAddressesE: null); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.AddressesE); - } - { - var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesF(createAddressesF: _ => null); - - Assert.Single(student.AddressesF); - Assert.Null(student.AddressesF[0]); - } - { - var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesG(createAddressesG: null); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.AddressesG); - } - { - var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesG(createAddressesG: _ => null); - - Assert.Equal("Alice", student.Name); - Assert.NotNull(student.AddressesG); - Assert.Single(student.AddressesG!); - Assert.Null(student.AddressesG![0]); - } - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaManyPrivateCollectionsClass() - { - { - var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesE(createAddressesE: null); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.AddressesE); - } - { - var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesF(createAddressesF: _ => null); - - Assert.Single(student.AddressesF); - Assert.Null(student.AddressesF[0]); - } - { - var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesG(createAddressesG: null); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.AddressesG); - } - { - var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesG(createAddressesG: _ => null); - - Assert.Equal("Alice", student.Name); - Assert.NotNull(student.AddressesG); - Assert.Single(student.AddressesG!); - Assert.Null(student.AddressesG![0]); - } - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaNullablePropertyClass() - { - { - var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass - .CreateStudent - .WithName("Alice") - .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); - - Assert.Equal("Alice", student.Name); - Assert.Equal("23", student.Address!.HouseNumber); - Assert.Equal("Market Street", student.Address!.Street); - Assert.Equal("San Francisco", student.Address!.City); - } - { - var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass - .CreateStudent - .WithName("Alice") - .WithoutAddress(); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.Address); - } - { - var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass - .CreateStudent - .WithName("Alice") - .WithAddress(_ => null); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.Address); - } - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaRecursiveClass() - { - var student = TestClasses.Abstract.FluentLambdaRecursiveClass - .CreateStudent - .WithName("Alice") - .WithFriend(f => f - .WithName("Bob") - .WithFriend(f2 => f2 - .WithName("Eve") - .WithoutFriend())); - - Assert.Equal("Alice", student.Name); - Assert.Equal("Bob", student.Friend!.Name); - Assert.Equal("Eve", student.Friend!.Friend!.Name); - Assert.Null(student.Friend!.Friend!.Friend); - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaSingleStepClass() - { - var student = TestClasses.Abstract.FluentLambdaSingleStepClass - .CreateStudent - .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); - - Assert.Equal("23", student.Address.HouseNumber); - Assert.Equal("Market Street", student.Address.Street); - Assert.Equal("San Francisco", student.Address.City); - } - - [Fact, Priority(1)] - public void CanExecuteFluentMethodClass() - { - var student = TestClasses.Abstract.FluentMethodClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecuteFluentReturnMultiStepPrivateMethodsClass() - { - { - TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnVoidMethod(); - } - { - int result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnIntMethod(); - Assert.Equal(24, result); - } - { - string string1 = "string1"; - int result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnIntMethodWithRefParameter(ref string1); - Assert.Equal(28, result); - } - { - List result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnListMethod(); - Assert.Equal(new List() { 1, 2, 3 }, result); - } - } - - [Fact, Priority(1)] - public void CanExecuteFluentReturnSingleStepPrivateMethodsClass() - { - { - TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnVoidMethod(); - } - { - int result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnIntMethod(); - Assert.Equal(24, result); - } - { - string string1 = "string1"; - int result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnIntMethodWithRefParameter(ref string1); - Assert.Equal(28, result); - } - { - List result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnListMethod(); - Assert.Equal(new List() { 1, 2, 3 }, result); - } - } - - [Fact, Priority(1)] - public void CanExecuteGenericClassPrivateConstructor() - { - var student = TestClasses.Abstract.GenericClassPrivateConstructor - .CreateStudent - .WithProperty1(10); - - Assert.Equal(10, student.Property1); - Assert.Null(student.Property2); - } - - [Fact, Priority(1)] - public void CanExecuteGenericClassWithGenericMethods() - { - var student = TestClasses.Abstract.GenericClassWithGenericMethods - .CreateStudent - .WithProperty1("property1") - .WithProperty2(null) - .WithProperty3(0) - .WithProperty4(0) - .WithProperty5(0) - .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) - .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), - new List()) - .Method3, Dictionary, List>("string1"); - - string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; - Assert.Equal(expectedLogs, student.Logs); - } - - [Fact, Priority(1)] - public void CanExecuteGenericClassWithPrivateGenericMethods() - { - var student = TestClasses.Abstract.GenericClassWithPrivateGenericMethods - .CreateStudent - .WithProperty1("property1") - .WithProperty2(null) - .WithProperty3(0) - .WithProperty4(0) - .WithProperty5(0) - .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) - .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), - new List()) - .Method3, Dictionary, List>("string1"); - - string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; - Assert.Equal(expectedLogs, student.Logs); - } - - [Fact, Priority(1)] - public void CanExecuteGenericOverloadedMethodClass() - { - { - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1("string1", "string2"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); - } - { - string string1 = "string1"; - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, out string1); - Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); - } - { - int i = 0; - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(in i, "string1"); - Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); - } - { - int i = 0; - string string1 = "string1"; - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(in i, ref string1); - Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); - } - } - - [Fact, Priority(1)] - public void CanExecuteGenericOverloadedPrivateMethodClass() - { - { - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1("string1", "string2"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); - } - { - string string1 = "string1"; - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, out string1); - Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); - } - { - int i = 0; - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(in i, "string1"); - Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); - } - { - int i = 0; - string string1 = "string"; - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(in i, ref string1); - Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); - } - } - - [Fact, Priority(1)] - public void CanExecuteInheritedClass() - { - var student = TestClasses.Abstract.InheritedClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecuteInheritedClassPrivateSetters() - { - var student = TestClasses.Abstract.InheritedClassPrivateSetters - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(22, student.Age); - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecuteInheritedClassProtectedMembers() - { - var student = TestClasses.Abstract.InheritedClassProtectedMembers - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", GetProperty("Name")); - Assert.Equal(new DateOnly(2002, 8, 3), GetProperty("DateOfBirth")); - Assert.Equal(2, GetProperty("Semester")); - - object GetProperty(string propertyName) - { - return typeof(TestClasses.Abstract.InheritedClassProtectedMembers.Student) - .GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic)? - .GetValue(student)!; - } - } - - [Fact, Priority(1)] - public void CanExecuteInheritedClassProtectedSetters() - { - var student = TestClasses.Abstract.InheritedClassProtectedSetters - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecuteInheritedRecord() - { - var student = TestClasses.Abstract.InheritedRecord - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecutePartialClass() - { - var student = TestClasses.Abstract.PartialClass - .CreateStudent - .WithFirstName("Alice") - .WithLastName("King"); - - Assert.Equal("Alice", student.FirstName); - Assert.Equal("King", student.LastName); - } - - [Fact, Priority(1)] - public void CanExecutePrivateConstructorClass() - { - var student = TestClasses.Abstract.PrivateConstructorClass - .CreateStudent - .InSemester(2); - - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecutePrivateFieldClass() - { - var student = TestClasses.Abstract.PrivateFieldClass - .CreateStudent - .InSemester(2); - - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecutePrivateFluentMethodClass() - { - var student = TestClasses.Abstract.PrivateFluentMethodClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecutePrivateMethodFluentNullableParameterClass() - { - var student = TestClasses.Abstract.PrivateFluentMethodNullableParameterClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(null); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Null(student.Semester); - } - - [Fact, Priority(1)] - public void CanExecutePublicReadonlyFieldClass() - { - var student = TestClasses.Abstract.PublicReadonlyFieldClass - .CreateStudent - .InSemester(2); - - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecuteSkippableMemberClass() - { - { - var student = TestClasses.Abstract.SkippableMemberClass - .CreateStudent - .WithFirstName("Alice") - .WithMiddleName("Sophia") - .WithLastName("King"); - - Assert.Equal("Alice", student.FirstName); - Assert.Equal("Sophia", student.MiddleName); - Assert.Equal("King", student.LastName); - } - { - var student = TestClasses.Abstract.SkippableMemberClass - .CreateStudent - .WithFirstName("Alice") - .WithLastName("King"); - - Assert.Equal("Alice", student.FirstName); - Assert.Null(student.MiddleName); - Assert.Equal("King", student.LastName); - } - } - - [Fact, Priority(1)] - public void CanExecuteSkippableFirstMemberClass() - { - { - var student = TestClasses.Abstract.SkippableFirstMemberClass - .CreateStudent - .WithFirstName("Alice") - .WithLastName("King"); - - Assert.Equal("Alice", student.FirstName); - Assert.Equal("King", student.LastName); - } - { - var student = TestClasses.Abstract.SkippableFirstMemberClass - .CreateStudent - .WithLastName("King"); - - Assert.Null(student.FirstName); - Assert.Equal("King", student.LastName); - } - } - - [Fact, Priority(1)] - public void CanExecuteSkippableLoopClass() - { - var student = TestClasses.Abstract.SkippableLoopClass - .CreateStudent - .WithMember3("3") - .WithMember1("1") - .WithMember4("4"); - - Assert.Equal("1", student.Member1); - Assert.Null(student.Member2); - Assert.Equal("3", student.Member3); - Assert.Equal("4", student.Member4); - } - - [Fact, Priority(1)] - public void CanExecuteSkippableSeveralMembersClass() - { - { - var student = TestClasses.Abstract.SkippableSeveralMembersClass - .CreateStudent - .WithMember2("2") - .WithMember4("4"); - - Assert.Null(student.Member1); - Assert.Equal("2", student.Member2); - Assert.Null(student.Member3); - Assert.Equal("4", student.Member4); - } - { - var student = TestClasses.Abstract.SkippableSeveralMembersClass - .CreateStudent - .WithMember4("4"); - - Assert.Null(student.Member1); - Assert.Null(student.Member2); - Assert.Null(student.Member3); - Assert.Equal("4", student.Member4); - } - } - - [Fact, Priority(1)] - public void CanExecuteThreeMemberClass() - { - var student = TestClasses.Abstract.ThreeMemberClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecuteThreeMemberRecordPrimaryConstructor() - { - var student = TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.name); - Assert.Equal(new DateOnly(2002, 8, 3), student.dateOfBirth); - Assert.Equal(2, student.semester); - } - - [Fact, Priority(1)] - public void CanExecuteThreePrivateMembersClass() - { - var student = TestClasses.Abstract.ThreePrivateMembersClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } -} -#endif \ No newline at end of file +// #define TEST_GENERATED_CODE +// #if TEST_GENERATED_CODE +// +// // ReSharper disable NotAccessedVariable +// +// using System; +// using System.Collections.Generic; +// using System.Reflection; +// using M31.FluentApi.Tests.CodeGeneration.Helpers; +// using Xunit; +// using Xunit.Priority; +// +// namespace M31.FluentApi.Tests.CodeGeneration; +// +// public partial class CodeGenerationTests +// { +// [Fact, Priority(1)] +// public void CanExecuteContinueWithInForkClass() +// { +// { +// var student = TestClasses.Abstract.ContinueWithInForkClass +// .CreateStudent +// .WithMember1("1") +// .WithMember2A("2A") +// .WithMember3("3") +// .WithMember4("4"); +// +// Assert.Equal("1", student.Member1); +// Assert.Equal("2A", student.Member2A); +// Assert.Null(student.Member2B); +// Assert.Equal("3", student.Member3); +// Assert.Equal("4", student.Member4); +// } +// { +// var student = TestClasses.Abstract.ContinueWithInForkClass +// .CreateStudent +// .WithMember1("1") +// .WithMember2B("2B") +// .WithMember4("4"); +// +// Assert.Equal("1", student.Member1); +// Assert.Null(student.Member2A); +// Assert.Equal("2B", student.Member2B); +// Assert.Null(student.Member3); +// Assert.Equal("4", student.Member4); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentLambdaClass() +// { +// var student = TestClasses.Abstract.FluentLambdaClass +// .CreateStudent +// .WithName("Alice") +// .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal("23", student.Address.HouseNumber); +// Assert.Equal("Market Street", student.Address.Street); +// Assert.Equal("San Francisco", student.Address.City); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentLambdaCollectionClass() +// { +// var student = TestClasses.Abstract.FluentLambdaCollectionClass +// .CreateStudent +// .WithName("Alice") +// .WithAddresses( +// a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), +// a => a.WithHouseNumber("108").WithStreet("5th Avenue").InCity("New York")); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(2, student.Addresses.Count); +// Assert.Equal("23", student.Addresses[0].HouseNumber); +// Assert.Equal("Market Street", student.Addresses[0].Street); +// Assert.Equal("San Francisco", student.Addresses[0].City); +// Assert.Equal("108", student.Addresses[1].HouseNumber); +// Assert.Equal("5th Avenue", student.Addresses[1].Street); +// Assert.Equal("New York", student.Addresses[1].City); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentLambdaCompoundClass() +// { +// var student = TestClasses.Abstract.FluentLambdaCompoundClass +// .CreateStudent +// .WithName("Alice") +// .WithDetails( +// a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), +// p => p.WithNumber("222-222-2222").WithUsage("CELL")); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal("23", student.Address.HouseNumber); +// Assert.Equal("Market Street", student.Address.Street); +// Assert.Equal("San Francisco", student.Address.City); +// Assert.Equal("222-222-2222", student.Phone.Number); +// Assert.Equal("CELL", student.Phone.Usage); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentLambdaManyCollectionsClass() +// { +// { +// var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass +// .CreateStudent +// .WithName("Alice") +// .WithAddressesE(createAddressesE: null); +// +// Assert.Equal("Alice", student.Name); +// Assert.Null(student.AddressesE); +// } +// { +// var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass +// .CreateStudent +// .WithName("Alice") +// .WithAddressesF(createAddressesF: _ => null); +// +// Assert.Single(student.AddressesF); +// Assert.Null(student.AddressesF[0]); +// } +// { +// var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass +// .CreateStudent +// .WithName("Alice") +// .WithAddressesG(createAddressesG: null); +// +// Assert.Equal("Alice", student.Name); +// Assert.Null(student.AddressesG); +// } +// { +// var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass +// .CreateStudent +// .WithName("Alice") +// .WithAddressesG(createAddressesG: _ => null); +// +// Assert.Equal("Alice", student.Name); +// Assert.NotNull(student.AddressesG); +// Assert.Single(student.AddressesG!); +// Assert.Null(student.AddressesG![0]); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentLambdaManyPrivateCollectionsClass() +// { +// { +// var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass +// .CreateStudent +// .WithName("Alice") +// .WithAddressesE(createAddressesE: null); +// +// Assert.Equal("Alice", student.Name); +// Assert.Null(student.AddressesE); +// } +// { +// var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass +// .CreateStudent +// .WithName("Alice") +// .WithAddressesF(createAddressesF: _ => null); +// +// Assert.Single(student.AddressesF); +// Assert.Null(student.AddressesF[0]); +// } +// { +// var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass +// .CreateStudent +// .WithName("Alice") +// .WithAddressesG(createAddressesG: null); +// +// Assert.Equal("Alice", student.Name); +// Assert.Null(student.AddressesG); +// } +// { +// var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass +// .CreateStudent +// .WithName("Alice") +// .WithAddressesG(createAddressesG: _ => null); +// +// Assert.Equal("Alice", student.Name); +// Assert.NotNull(student.AddressesG); +// Assert.Single(student.AddressesG!); +// Assert.Null(student.AddressesG![0]); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentLambdaNullablePropertyClass() +// { +// { +// var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass +// .CreateStudent +// .WithName("Alice") +// .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal("23", student.Address!.HouseNumber); +// Assert.Equal("Market Street", student.Address!.Street); +// Assert.Equal("San Francisco", student.Address!.City); +// } +// { +// var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass +// .CreateStudent +// .WithName("Alice") +// .WithoutAddress(); +// +// Assert.Equal("Alice", student.Name); +// Assert.Null(student.Address); +// } +// { +// var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass +// .CreateStudent +// .WithName("Alice") +// .WithAddress(_ => null); +// +// Assert.Equal("Alice", student.Name); +// Assert.Null(student.Address); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentLambdaRecursiveClass() +// { +// var student = TestClasses.Abstract.FluentLambdaRecursiveClass +// .CreateStudent +// .WithName("Alice") +// .WithFriend(f => f +// .WithName("Bob") +// .WithFriend(f2 => f2 +// .WithName("Eve") +// .WithoutFriend())); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal("Bob", student.Friend!.Name); +// Assert.Equal("Eve", student.Friend!.Friend!.Name); +// Assert.Null(student.Friend!.Friend!.Friend); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentLambdaSingleStepClass() +// { +// var student = TestClasses.Abstract.FluentLambdaSingleStepClass +// .CreateStudent +// .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); +// +// Assert.Equal("23", student.Address.HouseNumber); +// Assert.Equal("Market Street", student.Address.Street); +// Assert.Equal("San Francisco", student.Address.City); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentMethodClass() +// { +// var student = TestClasses.Abstract.FluentMethodClass +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); +// Assert.Equal(2, student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentReturnMultiStepPrivateMethodsClass() +// { +// { +// TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass +// .CreateStudent.WithName("Alice").ReturnVoidMethod(); +// } +// { +// int result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass +// .CreateStudent.WithName("Alice").ReturnIntMethod(); +// Assert.Equal(24, result); +// } +// { +// string string1 = "string1"; +// int result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass +// .CreateStudent.WithName("Alice").ReturnIntMethodWithRefParameter(ref string1); +// Assert.Equal(28, result); +// } +// { +// List result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass +// .CreateStudent.WithName("Alice").ReturnListMethod(); +// Assert.Equal(new List() { 1, 2, 3 }, result); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteFluentReturnSingleStepPrivateMethodsClass() +// { +// { +// TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass +// .CreateStudent.ReturnVoidMethod(); +// } +// { +// int result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass +// .CreateStudent.ReturnIntMethod(); +// Assert.Equal(24, result); +// } +// { +// string string1 = "string1"; +// int result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass +// .CreateStudent.ReturnIntMethodWithRefParameter(ref string1); +// Assert.Equal(28, result); +// } +// { +// List result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass +// .CreateStudent.ReturnListMethod(); +// Assert.Equal(new List() { 1, 2, 3 }, result); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteGenericClassWithGenericMethods() +// { +// var student = TestClasses.Abstract.GenericClassWithGenericMethods +// .CreateStudent +// .WithProperty1("property1") +// .WithProperty2(null) +// .WithProperty3(0) +// .WithProperty4(0) +// .WithProperty5(0) +// .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) +// .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), +// new List()) +// .Method3, Dictionary, List>("string1"); +// +// string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; +// Assert.Equal(expectedLogs, student.Logs); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteGenericClassWithPrivateGenericMethods() +// { +// var student = TestClasses.Abstract.GenericClassWithPrivateGenericMethods +// .CreateStudent +// .WithProperty1("property1") +// .WithProperty2(null) +// .WithProperty3(0) +// .WithProperty4(0) +// .WithProperty5(0) +// .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) +// .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), +// new List()) +// .Method3, Dictionary, List>("string1"); +// +// string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; +// Assert.Equal(expectedLogs, student.Logs); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteGenericOverloadedMethodClass() +// { +// { +// var student = TestClasses.Abstract.GenericOverloadedMethodClass +// .CreateStudent.Method1(0, "string1"); +// Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); +// } +// { +// var student = TestClasses.Abstract.GenericOverloadedMethodClass +// .CreateStudent.Method1(0, "string1"); +// Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); +// } +// { +// var student = TestClasses.Abstract.GenericOverloadedMethodClass +// .CreateStudent.Method1("string1", "string2"); +// Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); +// } +// { +// var student = TestClasses.Abstract.GenericOverloadedMethodClass +// .CreateStudent.Method1(0, "string1"); +// Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); +// } +// { +// string string1 = "string1"; +// var student = TestClasses.Abstract.GenericOverloadedMethodClass +// .CreateStudent.Method1(0, out string1); +// Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); +// } +// { +// int i = 0; +// var student = TestClasses.Abstract.GenericOverloadedMethodClass +// .CreateStudent.Method1(in i, "string1"); +// Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); +// } +// { +// int i = 0; +// string string1 = "string1"; +// var student = TestClasses.Abstract.GenericOverloadedMethodClass +// .CreateStudent.Method1(in i, ref string1); +// Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteGenericOverloadedPrivateMethodClass() +// { +// { +// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass +// .CreateStudent.Method1(0, "string1"); +// Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); +// } +// { +// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass +// .CreateStudent.Method1(0, "string1"); +// Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); +// } +// { +// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass +// .CreateStudent.Method1("string1", "string2"); +// Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); +// } +// { +// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass +// .CreateStudent.Method1(0, "string1"); +// Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); +// } +// { +// string string1 = "string1"; +// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass +// .CreateStudent.Method1(0, out string1); +// Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); +// } +// { +// int i = 0; +// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass +// .CreateStudent.Method1(in i, "string1"); +// Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); +// } +// { +// int i = 0; +// string string1 = "string"; +// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass +// .CreateStudent.Method1(in i, ref string1); +// Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteInheritedClass() +// { +// var student = TestClasses.Abstract.InheritedClass +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); +// Assert.Equal(2, student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteInheritedClassPrivateSetters() +// { +// var student = TestClasses.Abstract.InheritedClassPrivateSetters +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(22, student.Age); +// Assert.Equal(2, student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteInheritedClassProtectedMembers() +// { +// var student = TestClasses.Abstract.InheritedClassProtectedMembers +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", GetProperty("Name")); +// Assert.Equal(new DateOnly(2002, 8, 3), GetProperty("DateOfBirth")); +// Assert.Equal(2, GetProperty("Semester")); +// +// object GetProperty(string propertyName) +// { +// return typeof(TestClasses.Abstract.InheritedClassProtectedMembers.Student) +// .GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic)? +// .GetValue(student)!; +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteInheritedClassProtectedSetters() +// { +// var student = TestClasses.Abstract.InheritedClassProtectedSetters +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); +// Assert.Equal(2, student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteInheritedRecord() +// { +// var student = TestClasses.Abstract.InheritedRecord +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); +// Assert.Equal(2, student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecutePartialClass() +// { +// var student = TestClasses.Abstract.PartialClass +// .CreateStudent +// .WithFirstName("Alice") +// .WithLastName("King"); +// +// Assert.Equal("Alice", student.FirstName); +// Assert.Equal("King", student.LastName); +// } +// +// [Fact, Priority(1)] +// public void CanExecutePrivateConstructorClass() +// { +// var student = TestClasses.Abstract.PrivateConstructorClass +// .CreateStudent +// .InSemester(2); +// +// Assert.Equal(2, student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecutePrivateFieldClass() +// { +// var student = TestClasses.Abstract.PrivateFieldClass +// .CreateStudent +// .InSemester(2); +// +// Assert.Equal(2, student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecutePrivateFluentMethodClass() +// { +// var student = TestClasses.Abstract.PrivateFluentMethodClass +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); +// Assert.Equal(2, student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecutePrivateMethodFluentNullableParameterClass() +// { +// var student = TestClasses.Abstract.PrivateFluentMethodNullableParameterClass +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(null); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); +// Assert.Null(student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecutePublicReadonlyFieldClass() +// { +// var student = TestClasses.Abstract.PublicReadonlyFieldClass +// .CreateStudent +// .InSemester(2); +// +// Assert.Equal(2, student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteSkippableMemberClass() +// { +// { +// var student = TestClasses.Abstract.SkippableMemberClass +// .CreateStudent +// .WithFirstName("Alice") +// .WithMiddleName("Sophia") +// .WithLastName("King"); +// +// Assert.Equal("Alice", student.FirstName); +// Assert.Equal("Sophia", student.MiddleName); +// Assert.Equal("King", student.LastName); +// } +// { +// var student = TestClasses.Abstract.SkippableMemberClass +// .CreateStudent +// .WithFirstName("Alice") +// .WithLastName("King"); +// +// Assert.Equal("Alice", student.FirstName); +// Assert.Null(student.MiddleName); +// Assert.Equal("King", student.LastName); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteSkippableFirstMemberClass() +// { +// { +// var student = TestClasses.Abstract.SkippableFirstMemberClass +// .CreateStudent +// .WithFirstName("Alice") +// .WithLastName("King"); +// +// Assert.Equal("Alice", student.FirstName); +// Assert.Equal("King", student.LastName); +// } +// { +// var student = TestClasses.Abstract.SkippableFirstMemberClass +// .CreateStudent +// .WithLastName("King"); +// +// Assert.Null(student.FirstName); +// Assert.Equal("King", student.LastName); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteSkippableLoopClass() +// { +// var student = TestClasses.Abstract.SkippableLoopClass +// .CreateStudent +// .WithMember3("3") +// .WithMember1("1") +// .WithMember4("4"); +// +// Assert.Equal("1", student.Member1); +// Assert.Null(student.Member2); +// Assert.Equal("3", student.Member3); +// Assert.Equal("4", student.Member4); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteSkippableSeveralMembersClass() +// { +// { +// var student = TestClasses.Abstract.SkippableSeveralMembersClass +// .CreateStudent +// .WithMember2("2") +// .WithMember4("4"); +// +// Assert.Null(student.Member1); +// Assert.Equal("2", student.Member2); +// Assert.Null(student.Member3); +// Assert.Equal("4", student.Member4); +// } +// { +// var student = TestClasses.Abstract.SkippableSeveralMembersClass +// .CreateStudent +// .WithMember4("4"); +// +// Assert.Null(student.Member1); +// Assert.Null(student.Member2); +// Assert.Null(student.Member3); +// Assert.Equal("4", student.Member4); +// } +// } +// +// [Fact, Priority(1)] +// public void CanExecuteThreeMemberClass() +// { +// var student = TestClasses.Abstract.ThreeMemberClass +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); +// Assert.Equal(2, student.Semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteThreeMemberRecordPrimaryConstructor() +// { +// var student = TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", student.name); +// Assert.Equal(new DateOnly(2002, 8, 3), student.dateOfBirth); +// Assert.Equal(2, student.semester); +// } +// +// [Fact, Priority(1)] +// public void CanExecuteThreePrivateMembersClass() +// { +// var student = TestClasses.Abstract.ThreePrivateMembersClass +// .CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); +// Assert.Equal(2, student.Semester); +// } +// } +// #endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 7aa7d7a..869b8f6 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,112 +7,112 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] { }, + Filter(new string[] { "GenericClassPrivateDefaultConstructor" }, new List { - new object[] { "Abstract", "AliasNamespaceClass", "Student" }, - new object[] { "Abstract", "CollectionInterfaceMemberClass", "Student" }, - new object[] { "Abstract", "CollectionMemberClass", "Student" }, - new object[] { "Abstract", "CollectionMemberClassWithSuppression", "Student" }, - new object[] { "Abstract", "CollectionNullableArrayClass", "Student" }, - new object[] { "Abstract", "ContinueWithAfterCompoundClass", "Student" }, - new object[] { "Abstract", "ContinueWithInForkClass", "Student" }, - new object[] { "Abstract", "ContinueWithOfOverloadedMethodClass", "Student" }, - new object[] { "Abstract", "ContinueWithSelfClass", "Student" }, - new object[] { "Abstract", "CustomFluentMethodNameClass", "Student" }, - new object[] { "Abstract", "DefaultFluentMethodNameClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "CommentedCompoundClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "CommentedLambdaCollectionClass", "Student|Phone" }, - new object[] { "Abstract", "FluentApiComments", "CommentedMethodsClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClassAdvanced", "Student" }, - new object[] { "Abstract", "FluentApiComments", "IncompletelyCommentedPropertyClass", "Student"}, - new object[] { "Abstract", "FluentApiComments", "RedundantCommentCompoundClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass2", "Student" }, - new object[] { "Abstract", "EmptyClass", "Student" }, - new object[] { "Abstract", "FluentDefaultMemberClass", "Student" }, - new object[] { "Abstract", "FluentLambdaClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaClassInDifferentNamespace", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaCollectionClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaCompoundClass", "Student|Address|Phone" }, - new object[] { "Abstract", "FluentLambdaCompoundOfSameTypeClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaManyCollectionsClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaManyPrivateCollectionsClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaNullablePropertyClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaRecursiveClass", "Student" }, - new object[] { "Abstract", "FluentLambdaSingleStepClass", "Student|Address" }, - new object[] { "Abstract", "FluentMethodClass", "Student" }, - new object[] { "Abstract", "FluentMethodDefaultValuesClass", "Student" }, - new object[] { "Abstract", "FluentMethodParameterModifiersClass", "Student" }, - new object[] { "Abstract", "FluentNullableClass", "Student" }, - new object[] { "Abstract", "FluentNullableNoNullableAnnotationClass", "Student" }, - new object[] { "Abstract", "FluentNullableNoNullableAnnotationPrivateSetClass", "Student" }, - new object[] { "Abstract", "FluentReturnMultiStepClass", "Student" }, + // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, + // new object[] { "Abstract", "CollectionInterfaceMemberClass", "Student" }, + // new object[] { "Abstract", "CollectionMemberClass", "Student" }, + // new object[] { "Abstract", "CollectionMemberClassWithSuppression", "Student" }, + // new object[] { "Abstract", "CollectionNullableArrayClass", "Student" }, + // new object[] { "Abstract", "ContinueWithAfterCompoundClass", "Student" }, + // new object[] { "Abstract", "ContinueWithInForkClass", "Student" }, + // new object[] { "Abstract", "ContinueWithOfOverloadedMethodClass", "Student" }, + // new object[] { "Abstract", "ContinueWithSelfClass", "Student" }, + // new object[] { "Abstract", "CustomFluentMethodNameClass", "Student" }, + // new object[] { "Abstract", "DefaultFluentMethodNameClass", "Student" }, + // new object[] { "Abstract", "FluentApiComments", "CommentedCompoundClass", "Student" }, + // new object[] { "Abstract", "FluentApiComments", "CommentedLambdaCollectionClass", "Student|Phone" }, + // new object[] { "Abstract", "FluentApiComments", "CommentedMethodsClass", "Student" }, + // new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClass", "Student" }, + // new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClassAdvanced", "Student" }, + // new object[] { "Abstract", "FluentApiComments", "IncompletelyCommentedPropertyClass", "Student"}, + // new object[] { "Abstract", "FluentApiComments", "RedundantCommentCompoundClass", "Student" }, + // new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass", "Student" }, + // new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass2", "Student" }, + // new object[] { "Abstract", "EmptyClass", "Student" }, + // new object[] { "Abstract", "FluentDefaultMemberClass", "Student" }, + // new object[] { "Abstract", "FluentLambdaClass", "Student|Address" }, + // new object[] { "Abstract", "FluentLambdaClassInDifferentNamespace", "Student|Address" }, + // new object[] { "Abstract", "FluentLambdaCollectionClass", "Student|Address" }, + // new object[] { "Abstract", "FluentLambdaCompoundClass", "Student|Address|Phone" }, + // new object[] { "Abstract", "FluentLambdaCompoundOfSameTypeClass", "Student|Address" }, + // new object[] { "Abstract", "FluentLambdaManyCollectionsClass", "Student|Address" }, + // new object[] { "Abstract", "FluentLambdaManyPrivateCollectionsClass", "Student|Address" }, + // new object[] { "Abstract", "FluentLambdaNullablePropertyClass", "Student|Address" }, + // new object[] { "Abstract", "FluentLambdaRecursiveClass", "Student" }, + // new object[] { "Abstract", "FluentLambdaSingleStepClass", "Student|Address" }, + // new object[] { "Abstract", "FluentMethodClass", "Student" }, + // new object[] { "Abstract", "FluentMethodDefaultValuesClass", "Student" }, + // new object[] { "Abstract", "FluentMethodParameterModifiersClass", "Student" }, + // new object[] { "Abstract", "FluentNullableClass", "Student" }, + // new object[] { "Abstract", "FluentNullableNoNullableAnnotationClass", "Student" }, + // new object[] { "Abstract", "FluentNullableNoNullableAnnotationPrivateSetClass", "Student" }, + // new object[] { "Abstract", "FluentReturnMultiStepClass", "Student" }, new object[] { "Abstract", "FluentReturnMultiStepPrivateMethodsClass", "Student" }, - new object[] { "Abstract", "FluentReturnSingleStepClass", "Student" }, - new object[] { "Abstract", "FluentReturnSingleStepPrivateMethodsClass", "Student" }, - new object[] { "Abstract", "ForkClass", "Student" }, - new object[] { "Abstract", "FullyQualifiedTypeClass", "Student" }, - new object[] { "Abstract", "GenericClass", "Student" }, + // new object[] { "Abstract", "FluentReturnSingleStepClass", "Student" }, + // new object[] { "Abstract", "FluentReturnSingleStepPrivateMethodsClass", "Student" }, + // new object[] { "Abstract", "ForkClass", "Student" }, + // new object[] { "Abstract", "FullyQualifiedTypeClass", "Student" }, + // new object[] { "Abstract", "GenericClass", "Student" }, new object[] { "Abstract", "GenericClassPrivateConstructor", "Student" }, new object[] { "Abstract", "GenericClassPrivateDefaultConstructor", "Student" }, - new object[] { "Abstract", "GenericClassWithConstraints", "Student" }, - new object[] { "Abstract", "GenericClassWithGenericMethods", "Student" }, - new object[] { "Abstract", "GenericClassWithPrivateGenericMethods", "Student" }, - new object[] { "Abstract", "GenericMethodWithConstraintsClass", "Student" }, - new object[] { "Abstract", "GenericOverloadedMethodClass", "Student" }, - new object[] { "Abstract", "GenericOverloadedPrivateMethodClass", "Student" }, - new object[] { "Abstract", "GetInitPropertyClass", "Student" }, - new object[] { "Abstract", "GetPrivateInitPropertyClass", "Student" }, - new object[] { "Abstract", "GetPrivateSetPropertyClass", "Student" }, - new object[] { "Abstract", "InternalPropertyClass", "Student" }, - new object[] { "Abstract", "InheritedClass", "Student|Person" }, - new object[] { "Abstract", "InheritedClassPrivateSetters", "Student|Person" }, - new object[] { "Abstract", "InheritedClassProtectedMembers", "Student|Person" }, - new object[] { "Abstract", "InheritedClassProtectedSetters", "Student|Person" }, - new object[] { "Abstract", "InheritedRecord", "Student|Person" }, - new object[] { "Abstract", "InternalClass", "Student" }, - new object[] { "Abstract", "KeywordClass", "Student"}, - new object[] { "Abstract", "NonGenericCollectionMemberClass", "Student" }, - new object[] { "Abstract", "NullablePredicateAndCollectionClass", "Student" }, - new object[] { "Abstract", "OneMemberClass", "Student" }, - new object[] { "Abstract", "OverloadedMethodClass", "Student" }, - new object[] { "Abstract", "PartialClass", "Student1|Student2" }, - new object[] { "Abstract", "PredicateClass", "Student" }, - new object[] { "Abstract", "PredicatePrivateFieldClass", "Student" }, + // new object[] { "Abstract", "GenericClassWithConstraints", "Student" }, + // new object[] { "Abstract", "GenericClassWithGenericMethods", "Student" }, + // new object[] { "Abstract", "GenericClassWithPrivateGenericMethods", "Student" }, + // new object[] { "Abstract", "GenericMethodWithConstraintsClass", "Student" }, + // new object[] { "Abstract", "GenericOverloadedMethodClass", "Student" }, + // new object[] { "Abstract", "GenericOverloadedPrivateMethodClass", "Student" }, + // new object[] { "Abstract", "GetInitPropertyClass", "Student" }, + // new object[] { "Abstract", "GetPrivateInitPropertyClass", "Student" }, + // new object[] { "Abstract", "GetPrivateSetPropertyClass", "Student" }, + // new object[] { "Abstract", "InternalPropertyClass", "Student" }, + // new object[] { "Abstract", "InheritedClass", "Student|Person" }, + // new object[] { "Abstract", "InheritedClassPrivateSetters", "Student|Person" }, + // new object[] { "Abstract", "InheritedClassProtectedMembers", "Student|Person" }, + // new object[] { "Abstract", "InheritedClassProtectedSetters", "Student|Person" }, + // new object[] { "Abstract", "InheritedRecord", "Student|Person" }, + // new object[] { "Abstract", "InternalClass", "Student" }, + // new object[] { "Abstract", "KeywordClass", "Student"}, + // new object[] { "Abstract", "NonGenericCollectionMemberClass", "Student" }, + // new object[] { "Abstract", "NullablePredicateAndCollectionClass", "Student" }, + // new object[] { "Abstract", "OneMemberClass", "Student" }, + // new object[] { "Abstract", "OverloadedMethodClass", "Student" }, + // new object[] { "Abstract", "PartialClass", "Student1|Student2" }, + // new object[] { "Abstract", "PredicateClass", "Student" }, + // new object[] { "Abstract", "PredicatePrivateFieldClass", "Student" }, new object[] { "Abstract", "PrivateConstructorClass", "Student" }, - new object[] { "Abstract", "PrivateFieldClass", "Student" }, + // new object[] { "Abstract", "PrivateFieldClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodClass", "Student" }, - new object[] { "Abstract", "PrivateFluentMethodNullableParameterClass", "Student" }, - new object[] { "Abstract", "PrivateFluentMethodParameterModifiersClass", "Student" }, - new object[] { "Abstract", "PrivateReadonlyFieldClass", "Student" }, - new object[] { "Abstract", "PrivateUnderscoreFieldClass", "Student" }, - new object[] { "Abstract", "PublicFieldClass", "Student" }, - new object[] { "Abstract", "PublicReadonlyFieldClass", "Student" }, - new object[] { "Abstract", "SameNameMemberClass", "Student" }, - new object[] { "Abstract", "SkippableFirstMemberClass", "Student" }, - new object[] { "Abstract", "SkippableFirstTwoMembersClass", "Student" }, - new object[] { "Abstract", "SkippableForkMembersClass", "Student" }, - new object[] { "Abstract", "SkippableLoopClass", "Student" }, - new object[] { "Abstract", "SkippableMemberClass", "Student" }, - new object[] { "Abstract", "SkippableSeveralMembersClass", "Student" }, - new object[] { "Abstract", "SkippableTwoLoopsClass", "Student" }, - new object[] { "Abstract", "ThreeMemberClass", "Student" }, - new object[] { "Abstract", "ThreeMemberRecord", "Student" }, + // new object[] { "Abstract", "PrivateFluentMethodNullableParameterClass", "Student" }, + // new object[] { "Abstract", "PrivateFluentMethodParameterModifiersClass", "Student" }, + // new object[] { "Abstract", "PrivateReadonlyFieldClass", "Student" }, + // new object[] { "Abstract", "PrivateUnderscoreFieldClass", "Student" }, + // new object[] { "Abstract", "PublicFieldClass", "Student" }, + // new object[] { "Abstract", "PublicReadonlyFieldClass", "Student" }, + // new object[] { "Abstract", "SameNameMemberClass", "Student" }, + // new object[] { "Abstract", "SkippableFirstMemberClass", "Student" }, + // new object[] { "Abstract", "SkippableFirstTwoMembersClass", "Student" }, + // new object[] { "Abstract", "SkippableForkMembersClass", "Student" }, + // new object[] { "Abstract", "SkippableLoopClass", "Student" }, + // new object[] { "Abstract", "SkippableMemberClass", "Student" }, + // new object[] { "Abstract", "SkippableSeveralMembersClass", "Student" }, + // new object[] { "Abstract", "SkippableTwoLoopsClass", "Student" }, + // new object[] { "Abstract", "ThreeMemberClass", "Student" }, + // new object[] { "Abstract", "ThreeMemberRecord", "Student" }, new object[] { "Abstract", "ThreeMemberRecordPrimaryConstructor", "Student" }, - new object[] { "Abstract", "ThreeMemberStruct", "Student" }, + // new object[] { "Abstract", "ThreeMemberStruct", "Student" }, new object[] { "Abstract", "ThreePrivateMembersClass", "Student" }, - new object[] { "Abstract", "ThreeMemberRecordStruct", "Student" }, - new object[] { "Abstract", "TryBreakFluentApiClass1", "Student" }, - new object[] { "Abstract", "TryBreakFluentApiClass2", "Student" }, - new object[] { "Abstract", "TryBreakFluentApiClass3", "Student|Address" }, - new object[] { "Abstract", "TwoMemberClass", "Student" }, - new object[] { "Abstract", "TwoParameterCompoundClass", "Student" }, - new object[] { "Abstract", "TwoParameterCompoundClassReversedParameters", "Student" }, - new object[] { "DocumentedStudentClass", "DocumentedStudent" }, - new object[] { "PersonClass", "Person" }, - new object[] { "StudentClass", "Student" } + // new object[] { "Abstract", "ThreeMemberRecordStruct", "Student" }, + // new object[] { "Abstract", "TryBreakFluentApiClass1", "Student" }, + // new object[] { "Abstract", "TryBreakFluentApiClass2", "Student" }, + // new object[] { "Abstract", "TryBreakFluentApiClass3", "Student|Address" }, + // new object[] { "Abstract", "TwoMemberClass", "Student" }, + // new object[] { "Abstract", "TwoParameterCompoundClass", "Student" }, + // new object[] { "Abstract", "TwoParameterCompoundClassReversedParameters", "Student" }, + // new object[] { "DocumentedStudentClass", "DocumentedStudent" }, + // new object[] { "PersonClass", "Person" }, + // new object[] { "StudentClass", "Student" } }).Select(l => new string[] { "..", "..", "..", "CodeGeneration", "TestClasses" } .Concat(l).Reverse().ToArray()).ToList(); // reversed for better readability in the unit test panel From 358f54bc7188e81b9e0aa2b162720f2d16bb9c0f Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 14:33:41 +0100 Subject: [PATCH 22/67] chore: upgrade to .NET 10 --- .../M31.FluentApi.Generator.csproj | 2 +- .../FluentApiCommentsProviderTests.cs | 8 ++++---- .../Helpers/AnalyzerAndCodeFixVerifier.cs | 8 ++++---- src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj | 6 ++---- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj b/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj index 906b08a..bdf08f9 100644 --- a/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj +++ b/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj @@ -24,7 +24,7 @@ - + all diff --git a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs index aa17bbd..dda6f34 100644 --- a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs +++ b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs @@ -35,11 +35,11 @@ public async Task CanProvideFluentApiComments( { TestCode = source.Source.SelectSpan(selectedSpan), FixedCode = source.FixedSource!, -#if NET8_0 +#if NET10_0 ReferenceAssemblies = new ReferenceAssemblies( - "net8.0", - new PackageIdentity("Microsoft.NETCore.App.Ref", "8.0.0"), - Path.Combine("ref", "net8.0")), + "net10.0", + new PackageIdentity("Microsoft.NETCore.App.Ref", "10.0.0"), + Path.Combine("ref", "net10.0")), #else throw new NotSupportedException(); #endif diff --git a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs index e7b8415..7527afa 100644 --- a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs +++ b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs @@ -57,11 +57,11 @@ internal CodeFixTest( ExpectedDiagnostics.AddRange(expected); -#if NET8_0 +#if NET10_0 ReferenceAssemblies = new ReferenceAssemblies( - "net8.0", - new PackageIdentity("Microsoft.NETCore.App.Ref", "8.0.0"), - Path.Combine("ref", "net8.0")); + "net10.0", + new PackageIdentity("Microsoft.NETCore.App.Ref", "10.0.0"), + Path.Combine("ref", "net10.0")); #else throw new NotSupportedException(); #endif diff --git a/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj b/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj index d038570..032560c 100644 --- a/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj +++ b/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable false M31.FluentApi.Tests @@ -9,12 +9,10 @@ - - - + From 030ae48099afa2e78144a126ad26797c55c50352 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 14:41:22 +0100 Subject: [PATCH 23/67] chore(M31.FluentApi.Tests): update nuget packages --- .../AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs | 3 +-- .../Helpers/AnalyzerAndCodeFixVerifier.cs | 5 ++--- src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj | 6 +++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs index dda6f34..7cfa148 100644 --- a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs +++ b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/FluentApiCommentsProviderTests.cs @@ -4,7 +4,6 @@ using M31.FluentApi.Attributes; using M31.FluentApi.Generator.SourceAnalyzers.FluentApiComments; using Microsoft.CodeAnalysis.CSharp.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; using Xunit; using M31.FluentApi.Tests.AnalyzerAndCodeFixes.Helpers; using Microsoft.CodeAnalysis.Testing; @@ -31,7 +30,7 @@ public async Task CanProvideFluentApiComments( { SourceWithFix source = ReadSource(Path.Combine("FluentApiComments", commentTestClass), @class, $"Student.{member}.txt"); - var test = new CSharpCodeRefactoringTest + var test = new CSharpCodeRefactoringTest { TestCode = source.Source.SelectSpan(selectedSpan), FixedCode = source.FixedSource!, diff --git a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs index 7527afa..fccb500 100644 --- a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs +++ b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/Helpers/AnalyzerAndCodeFixVerifier.cs @@ -10,7 +10,6 @@ using Microsoft.CodeAnalysis.CSharp.Testing; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Testing; -using Microsoft.CodeAnalysis.Testing.Verifiers; namespace M31.FluentApi.Tests.AnalyzerAndCodeFixes.Helpers; @@ -20,7 +19,7 @@ internal static class AnalyzerAndCodeFixVerifier { internal static DiagnosticResult Diagnostic(string diagnosticId) { - return CSharpCodeFixVerifier + return CSharpCodeFixVerifier .Diagnostic(diagnosticId); } @@ -39,7 +38,7 @@ internal static async Task VerifyCodeFixAsync( await test.RunAsync(CancellationToken.None); } - private class CodeFixTest : CSharpCodeFixTest + private class CodeFixTest : CSharpCodeFixTest { internal CodeFixTest( IReadOnlyCollection sourceCode, diff --git a/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj b/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj index 032560c..ee62f48 100644 --- a/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj +++ b/src/M31.FluentApi.Tests/M31.FluentApi.Tests.csproj @@ -9,9 +9,9 @@ - - - + + + From 05e04f125be34ac5e9f62c0156cf68a9cf71fbe4 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 18:35:27 +0100 Subject: [PATCH 24/67] test: ParameterAnnotationsPublicConstructorClass / ParameterAnnotationsPrivateConstructorClass --- .../CodeBoardActors/ConstructorGenerator.cs | 59 ++++++++++------- .../CreateStudent.expected.txt | 66 +++++++++++++++++++ .../CreateStudent.g.cs | 66 +++++++++++++++++++ .../Student.cs | 24 +++++++ .../UsageTests.cs | 24 +++++++ .../CreateStudent.expected.txt | 61 +++++++++++++++++ .../CreateStudent.g.cs | 61 +++++++++++++++++ .../Student.cs | 24 +++++++ .../UsageTests.cs | 24 +++++++ .../CodeGeneration/TestDataProvider.cs | 4 +- 10 files changed, 390 insertions(+), 23 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/CreateStudent.expected.txt create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/CreateStudent.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/Student.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/CreateStudent.expected.txt create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/CreateStudent.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/Student.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/UsageTests.cs diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs index f180045..3d4c948 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs @@ -1,5 +1,4 @@ using M31.FluentApi.Generator.CodeBuilding; -using M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.Commons; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; using M31.FluentApi.Generator.SourceGenerators; @@ -17,6 +16,7 @@ public void Modify(CodeBoard codeBoard) if (codeBoard.Info.FluentApiTypeConstructorInfo.ConstructorIsNonPublic) { + // private static extern Student CreateStudentInstance(T1 property1, T2 property2); string unsafeAccessorName = $"Create{codeBoard.Info.FluentApiClassName}Instance"; MethodSignature unsafeAccessorSignature = MethodSignature.Create( classNameWithTypeParameters, @@ -40,40 +40,56 @@ public void Modify(CodeBoard codeBoard) codeBoard.BuilderClass.AddMethodSignature(unsafeAccessorSignature); codeBoard.CodeFile.AddUsing("System.Runtime.CompilerServices"); + // student = CreateStudentInstance(default!, default!); ReservedVariableNames reservedVariableNames = codeBoard.ReservedVariableNames.NewLocalScope(); - List requiredAssignments = new List(); - List arguments = new List(); - CodeBuilder codeBuilder = new CodeBuilder(codeBoard.NewLineString); - codeBuilder - .Append($"{instanceName} = {unsafeAccessorName}"); - foreach (ParameterSymbolInfo parameterInfo in constructorInfo.ParameterInfos) - { - string argument = CreateArgument(parameterInfo, reservedVariableNames, out string? requiredAssignment); - arguments.Add(argument); - if (requiredAssignment != null) - { - requiredAssignments.Add(requiredAssignment); - } - } + CodeBuilder codeBuilder = new CodeBuilder(codeBoard.NewLineString); + codeBuilder.Append($"{instanceName} = {unsafeAccessorName}"); + (List arguments, List requiredAssignments) = + GetArguments(constructorInfo.ParameterInfos, reservedVariableNames); codeBuilder.Append($"({string.Join(", ", arguments)});"); requiredAssignments.ForEach(constructor.AppendBodyLine); constructor.AppendBodyLine(codeBuilder.ToString()); - // todo: test constructor in generic class. } else { // student = new Student(default!, default!); - string parameters = string.Join(", ", - Enumerable.Repeat("default!", constructorInfo.NumberOfParameters)); - constructor.AppendBodyLine($"{instanceName} = new {classNameWithTypeParameters}({parameters});"); + ReservedVariableNames reservedVariableNames = codeBoard.ReservedVariableNames.NewLocalScope(); + CodeBuilder codeBuilder = new CodeBuilder(codeBoard.NewLineString); + codeBuilder.Append($"{instanceName} = new {classNameWithTypeParameters}"); + + (List arguments, List requiredAssignments) = + GetArguments(constructorInfo.ParameterInfos, reservedVariableNames); + codeBuilder.Append($"({string.Join(", ", arguments)});"); + requiredAssignments.ForEach(constructor.AppendBodyLine); + constructor.AppendBodyLine(codeBuilder.ToString()); } codeBoard.Constructor = constructor; codeBoard.BuilderClass.AddMethod(constructor); } + private static (List arguments, List requiredAssignments) GetArguments( + IReadOnlyCollection parameterInfos, + ReservedVariableNames reservedVariableNames) + { + List requiredAssignments = new List(); + List arguments = new List(); + + foreach (ParameterSymbolInfo parameterInfo in parameterInfos) + { + string argument = CreateArgument(parameterInfo, reservedVariableNames, out string? requiredAssignment); + arguments.Add(argument); + if (requiredAssignment != null) + { + requiredAssignments.Add(requiredAssignment); + } + } + + return (arguments, requiredAssignments); + } + private static string CreateArgument( ParameterSymbolInfo parameter, ReservedVariableNames reservedVariableNames, @@ -89,19 +105,18 @@ private static string CreateArgument( if (parameter.HasAnnotation(ParameterKinds.Ref)) { string variableName = reservedVariableNames.GetNewLocalVariableName("v"); - requiredAssignment = $"var {variableName} = default!;"; + requiredAssignment = $"{parameter.TypeForCodeGeneration} {variableName} = default!;"; return $"ref {variableName}"; } if(parameter.HasAnnotation(ParameterKinds.In)) { string variableName = reservedVariableNames.GetNewLocalVariableName("v"); - requiredAssignment = $"var {variableName} = default!;"; + requiredAssignment = $"{parameter.TypeForCodeGeneration} {variableName} = default!;"; return $"in {variableName}"; } return "default!"; - // todo: test constructor with ref, in, out parameter } private static Method CreateConstructor(string builderClassName) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/CreateStudent.expected.txt new file mode 100644 index 0000000..c29e16d --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/CreateStudent.expected.txt @@ -0,0 +1,66 @@ +// +// This code was generated by the library M31.FluentAPI. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#nullable enable + +using System.Runtime.CompilerServices; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ParameterAnnotationsPrivateConstructorClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithProperty1, + CreateStudent.IWithProperty2 +{ + private readonly Student student; + + private CreateStudent() + { + string v = default!; + int v2 = default!; + student = CreateStudentInstance(ref v, in v2, out _); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithProperty2 WithProperty1(string property1) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Property1 = property1; + return createStudent; + } + + IWithProperty2 IWithProperty1.WithProperty1(string property1) + { + student.Property1 = property1; + return this; + } + + Student IWithProperty2.WithProperty2(int property2) + { + student.Property2 = property2; + return student; + } + + public interface ICreateStudent : IWithProperty1 + { + } + + public interface IWithProperty1 + { + IWithProperty2 WithProperty1(string property1); + } + + public interface IWithProperty2 + { + Student WithProperty2(int property2); + } + + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] + private static extern Student CreateStudentInstance(ref string property1, in int property2, out double outValue); +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/CreateStudent.g.cs new file mode 100644 index 0000000..c29e16d --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/CreateStudent.g.cs @@ -0,0 +1,66 @@ +// +// This code was generated by the library M31.FluentAPI. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#nullable enable + +using System.Runtime.CompilerServices; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ParameterAnnotationsPrivateConstructorClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithProperty1, + CreateStudent.IWithProperty2 +{ + private readonly Student student; + + private CreateStudent() + { + string v = default!; + int v2 = default!; + student = CreateStudentInstance(ref v, in v2, out _); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithProperty2 WithProperty1(string property1) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Property1 = property1; + return createStudent; + } + + IWithProperty2 IWithProperty1.WithProperty1(string property1) + { + student.Property1 = property1; + return this; + } + + Student IWithProperty2.WithProperty2(int property2) + { + student.Property2 = property2; + return student; + } + + public interface ICreateStudent : IWithProperty1 + { + } + + public interface IWithProperty1 + { + IWithProperty2 WithProperty1(string property1); + } + + public interface IWithProperty2 + { + Student WithProperty2(int property2); + } + + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] + private static extern Student CreateStudentInstance(ref string property1, in int property2, out double outValue); +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/Student.cs new file mode 100644 index 0000000..221a84b --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/Student.cs @@ -0,0 +1,24 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable All + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ParameterAnnotationsPrivateConstructorClass; + +[FluentApi] +public class Student +{ + private Student(ref string property1, in int property2, out double outValue) + { + Property1 = property1; + Property2 = property2; + outValue = 1; + } + + [FluentMember(0)] + public string Property1 { get; set; } + + [FluentMember(1)] + public int Property2 { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/UsageTests.cs new file mode 100644 index 0000000..d7f7676 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPrivateConstructorClass/UsageTests.cs @@ -0,0 +1,24 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ParameterAnnotationsPrivateConstructorClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteParameterAnnotationsPrivateConstructorClass() + { + var student = CreateStudent + .WithProperty1("hello world") + .WithProperty2(42); + + Assert.Equal("hello world", student.Property1); + Assert.Equal(42, student.Property2); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/CreateStudent.expected.txt new file mode 100644 index 0000000..d0ddf81 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/CreateStudent.expected.txt @@ -0,0 +1,61 @@ +// +// This code was generated by the library M31.FluentAPI. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#nullable enable + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ParameterAnnotationsPublicConstructorClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithProperty1, + CreateStudent.IWithProperty2 +{ + private readonly Student student; + + private CreateStudent() + { + string v = default!; + int v2 = default!; + student = new Student(ref v, in v2, out _); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithProperty2 WithProperty1(string property1) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Property1 = property1; + return createStudent; + } + + IWithProperty2 IWithProperty1.WithProperty1(string property1) + { + student.Property1 = property1; + return this; + } + + Student IWithProperty2.WithProperty2(int property2) + { + student.Property2 = property2; + return student; + } + + public interface ICreateStudent : IWithProperty1 + { + } + + public interface IWithProperty1 + { + IWithProperty2 WithProperty1(string property1); + } + + public interface IWithProperty2 + { + Student WithProperty2(int property2); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/CreateStudent.g.cs new file mode 100644 index 0000000..d0ddf81 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/CreateStudent.g.cs @@ -0,0 +1,61 @@ +// +// This code was generated by the library M31.FluentAPI. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#nullable enable + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ParameterAnnotationsPublicConstructorClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithProperty1, + CreateStudent.IWithProperty2 +{ + private readonly Student student; + + private CreateStudent() + { + string v = default!; + int v2 = default!; + student = new Student(ref v, in v2, out _); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithProperty2 WithProperty1(string property1) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Property1 = property1; + return createStudent; + } + + IWithProperty2 IWithProperty1.WithProperty1(string property1) + { + student.Property1 = property1; + return this; + } + + Student IWithProperty2.WithProperty2(int property2) + { + student.Property2 = property2; + return student; + } + + public interface ICreateStudent : IWithProperty1 + { + } + + public interface IWithProperty1 + { + IWithProperty2 WithProperty1(string property1); + } + + public interface IWithProperty2 + { + Student WithProperty2(int property2); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/Student.cs new file mode 100644 index 0000000..1956deb --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/Student.cs @@ -0,0 +1,24 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable All + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ParameterAnnotationsPublicConstructorClass; + +[FluentApi] +public class Student +{ + public Student(ref string property1, in int property2, out double outValue) + { + Property1 = property1; + Property2 = property2; + outValue = 1; + } + + [FluentMember(0)] + public string Property1 { get; set; } + + [FluentMember(1)] + public int Property2 { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/UsageTests.cs new file mode 100644 index 0000000..5efdbb1 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ParameterAnnotationsPublicConstructorClass/UsageTests.cs @@ -0,0 +1,24 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ParameterAnnotationsPublicConstructorClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteParameterAnnotationsPublicConstructorClass() + { + var student = CreateStudent + .WithProperty1("hello world") + .WithProperty2(42); + + Assert.Equal("hello world", student.Property1); + Assert.Equal(42, student.Property2); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 869b8f6..f6c72c6 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] { "GenericClassPrivateDefaultConstructor" }, + Filter(new string[] { }, new List { // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -78,6 +78,8 @@ internal class TestDataProvider : IEnumerable // new object[] { "Abstract", "NullablePredicateAndCollectionClass", "Student" }, // new object[] { "Abstract", "OneMemberClass", "Student" }, // new object[] { "Abstract", "OverloadedMethodClass", "Student" }, + new object[] { "Abstract", "ParameterAnnotationsPrivateConstructorClass", "Student" }, + new object[] { "Abstract", "ParameterAnnotationsPublicConstructorClass", "Student" }, // new object[] { "Abstract", "PartialClass", "Student1|Student2" }, // new object[] { "Abstract", "PredicateClass", "Student" }, // new object[] { "Abstract", "PredicatePrivateFieldClass", "Student" }, From 3e7fb6ea78dd21c93c8726dba7049790a77722c9 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Sun, 28 Dec 2025 18:46:08 +0100 Subject: [PATCH 25/67] chore: address warnings --- .../CodeGeneration/CodeBoardActors/ConstructorGenerator.cs | 2 +- .../SourceAnalyzers/FluentApiAnalyzer.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs index 3d4c948..b4289c9 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs @@ -109,7 +109,7 @@ private static string CreateArgument( return $"ref {variableName}"; } - if(parameter.HasAnnotation(ParameterKinds.In)) + if (parameter.HasAnnotation(ParameterKinds.In)) { string variableName = reservedVariableNames.GetNewLocalVariableName("v"); requiredAssignment = $"{parameter.TypeForCodeGeneration} {variableName} = default!;"; diff --git a/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiAnalyzer.cs b/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiAnalyzer.cs index 0847f9c..5c47849 100644 --- a/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiAnalyzer.cs +++ b/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiAnalyzer.cs @@ -10,6 +10,7 @@ namespace M31.FluentApi.Generator.SourceAnalyzers; +// todo: https://github.com/dotnet/roslyn-analyzers/issues/7438 [DiagnosticAnalyzer(LanguageNames.CSharp)] internal class FluentApiAnalyzer : DiagnosticAnalyzer { From 975b547a764090554b7d8d738792acaa3977983e Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 08:55:53 +0100 Subject: [PATCH 26/67] test: PrivateFluentMethodNullableParameterClass --- .../CreateStudent.expected.txt | 47 ++++++------------- .../CreateStudent.g.cs | 47 ++++++------------- .../CodeGeneration/TestDataProvider.cs | 4 +- 3 files changed, 30 insertions(+), 68 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/CreateStudent.expected.txt index eb64caa..e4d8371 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/CreateStudent.expected.txt @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFluentMethodNullableParameterClass; @@ -17,34 +17,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly MethodInfo withNameMethodInfo; - private static readonly MethodInfo bornOnMethodInfo; - private static readonly MethodInfo inSemesterMethodInfo; - - static CreateStudent() - { - withNameMethodInfo = typeof(Student).GetMethod( - "WithName", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - bornOnMethodInfo = typeof(Student).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly?) }, - null)!; - inSemesterMethodInfo = typeof(Student).GetMethod( - "InSemester", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int?) }, - null)!; - } private CreateStudent() { @@ -59,25 +31,25 @@ public class CreateStudent : public static IBornOn WithName(string? name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.withNameMethodInfo.Invoke(createStudent.student, new object?[] { name }); + CallWithName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string? name) { - CreateStudent.withNameMethodInfo.Invoke(student, new object?[] { name }); + CallWithName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly? date) { - CreateStudent.bornOnMethodInfo.Invoke(student, new object?[] { date }); + CallBornOn(student, date); return this; } Student IInSemester.InSemester(int? semester) { - CreateStudent.inSemesterMethodInfo.Invoke(student, new object?[] { semester }); + CallInSemester(student, semester); return student; } @@ -99,4 +71,13 @@ public class CreateStudent : { Student InSemester(int? semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] + private static extern void CallWithName(Student student, string? name); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Student student, System.DateOnly? date); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "InSemester")] + private static extern void CallInSemester(Student student, int? semester); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/CreateStudent.g.cs index eb64caa..e4d8371 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFluentMethodNullableParameterClass; @@ -17,34 +17,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly MethodInfo withNameMethodInfo; - private static readonly MethodInfo bornOnMethodInfo; - private static readonly MethodInfo inSemesterMethodInfo; - - static CreateStudent() - { - withNameMethodInfo = typeof(Student).GetMethod( - "WithName", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - bornOnMethodInfo = typeof(Student).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly?) }, - null)!; - inSemesterMethodInfo = typeof(Student).GetMethod( - "InSemester", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int?) }, - null)!; - } private CreateStudent() { @@ -59,25 +31,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string? name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.withNameMethodInfo.Invoke(createStudent.student, new object?[] { name }); + CallWithName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string? name) { - CreateStudent.withNameMethodInfo.Invoke(student, new object?[] { name }); + CallWithName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly? date) { - CreateStudent.bornOnMethodInfo.Invoke(student, new object?[] { date }); + CallBornOn(student, date); return this; } Student IInSemester.InSemester(int? semester) { - CreateStudent.inSemesterMethodInfo.Invoke(student, new object?[] { semester }); + CallInSemester(student, semester); return student; } @@ -99,4 +71,13 @@ public interface IInSemester { Student InSemester(int? semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] + private static extern void CallWithName(Student student, string? name); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Student student, System.DateOnly? date); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "InSemester")] + private static extern void CallInSemester(Student student, int? semester); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index f6c72c6..df79ff1 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] { }, + Filter(new string[] {"PrivateFluentMethodNullableParameterClass" }, new List { // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -86,7 +86,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "PrivateConstructorClass", "Student" }, // new object[] { "Abstract", "PrivateFieldClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodClass", "Student" }, - // new object[] { "Abstract", "PrivateFluentMethodNullableParameterClass", "Student" }, + new object[] { "Abstract", "PrivateFluentMethodNullableParameterClass", "Student" }, // new object[] { "Abstract", "PrivateFluentMethodParameterModifiersClass", "Student" }, // new object[] { "Abstract", "PrivateReadonlyFieldClass", "Student" }, // new object[] { "Abstract", "PrivateUnderscoreFieldClass", "Student" }, From f8722cb717566b0dd2c9fa364d20d727c92fbb3e Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 09:00:10 +0100 Subject: [PATCH 27/67] refactor: extract CreateParameters method --- .../CodeBoardActors/Commons/BuilderMethodFactory.cs | 10 +--------- .../CodeBoardActors/Commons/CodeBuildingHelpers.cs | 13 +++++++++++++ .../CodeBoardActors/ConstructorGenerator.cs | 11 ++--------- .../InnerBodyForMethodGenerator.cs | 10 +--------- 4 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/BuilderMethodFactory.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/BuilderMethodFactory.cs index 0f76129..dbd3863 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/BuilderMethodFactory.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/BuilderMethodFactory.cs @@ -85,15 +85,7 @@ internal BuilderMethod CreateBuilderMethod( string methodName, bool respectReturnType) { - List parameters = methodSymbolInfo.ParameterInfos - .Select(i => new Parameter( - i.TypeForCodeGeneration, - i.ParameterName, - i.DefaultValue, - i.GenericTypeParameterPosition, - new ParameterAnnotations(i.ParameterKinds))) - .ToList(); - + List parameters = CodeBuildingHelpers.CreateParameters(methodSymbolInfo.ParameterInfos); string? returnTypeToRespect = respectReturnType ? methodSymbolInfo.ReturnType : null; List BuildBodyCode( diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/CodeBuildingHelpers.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/CodeBuildingHelpers.cs index ad072c6..d069af3 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/CodeBuildingHelpers.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/Commons/CodeBuildingHelpers.cs @@ -1,4 +1,5 @@ using M31.FluentApi.Generator.CodeBuilding; +using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; using M31.FluentApi.Generator.SourceGenerators.Generics; namespace M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.Commons; @@ -19,4 +20,16 @@ internal static void AddGenericParameters(MethodSignature methodSignature, Gener genericTypeParameter.Constraints.GetConstraintsForCodeGeneration()); } } + + internal static List CreateParameters(IReadOnlyCollection parameterInfos) + { + return parameterInfos + .Select(i => new Parameter( + i.TypeForCodeGeneration, + i.ParameterName, + i.DefaultValue, + i.GenericTypeParameterPosition, + new ParameterAnnotations(i.ParameterKinds))) + .ToList(); + } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs index b4289c9..d4979a2 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs @@ -1,4 +1,5 @@ using M31.FluentApi.Generator.CodeBuilding; +using M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.Commons; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; using M31.FluentApi.Generator.SourceGenerators; @@ -24,15 +25,7 @@ public void Modify(CodeBoard codeBoard) null, true); - List parameters = constructorInfo.ParameterInfos // todo: extract x3 - .Select(i => new Parameter( - i.TypeForCodeGeneration, - i.ParameterName, - i.DefaultValue, - i.GenericTypeParameterPosition, - new ParameterAnnotations(i.ParameterKinds))) - .ToList(); - + List parameters = CodeBuildingHelpers.CreateParameters(constructorInfo.ParameterInfos); parameters.ForEach(unsafeAccessorSignature.AddParameter); unsafeAccessorSignature.AddModifiers("private", "static", "extern"); diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index 561e87e..96a08ff 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -55,15 +55,7 @@ protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbo new Parameter(CodeBoard.Info.FluentApiClassNameWithTypeParameters, CodeBoard.Info.ClassInstanceName)); CodeBuildingHelpers.AddGenericParameters(unsafeAccessorSignature, CodeBoard.Info.GenericInfo); // todo: test generic case - List parameters = symbolInfo.ParameterInfos // todo: extract method from BuilderMethodFactory. - .Select(i => new Parameter( - i.TypeForCodeGeneration, - i.ParameterName, - i.DefaultValue, - i.GenericTypeParameterPosition, - new ParameterAnnotations(i.ParameterKinds))) - .ToList(); - + List parameters = CodeBuildingHelpers.CreateParameters(symbolInfo.ParameterInfos); parameters.ForEach(unsafeAccessorSignature.AddParameter); CodeBuildingHelpers.AddGenericParameters(unsafeAccessorSignature, symbolInfo.GenericInfo); From 185a681e5b75a6a72f8060ee86cbb012aaad44b9 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 09:07:39 +0100 Subject: [PATCH 28/67] test: PrivateFluentMethodParameterModifiersClass --- .../CodeBoardActors/ConstructorGenerator.cs | 2 + .../CreateStudent.expected.txt | 81 +++++-------------- .../CreateStudent.g.cs | 81 +++++-------------- .../CodeGeneration/TestDataProvider.cs | 4 +- 4 files changed, 48 insertions(+), 120 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs index d4979a2..4fc5c16 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs @@ -109,6 +109,8 @@ private static string CreateArgument( return $"in {variableName}"; } + // todo: test params. + return "default!"; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodParameterModifiersClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodParameterModifiersClass/CreateStudent.expected.txt index 27401ae..a2fa340 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodParameterModifiersClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodParameterModifiersClass/CreateStudent.expected.txt @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFluentMethodParameterModifiersClass; @@ -19,50 +18,6 @@ public class CreateStudent : CreateStudent.IMethodWithRefInAndOutParameter { private readonly Student student; - private static readonly MethodInfo methodWithParamsMethodInfo; - private static readonly MethodInfo methodWithRefParameterMethodInfo; - private static readonly MethodInfo methodWithInParameterMethodInfo; - private static readonly MethodInfo methodWithOutParameterMethodInfo; - private static readonly MethodInfo methodWithRefInAndOutParameterMethodInfo; - - static CreateStudent() - { - methodWithParamsMethodInfo = typeof(Student).GetMethod( - "MethodWithParams", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int[]) }, - null)!; - methodWithRefParameterMethodInfo = typeof(Student).GetMethod( - "MethodWithRefParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int).MakeByRefType() }, - null)!; - methodWithInParameterMethodInfo = typeof(Student).GetMethod( - "MethodWithInParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int).MakeByRefType() }, - null)!; - methodWithOutParameterMethodInfo = typeof(Student).GetMethod( - "MethodWithOutParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int).MakeByRefType() }, - null)!; - methodWithRefInAndOutParameterMethodInfo = typeof(Student).GetMethod( - "MethodWithRefInAndOutParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int).MakeByRefType(), typeof(int).MakeByRefType(), typeof(int).MakeByRefType() }, - null)!; - } private CreateStudent() { @@ -77,44 +32,37 @@ public class CreateStudent : public static IMethodWithRefParameter MethodWithParams(params int[] numbers) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.methodWithParamsMethodInfo.Invoke(createStudent.student, new object?[] { numbers }); + CallMethodWithParams(createStudent.student, numbers); return createStudent; } IMethodWithRefParameter IMethodWithParams.MethodWithParams(params int[] numbers) { - CreateStudent.methodWithParamsMethodInfo.Invoke(student, new object?[] { numbers }); + CallMethodWithParams(student, numbers); return this; } IMethodWithInParameter IMethodWithRefParameter.MethodWithRefParameter(ref int n1) { - object?[] args = new object?[] { n1 }; - CreateStudent.methodWithRefParameterMethodInfo.Invoke(student, args); - n1 = (int) args[0]!; + CallMethodWithRefParameter(student, ref n1); return this; } IMethodWithOutParameter IMethodWithInParameter.MethodWithInParameter(in int n2) { - CreateStudent.methodWithInParameterMethodInfo.Invoke(student, new object?[] { n2 }); + CallMethodWithInParameter(student, in n2); return this; } IMethodWithRefInAndOutParameter IMethodWithOutParameter.MethodWithOutParameter(out int n3) { - object?[] args = new object?[] { null }; - CreateStudent.methodWithOutParameterMethodInfo.Invoke(student, args); - n3 = (int) args[0]!; + CallMethodWithOutParameter(student, out n3); return this; } Student IMethodWithRefInAndOutParameter.MethodWithRefInAndOutParameter(ref int n4, in int n5, out int n6) { - object?[] args = new object?[] { n4, n5, null }; - CreateStudent.methodWithRefInAndOutParameterMethodInfo.Invoke(student, args); - n4 = (int) args[0]!; - n6 = (int) args[2]!; + CallMethodWithRefInAndOutParameter(student, ref n4, in n5, out n6); return student; } @@ -146,4 +94,19 @@ public class CreateStudent : { Student MethodWithRefInAndOutParameter(ref int n4, in int n5, out int n6); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "MethodWithParams")] + private static extern void CallMethodWithParams(Student student, params int[] numbers); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "MethodWithRefParameter")] + private static extern void CallMethodWithRefParameter(Student student, ref int n1); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "MethodWithInParameter")] + private static extern void CallMethodWithInParameter(Student student, in int n2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "MethodWithOutParameter")] + private static extern void CallMethodWithOutParameter(Student student, out int n3); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "MethodWithRefInAndOutParameter")] + private static extern void CallMethodWithRefInAndOutParameter(Student student, ref int n4, in int n5, out int n6); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodParameterModifiersClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodParameterModifiersClass/CreateStudent.g.cs index 27401ae..a2fa340 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodParameterModifiersClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodParameterModifiersClass/CreateStudent.g.cs @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFluentMethodParameterModifiersClass; @@ -19,50 +18,6 @@ public class CreateStudent : CreateStudent.IMethodWithRefInAndOutParameter { private readonly Student student; - private static readonly MethodInfo methodWithParamsMethodInfo; - private static readonly MethodInfo methodWithRefParameterMethodInfo; - private static readonly MethodInfo methodWithInParameterMethodInfo; - private static readonly MethodInfo methodWithOutParameterMethodInfo; - private static readonly MethodInfo methodWithRefInAndOutParameterMethodInfo; - - static CreateStudent() - { - methodWithParamsMethodInfo = typeof(Student).GetMethod( - "MethodWithParams", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int[]) }, - null)!; - methodWithRefParameterMethodInfo = typeof(Student).GetMethod( - "MethodWithRefParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int).MakeByRefType() }, - null)!; - methodWithInParameterMethodInfo = typeof(Student).GetMethod( - "MethodWithInParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int).MakeByRefType() }, - null)!; - methodWithOutParameterMethodInfo = typeof(Student).GetMethod( - "MethodWithOutParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int).MakeByRefType() }, - null)!; - methodWithRefInAndOutParameterMethodInfo = typeof(Student).GetMethod( - "MethodWithRefInAndOutParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int).MakeByRefType(), typeof(int).MakeByRefType(), typeof(int).MakeByRefType() }, - null)!; - } private CreateStudent() { @@ -77,44 +32,37 @@ public static ICreateStudent InitialStep() public static IMethodWithRefParameter MethodWithParams(params int[] numbers) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.methodWithParamsMethodInfo.Invoke(createStudent.student, new object?[] { numbers }); + CallMethodWithParams(createStudent.student, numbers); return createStudent; } IMethodWithRefParameter IMethodWithParams.MethodWithParams(params int[] numbers) { - CreateStudent.methodWithParamsMethodInfo.Invoke(student, new object?[] { numbers }); + CallMethodWithParams(student, numbers); return this; } IMethodWithInParameter IMethodWithRefParameter.MethodWithRefParameter(ref int n1) { - object?[] args = new object?[] { n1 }; - CreateStudent.methodWithRefParameterMethodInfo.Invoke(student, args); - n1 = (int) args[0]!; + CallMethodWithRefParameter(student, ref n1); return this; } IMethodWithOutParameter IMethodWithInParameter.MethodWithInParameter(in int n2) { - CreateStudent.methodWithInParameterMethodInfo.Invoke(student, new object?[] { n2 }); + CallMethodWithInParameter(student, in n2); return this; } IMethodWithRefInAndOutParameter IMethodWithOutParameter.MethodWithOutParameter(out int n3) { - object?[] args = new object?[] { null }; - CreateStudent.methodWithOutParameterMethodInfo.Invoke(student, args); - n3 = (int) args[0]!; + CallMethodWithOutParameter(student, out n3); return this; } Student IMethodWithRefInAndOutParameter.MethodWithRefInAndOutParameter(ref int n4, in int n5, out int n6) { - object?[] args = new object?[] { n4, n5, null }; - CreateStudent.methodWithRefInAndOutParameterMethodInfo.Invoke(student, args); - n4 = (int) args[0]!; - n6 = (int) args[2]!; + CallMethodWithRefInAndOutParameter(student, ref n4, in n5, out n6); return student; } @@ -146,4 +94,19 @@ public interface IMethodWithRefInAndOutParameter { Student MethodWithRefInAndOutParameter(ref int n4, in int n5, out int n6); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "MethodWithParams")] + private static extern void CallMethodWithParams(Student student, params int[] numbers); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "MethodWithRefParameter")] + private static extern void CallMethodWithRefParameter(Student student, ref int n1); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "MethodWithInParameter")] + private static extern void CallMethodWithInParameter(Student student, in int n2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "MethodWithOutParameter")] + private static extern void CallMethodWithOutParameter(Student student, out int n3); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "MethodWithRefInAndOutParameter")] + private static extern void CallMethodWithRefInAndOutParameter(Student student, ref int n4, in int n5, out int n6); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index df79ff1..d466451 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] {"PrivateFluentMethodNullableParameterClass" }, + Filter(new string[] {"PrivateFluentMethodParameterModifiersClass" }, new List { // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -87,7 +87,7 @@ internal class TestDataProvider : IEnumerable // new object[] { "Abstract", "PrivateFieldClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodNullableParameterClass", "Student" }, - // new object[] { "Abstract", "PrivateFluentMethodParameterModifiersClass", "Student" }, + new object[] { "Abstract", "PrivateFluentMethodParameterModifiersClass", "Student" }, // new object[] { "Abstract", "PrivateReadonlyFieldClass", "Student" }, // new object[] { "Abstract", "PrivateUnderscoreFieldClass", "Student" }, // new object[] { "Abstract", "PublicFieldClass", "Student" }, From 40ef49f2c3649e0ea3263adb136102ca3e1b707e Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 09:21:50 +0100 Subject: [PATCH 29/67] test: PrivateReadonlyFieldClass (wip) --- .../CreateStudent.expected.txt | 15 +++++------ .../CreateStudent.g.cs | 15 +++++------ .../PrivateReadonlyFieldClass/UsageTests.cs | 27 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 4 +-- 4 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt index 5834cdd..65ae324 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateReadonlyFieldClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly FieldInfo semesterFieldInfo; - - static CreateStudent() - { - semesterFieldInfo = typeof(Student).GetField("semester", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterFieldInfo.SetValue(createStudent.student, semester); + SetSemester(createStudent.student) = semester; return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterFieldInfo.SetValue(student, semester); + SetSemester(student) = semester; return student; } @@ -52,4 +46,7 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "semester")] + private static extern ref int SetSemester(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs index 5834cdd..65ae324 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateReadonlyFieldClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly FieldInfo semesterFieldInfo; - - static CreateStudent() - { - semesterFieldInfo = typeof(Student).GetField("semester", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterFieldInfo.SetValue(createStudent.student, semester); + SetSemester(createStudent.student) = semester; return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterFieldInfo.SetValue(student, semester); + SetSemester(student) = semester; return student; } @@ -52,4 +46,7 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "semester")] + private static extern ref int SetSemester(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/UsageTests.cs new file mode 100644 index 0000000..5262f34 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System.Reflection; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateReadonlyFieldClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateReadonlyFieldClass() + { + var student = CreateStudent + .InSemester(4); + + int semester = (int)typeof(Student).GetField( + "semester", + BindingFlags.Instance | BindingFlags.NonPublic) + !.GetValue(student)!; + Assert.Equal(4, semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index d466451..a29f115 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] {"PrivateFluentMethodParameterModifiersClass" }, + Filter(new string[] {"PrivateReadonlyFieldClass" }, new List { // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -88,7 +88,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "PrivateFluentMethodClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodNullableParameterClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodParameterModifiersClass", "Student" }, - // new object[] { "Abstract", "PrivateReadonlyFieldClass", "Student" }, + new object[] { "Abstract", "PrivateReadonlyFieldClass", "Student" }, // new object[] { "Abstract", "PrivateUnderscoreFieldClass", "Student" }, // new object[] { "Abstract", "PublicFieldClass", "Student" }, // new object[] { "Abstract", "PublicReadonlyFieldClass", "Student" }, From 9fc1b2bbc3323682143e3052d150087723d775d1 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 14:52:46 +0100 Subject: [PATCH 30/67] test: PrivateReadonlyFieldClass --- .../InnerBodyForMemberGenerator.cs | 39 ++++++++++++++++++- .../InnerBodyForMethodGenerator.cs | 2 +- .../CreateStudent.expected.txt | 6 +-- .../CreateStudent.g.cs | 6 +-- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs index 9eae26f..a60fce9 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs @@ -25,6 +25,18 @@ string GetPostfix(string value) } protected override void GenerateInnerBodyForPrivateSymbol(MemberSymbolInfo symbolInfo) + { + if (symbolInfo.IsProperty) + { + GenerateInnerBodyForPrivateProperty(symbolInfo); + } + else + { + GenerateInnerBodyForPrivateField(symbolInfo); + } + } + + private void GenerateInnerBodyForPrivateProperty(MemberSymbolInfo symbolInfo) { string setMethodName = $"Set{symbolInfo.NameInPascalCase}"; @@ -37,7 +49,7 @@ protected override void GenerateInnerBodyForPrivateSymbol(MemberSymbolInfo symbo unsafeAccessorSignature.AddParameter( CodeBoard.Info.FluentApiClassNameWithTypeParameters, CodeBoard.Info.ClassInstanceName); // Student student - unsafeAccessorSignature.AddParameter(symbolInfo.TypeForCodeGeneration, "value"); // string value + unsafeAccessorSignature.AddParameter(symbolInfo.TypeForCodeGeneration, "value"); unsafeAccessorSignature.AddAttribute( $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"set_{symbolInfo.Name}\")]"); @@ -49,4 +61,29 @@ protected override void GenerateInnerBodyForPrivateSymbol(MemberSymbolInfo symbo $"{setMethodName}({instancePrefix}{CodeBoard.Info.ClassInstanceName}, {value});"); CodeBoard.InnerBodyCreationDelegates.AssignSetMemberCode(symbolInfo.Name, setMemberCode); } + + private void GenerateInnerBodyForPrivateField(MemberSymbolInfo symbolInfo) + { + string getFieldName = $"{symbolInfo.NameInPascalCase}Field"; + + // [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "semester")] + // private static extern ref int SemesterField(Student student); + MethodSignature unsafeAccessorSignature = + MethodSignature.Create(symbolInfo.TypeForCodeGeneration, getFieldName, null, true); + unsafeAccessorSignature.AddModifiers("private", "static", "extern", "ref"); + + unsafeAccessorSignature.AddParameter( + CodeBoard.Info.FluentApiClassNameWithTypeParameters, + CodeBoard.Info.ClassInstanceName); // Student student + + unsafeAccessorSignature.AddAttribute( + $"[UnsafeAccessor(UnsafeAccessorKind.Field, Name = \"{symbolInfo.Name}\")]"); + CodeBoard.BuilderClass.AddMethodSignature(unsafeAccessorSignature); + + // SemesterField(createStudent.student) = semester; + SetMemberCode setMemberCode = + new SetMemberCode((instancePrefix, value) => + $"{getFieldName}({instancePrefix}{CodeBoard.Info.ClassInstanceName}) = {value};"); + CodeBoard.InnerBodyCreationDelegates.AssignSetMemberCode(symbolInfo.Name, setMemberCode); + } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index 96a08ff..a5fe8d8 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -60,7 +60,7 @@ protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbo CodeBuildingHelpers.AddGenericParameters(unsafeAccessorSignature, symbolInfo.GenericInfo); unsafeAccessorSignature.AddAttribute( - $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"{symbolInfo.NameInPascalCase}\")]"); + $"[UnsafeAccessor(UnsafeAccessorKind.Method, Name = \"{symbolInfo.Name}\")]"); CodeBoard.BuilderClass.AddMethodSignature(unsafeAccessorSignature); CallMethodCode callMethodCode = new CallMethodCode(BuildCallMethodCode, CodeBoard.NewLineString); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt index 65ae324..ab9c32e 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt @@ -28,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SetSemester(createStudent.student) = semester; + SemesterField(createStudent.student) = semester; return createStudent.student; } Student IInSemester.InSemester(int semester) { - SetSemester(student) = semester; + SemesterField(student) = semester; return student; } @@ -48,5 +48,5 @@ public class CreateStudent : } [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "semester")] - private static extern ref int SetSemester(Student student); + private static extern ref int SemesterField(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs index 65ae324..ab9c32e 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs @@ -28,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SetSemester(createStudent.student) = semester; + SemesterField(createStudent.student) = semester; return createStudent.student; } Student IInSemester.InSemester(int semester) { - SetSemester(student) = semester; + SemesterField(student) = semester; return student; } @@ -48,5 +48,5 @@ public interface IInSemester } [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "semester")] - private static extern ref int SetSemester(Student student); + private static extern ref int SemesterField(Student student); } \ No newline at end of file From efb1c1e626dc4c1d2452f1190113a9929f28c2bc Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 14:58:43 +0100 Subject: [PATCH 31/67] test: PrivateUnderscoreFieldClass --- .../InnerBodyForMethodGenerator.cs | 3 +-- .../CreateStudent.expected.txt | 15 +++++------ .../CreateStudent.g.cs | 15 +++++------ .../PrivateUnderscoreFieldClass/UsageTests.cs | 27 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 4 +-- 5 files changed, 42 insertions(+), 22 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/UsageTests.cs diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index a5fe8d8..14be277 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -53,7 +53,6 @@ protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbo unsafeAccessorSignature.AddParameter( new Parameter(CodeBoard.Info.FluentApiClassNameWithTypeParameters, CodeBoard.Info.ClassInstanceName)); - CodeBuildingHelpers.AddGenericParameters(unsafeAccessorSignature, CodeBoard.Info.GenericInfo); // todo: test generic case List parameters = CodeBuildingHelpers.CreateParameters(symbolInfo.ParameterInfos); parameters.ForEach(unsafeAccessorSignature.AddParameter); @@ -77,7 +76,7 @@ List BuildCallMethodCode( return new List() { - // CallWithName(student, name); // todo: better example + // CallWithName(student, name); CodeBoard.NewCodeBuilder() .Append("return ", !IsNoneOrVoid(returnType)) .Append($"{callMethodName}") diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.expected.txt index b1f5958..51448bc 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateUnderscoreFieldClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly FieldInfo semesterFieldInfo; - - static CreateStudent() - { - semesterFieldInfo = typeof(Student).GetField("_semester", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterFieldInfo.SetValue(createStudent.student, semester); + SemesterField(createStudent.student) = semester; return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterFieldInfo.SetValue(student, semester); + SemesterField(student) = semester; return student; } @@ -52,4 +46,7 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_semester")] + private static extern ref int SemesterField(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.g.cs index b1f5958..51448bc 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateUnderscoreFieldClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly FieldInfo semesterFieldInfo; - - static CreateStudent() - { - semesterFieldInfo = typeof(Student).GetField("_semester", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterFieldInfo.SetValue(createStudent.student, semester); + SemesterField(createStudent.student) = semester; return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterFieldInfo.SetValue(student, semester); + SemesterField(student) = semester; return student; } @@ -52,4 +46,7 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_semester")] + private static extern ref int SemesterField(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/UsageTests.cs new file mode 100644 index 0000000..9ac3c98 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System.Reflection; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateUnderscoreFieldClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateReadonlyFieldClass() + { + var student = CreateStudent + .InSemester(4); + + int semester = (int)typeof(Student).GetField( + "_semester", + BindingFlags.Instance | BindingFlags.NonPublic) + !.GetValue(student)!; + Assert.Equal(4, semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index a29f115..3b45d80 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] {"PrivateReadonlyFieldClass" }, + Filter(new string[] { "PrivateUnderscoreFieldClass" }, new List { // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -89,7 +89,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "PrivateFluentMethodNullableParameterClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodParameterModifiersClass", "Student" }, new object[] { "Abstract", "PrivateReadonlyFieldClass", "Student" }, - // new object[] { "Abstract", "PrivateUnderscoreFieldClass", "Student" }, + new object[] { "Abstract", "PrivateUnderscoreFieldClass", "Student" }, // new object[] { "Abstract", "PublicFieldClass", "Student" }, // new object[] { "Abstract", "PublicReadonlyFieldClass", "Student" }, // new object[] { "Abstract", "SameNameMemberClass", "Student" }, From 0a530921fe58020d8f07276867f04b1f7b897c21 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 15:00:00 +0100 Subject: [PATCH 32/67] test: PrivateFieldClass --- .../CreateStudent.expected.txt | 15 +++++------ .../PrivateFieldClass/CreateStudent.g.cs | 15 +++++------ .../Abstract/PrivateFieldClass/UsageTests.cs | 27 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 4 +-- 4 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.expected.txt index 66082b9..4dd5841 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFieldClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly FieldInfo semesterFieldInfo; - - static CreateStudent() - { - semesterFieldInfo = typeof(Student).GetField("semester", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterFieldInfo.SetValue(createStudent.student, semester); + SemesterField(createStudent.student) = semester; return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterFieldInfo.SetValue(student, semester); + SemesterField(student) = semester; return student; } @@ -52,4 +46,7 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "semester")] + private static extern ref int SemesterField(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.g.cs index 66082b9..4dd5841 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFieldClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly FieldInfo semesterFieldInfo; - - static CreateStudent() - { - semesterFieldInfo = typeof(Student).GetField("semester", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterFieldInfo.SetValue(createStudent.student, semester); + SemesterField(createStudent.student) = semester; return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterFieldInfo.SetValue(student, semester); + SemesterField(student) = semester; return student; } @@ -52,4 +46,7 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "semester")] + private static extern ref int SemesterField(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/UsageTests.cs new file mode 100644 index 0000000..9128bb7 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System.Reflection; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFieldClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateReadonlyFieldClass() + { + var student = CreateStudent + .InSemester(4); + + int semester = (int)typeof(Student).GetField( + "semester", + BindingFlags.Instance | BindingFlags.NonPublic) + !.GetValue(student)!; + Assert.Equal(4, semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 3b45d80..cbf0bb2 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] { "PrivateUnderscoreFieldClass" }, + Filter(new string[] { "PrivateFieldClass" }, new List { // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -84,7 +84,7 @@ internal class TestDataProvider : IEnumerable // new object[] { "Abstract", "PredicateClass", "Student" }, // new object[] { "Abstract", "PredicatePrivateFieldClass", "Student" }, new object[] { "Abstract", "PrivateConstructorClass", "Student" }, - // new object[] { "Abstract", "PrivateFieldClass", "Student" }, + new object[] { "Abstract", "PrivateFieldClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodNullableParameterClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodParameterModifiersClass", "Student" }, From 7a863e5402ad5f01a1867e96281cc7cd1d144604 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 15:02:52 +0100 Subject: [PATCH 33/67] test: PredicatePrivateFieldClass --- .../CreateStudent.expected.txt | 19 ++++++------- .../CreateStudent.g.cs | 19 ++++++------- .../PredicatePrivateFieldClass/UsageTests.cs | 27 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 4 +-- 4 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.expected.txt index da30821..deb6426 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PredicatePrivateFieldClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IWhoIsHappy { private readonly Student student; - private static readonly FieldInfo isHappyFieldInfo; - - static CreateStudent() - { - isHappyFieldInfo = typeof(Student).GetField("isHappy", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreateStudent() { @@ -34,26 +28,26 @@ public class CreateStudent : public static Student WhoIsHappy(bool isHappy = true) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.isHappyFieldInfo.SetValue(createStudent.student, isHappy); + IsHappyField(createStudent.student) = isHappy; return createStudent.student; } public static Student WhoIsSad() { CreateStudent createStudent = new CreateStudent(); - CreateStudent.isHappyFieldInfo.SetValue(createStudent.student, false); + IsHappyField(createStudent.student) = false; return createStudent.student; } Student IWhoIsHappy.WhoIsHappy(bool isHappy) { - CreateStudent.isHappyFieldInfo.SetValue(student, isHappy); + IsHappyField(student) = isHappy; return student; } Student IWhoIsHappy.WhoIsSad() { - CreateStudent.isHappyFieldInfo.SetValue(student, false); + IsHappyField(student) = false; return student; } @@ -67,4 +61,7 @@ public class CreateStudent : Student WhoIsSad(); } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "isHappy")] + private static extern ref bool IsHappyField(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.g.cs index da30821..deb6426 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PredicatePrivateFieldClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IWhoIsHappy { private readonly Student student; - private static readonly FieldInfo isHappyFieldInfo; - - static CreateStudent() - { - isHappyFieldInfo = typeof(Student).GetField("isHappy", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreateStudent() { @@ -34,26 +28,26 @@ public static ICreateStudent InitialStep() public static Student WhoIsHappy(bool isHappy = true) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.isHappyFieldInfo.SetValue(createStudent.student, isHappy); + IsHappyField(createStudent.student) = isHappy; return createStudent.student; } public static Student WhoIsSad() { CreateStudent createStudent = new CreateStudent(); - CreateStudent.isHappyFieldInfo.SetValue(createStudent.student, false); + IsHappyField(createStudent.student) = false; return createStudent.student; } Student IWhoIsHappy.WhoIsHappy(bool isHappy) { - CreateStudent.isHappyFieldInfo.SetValue(student, isHappy); + IsHappyField(student) = isHappy; return student; } Student IWhoIsHappy.WhoIsSad() { - CreateStudent.isHappyFieldInfo.SetValue(student, false); + IsHappyField(student) = false; return student; } @@ -67,4 +61,7 @@ public interface IWhoIsHappy Student WhoIsSad(); } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "isHappy")] + private static extern ref bool IsHappyField(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/UsageTests.cs new file mode 100644 index 0000000..e3853db --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System.Reflection; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PredicatePrivateFieldClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateReadonlyFieldClass() + { + var student = CreateStudent + .WhoIsHappy(); + + bool isHappy = (bool)typeof(Student).GetField( + "isHappy", + BindingFlags.Instance | BindingFlags.NonPublic) + !.GetValue(student)!; + Assert.True(isHappy); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index cbf0bb2..9c949d2 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] { "PrivateFieldClass" }, + Filter(new string[] { "PredicatePrivateFieldClass" }, new List { // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -82,7 +82,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "ParameterAnnotationsPublicConstructorClass", "Student" }, // new object[] { "Abstract", "PartialClass", "Student1|Student2" }, // new object[] { "Abstract", "PredicateClass", "Student" }, - // new object[] { "Abstract", "PredicatePrivateFieldClass", "Student" }, + new object[] { "Abstract", "PredicatePrivateFieldClass", "Student" }, new object[] { "Abstract", "PrivateConstructorClass", "Student" }, new object[] { "Abstract", "PrivateFieldClass", "Student" }, new object[] { "Abstract", "PrivateFluentMethodClass", "Student" }, From 44cbccc2dd5150343b5b7f49d19c5d7d65075b46 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 15:14:49 +0100 Subject: [PATCH 34/67] test: InheritedRecord (wip) --- .../CodeGenerationExecutionTests.cs | 13 --------- .../InheritedRecord/CreatePerson.g.cs | 22 +++++++------- .../InheritedRecord/CreateStudent.g.cs | 29 +++++++++---------- .../Abstract/InheritedRecord/UsageTests.cs | 28 ++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 4 +-- 5 files changed, 54 insertions(+), 42 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs index d017bb4..f5de466 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs @@ -501,19 +501,6 @@ // Assert.Equal(2, student.Semester); // } // -// [Fact, Priority(1)] -// public void CanExecuteInheritedRecord() -// { -// var student = TestClasses.Abstract.InheritedRecord -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); -// Assert.Equal(2, student.Semester); -// } // // [Fact, Priority(1)] // public void CanExecutePartialClass() diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreatePerson.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreatePerson.g.cs index 414001d..dee9103 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreatePerson.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreatePerson.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedRecord; @@ -16,14 +16,6 @@ public class CreatePerson : CreatePerson.IBornOn { private readonly Person person; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - - static CreatePerson() - { - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - dateOfBirthPropertyInfo = typeof(Person).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.Public)!; - } private CreatePerson() { @@ -38,19 +30,19 @@ public static ICreatePerson InitialStep() public static IBornOn WithName(string name) { CreatePerson createPerson = new CreatePerson(); - CreatePerson.namePropertyInfo.SetValue(createPerson.person, name); + SetName(createPerson.person, name); return createPerson; } IBornOn IWithName.WithName(string name) { - CreatePerson.namePropertyInfo.SetValue(person, name); + SetName(person, name); return this; } Person IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreatePerson.dateOfBirthPropertyInfo.SetValue(person, dateOfBirth); + SetDateOfBirth(person, dateOfBirth); return person; } @@ -67,4 +59,10 @@ public interface IBornOn { Person BornOn(System.DateOnly dateOfBirth); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Person person, System.DateOnly value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs index 0df334a..549dec3 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedRecord; @@ -17,16 +17,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - dateOfBirthPropertyInfo = typeof(Person).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -41,25 +31,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.dateOfBirthPropertyInfo.SetValue(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -81,4 +71,13 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Student student, System.DateOnly value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/UsageTests.cs new file mode 100644 index 0000000..eb8dfd2 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/UsageTests.cs @@ -0,0 +1,28 @@ +// #if TEST_GENERATED_CODE +// +// // ReSharper disable NotAccessedVariable +// +// using System; +// using Xunit; +// using Xunit.Priority; +// +// namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedRecord; +// +// public class UsageTests +// { +// [Fact, Priority(1)] +// public void CanExecuteInheritedRecord() +// { +// var student = +// CreateStudent +// .WithName("Alice") +// .BornOn(new DateOnly(2002, 8, 3)) +// .InSemester(2); +// +// Assert.Equal("Alice", student.Name); +// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); +// Assert.Equal(2, student.Semester); +// } +// } +// +// #endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 9c949d2..82e4549 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] { "PredicatePrivateFieldClass" }, + Filter(new string[] { "InheritedRecord" }, new List { // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -71,7 +71,7 @@ internal class TestDataProvider : IEnumerable // new object[] { "Abstract", "InheritedClassPrivateSetters", "Student|Person" }, // new object[] { "Abstract", "InheritedClassProtectedMembers", "Student|Person" }, // new object[] { "Abstract", "InheritedClassProtectedSetters", "Student|Person" }, - // new object[] { "Abstract", "InheritedRecord", "Student|Person" }, + new object[] { "Abstract", "InheritedRecord", "Student|Person" }, // new object[] { "Abstract", "InternalClass", "Student" }, // new object[] { "Abstract", "KeywordClass", "Student"}, // new object[] { "Abstract", "NonGenericCollectionMemberClass", "Student" }, From c943333b6c4b2ce4c1e4d1c2b886099e62261830 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 15:17:12 +0100 Subject: [PATCH 35/67] fix: InheritedRecord: CreateStudent.expected.txt --- .../CreateStudent.expected.txt | 29 +++++----- .../Abstract/InheritedRecord/UsageTests.cs | 56 +++++++++---------- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.expected.txt index 0df334a..0e9e003 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.expected.txt @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedRecord; @@ -17,16 +17,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - dateOfBirthPropertyInfo = typeof(Person).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -41,25 +31,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.dateOfBirthPropertyInfo.SetValue(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -81,4 +71,13 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Person person, System.DateOnly value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/UsageTests.cs index eb8dfd2..1526648 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/UsageTests.cs @@ -1,28 +1,28 @@ -// #if TEST_GENERATED_CODE -// -// // ReSharper disable NotAccessedVariable -// -// using System; -// using Xunit; -// using Xunit.Priority; -// -// namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedRecord; -// -// public class UsageTests -// { -// [Fact, Priority(1)] -// public void CanExecuteInheritedRecord() -// { -// var student = -// CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); -// Assert.Equal(2, student.Semester); -// } -// } -// -// #endif \ No newline at end of file +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedRecord; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteInheritedRecord() + { + var student = + CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } +} + +#endif \ No newline at end of file From cfbcb0865d8ed3f919e116d7541ca34b486a94a2 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 15:31:42 +0100 Subject: [PATCH 36/67] test: InheritedRecord --- .../InnerBodyGeneration/InnerBodyForMemberGenerator.cs | 9 +++++---- .../InnerBodyGeneration/InnerBodyForMethodGenerator.cs | 1 + .../Abstract/InheritedRecord/CreateStudent.g.cs | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs index a60fce9..d947bfa 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs @@ -1,5 +1,6 @@ using M31.FluentApi.Generator.CodeBuilding; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; +using M31.FluentApi.Generator.Commons; namespace M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.InnerBodyGeneration; @@ -47,8 +48,8 @@ private void GenerateInnerBodyForPrivateProperty(MemberSymbolInfo symbolInfo) unsafeAccessorSignature.AddModifiers("private", "static", "extern"); unsafeAccessorSignature.AddParameter( - CodeBoard.Info.FluentApiClassNameWithTypeParameters, - CodeBoard.Info.ClassInstanceName); // Student student + symbolInfo.DeclaringClassNameWithTypeParameters, + symbolInfo.DeclaringClassNameWithTypeParameters.FirstCharToLower()); // Student student unsafeAccessorSignature.AddParameter(symbolInfo.TypeForCodeGeneration, "value"); unsafeAccessorSignature.AddAttribute( @@ -73,8 +74,8 @@ private void GenerateInnerBodyForPrivateField(MemberSymbolInfo symbolInfo) unsafeAccessorSignature.AddModifiers("private", "static", "extern", "ref"); unsafeAccessorSignature.AddParameter( - CodeBoard.Info.FluentApiClassNameWithTypeParameters, - CodeBoard.Info.ClassInstanceName); // Student student + symbolInfo.DeclaringClassNameWithTypeParameters, + symbolInfo.DeclaringClassNameWithTypeParameters.FirstCharToLower()); // Student student unsafeAccessorSignature.AddAttribute( $"[UnsafeAccessor(UnsafeAccessorKind.Field, Name = \"{symbolInfo.Name}\")]"); diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index 14be277..402701e 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -49,6 +49,7 @@ protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbo MethodSignature unsafeAccessorSignature = MethodSignature.Create(symbolInfo.ReturnType, callMethodName, null, true); // todo: generic constraints handled correctly for generic return type? + // todo: check inheritance, see innerbody for member generator, uses symbolInfo.DeclaringClassNameWithTypeParameters, unsafeAccessorSignature.AddModifiers("private", "static", "extern"); unsafeAccessorSignature.AddParameter( diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs index 549dec3..0e9e003 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs @@ -76,8 +76,8 @@ public interface IInSemester private static extern void SetSemester(Student student, int value); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] - private static extern void SetName(Student student, string value); + private static extern void SetName(Person person, string value); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] - private static extern void SetDateOfBirth(Student student, System.DateOnly value); + private static extern void SetDateOfBirth(Person person, System.DateOnly value); } \ No newline at end of file From f28e6d608b97562c49513cffb3536154de720d82 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:11:20 +0100 Subject: [PATCH 37/67] test: InheritedClassPrivateSetters --- .../InnerBodyForMethodGenerator.cs | 7 ++-- .../CodeGenerationExecutionTests.cs | 13 ------ .../CreatePerson.g.cs | 35 +++++++--------- .../CreateStudent.expected.txt | 42 ++++++++----------- .../CreateStudent.g.cs | 42 ++++++++----------- .../UsageTests.cs | 28 +++++++++++++ .../CodeGeneration/TestDataProvider.cs | 6 +-- 7 files changed, 85 insertions(+), 88 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/UsageTests.cs diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index 402701e..bfcbd70 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -4,7 +4,7 @@ using M31.FluentApi.Generator.CodeBuilding; using M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.Commons; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; -using M31.FluentApi.Generator.SourceGenerators.Generics; // todo: remove if not needed +using M31.FluentApi.Generator.Commons; namespace M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.InnerBodyGeneration; @@ -49,11 +49,12 @@ protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbo MethodSignature unsafeAccessorSignature = MethodSignature.Create(symbolInfo.ReturnType, callMethodName, null, true); // todo: generic constraints handled correctly for generic return type? - // todo: check inheritance, see innerbody for member generator, uses symbolInfo.DeclaringClassNameWithTypeParameters, unsafeAccessorSignature.AddModifiers("private", "static", "extern"); + // Student student unsafeAccessorSignature.AddParameter( - new Parameter(CodeBoard.Info.FluentApiClassNameWithTypeParameters, CodeBoard.Info.ClassInstanceName)); + symbolInfo.DeclaringClassNameWithTypeParameters, + symbolInfo.DeclaringClassNameWithTypeParameters.FirstCharToLower()); List parameters = CodeBuildingHelpers.CreateParameters(symbolInfo.ParameterInfos); parameters.ForEach(unsafeAccessorSignature.AddParameter); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs index f5de466..1130411 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs @@ -452,19 +452,6 @@ // Assert.Equal(2, student.Semester); // } // -// [Fact, Priority(1)] -// public void CanExecuteInheritedClassPrivateSetters() -// { -// var student = TestClasses.Abstract.InheritedClassPrivateSetters -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(22, student.Age); -// Assert.Equal(2, student.Semester); -// } // // [Fact, Priority(1)] // public void CanExecuteInheritedClassProtectedMembers() diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreatePerson.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreatePerson.g.cs index 7577fd7..2b24c56 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreatePerson.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreatePerson.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassPrivateSetters; @@ -16,22 +16,6 @@ public class CreatePerson : CreatePerson.IOfAgeBornOn { private readonly Person person; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo agePropertyInfo; - private static readonly MethodInfo bornOnMethodInfo; - - static CreatePerson() - { - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - agePropertyInfo = typeof(Person).GetProperty("Age", BindingFlags.Instance | BindingFlags.Public)!; - bornOnMethodInfo = typeof(Person).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - } private CreatePerson() { @@ -46,25 +30,25 @@ public static ICreatePerson InitialStep() public static IOfAgeBornOn WithName(string name) { CreatePerson createPerson = new CreatePerson(); - CreatePerson.namePropertyInfo.SetValue(createPerson.person, name); + SetName(createPerson.person, name); return createPerson; } IOfAgeBornOn IWithName.WithName(string name) { - CreatePerson.namePropertyInfo.SetValue(person, name); + SetName(person, name); return this; } Person IOfAgeBornOn.OfAge(int age) { - CreatePerson.agePropertyInfo.SetValue(person, age); + SetAge(person, age); return person; } Person IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) { - CreatePerson.bornOnMethodInfo.Invoke(person, new object?[] { dateOfBirth }); + CallBornOn(person, dateOfBirth); return person; } @@ -83,4 +67,13 @@ public interface IOfAgeBornOn Person BornOn(System.DateOnly dateOfBirth); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Age")] + private static extern void SetAge(Person person, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Person person, System.DateOnly dateOfBirth); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.expected.txt index daaca81..4224acc 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.expected.txt @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassPrivateSetters; @@ -17,24 +17,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo agePropertyInfo; - private static readonly MethodInfo bornOnMethodInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - agePropertyInfo = typeof(Person).GetProperty("Age", BindingFlags.Instance | BindingFlags.Public)!; - bornOnMethodInfo = typeof(Person).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - } private CreateStudent() { @@ -49,31 +31,31 @@ public class CreateStudent : public static IOfAgeBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IOfAgeBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IOfAgeBornOn.OfAge(int age) { - CreateStudent.agePropertyInfo.SetValue(student, age); + SetAge(student, age); return this; } IInSemester IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.bornOnMethodInfo.Invoke(student, new object?[] { dateOfBirth }); + CallBornOn(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -97,4 +79,16 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Age")] + private static extern void SetAge(Person person, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Person person, System.DateOnly dateOfBirth); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.g.cs index daaca81..4224acc 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassPrivateSetters; @@ -17,24 +17,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo agePropertyInfo; - private static readonly MethodInfo bornOnMethodInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - agePropertyInfo = typeof(Person).GetProperty("Age", BindingFlags.Instance | BindingFlags.Public)!; - bornOnMethodInfo = typeof(Person).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - } private CreateStudent() { @@ -49,31 +31,31 @@ public static ICreateStudent InitialStep() public static IOfAgeBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IOfAgeBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IOfAgeBornOn.OfAge(int age) { - CreateStudent.agePropertyInfo.SetValue(student, age); + SetAge(student, age); return this; } IInSemester IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.bornOnMethodInfo.Invoke(student, new object?[] { dateOfBirth }); + CallBornOn(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -97,4 +79,16 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Age")] + private static extern void SetAge(Person person, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Person person, System.DateOnly dateOfBirth); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/UsageTests.cs new file mode 100644 index 0000000..cfb197d --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/UsageTests.cs @@ -0,0 +1,28 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassPrivateSetters; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteInheritedClassPrivateSetters() + { + var student = + CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(22, student.Age); + Assert.Equal(2, student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 82e4549..08d813b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] { "InheritedRecord" }, + Filter(new string[] { "InheritedClassPrivateSetters" }, new List { // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -67,8 +67,8 @@ internal class TestDataProvider : IEnumerable // new object[] { "Abstract", "GetPrivateInitPropertyClass", "Student" }, // new object[] { "Abstract", "GetPrivateSetPropertyClass", "Student" }, // new object[] { "Abstract", "InternalPropertyClass", "Student" }, - // new object[] { "Abstract", "InheritedClass", "Student|Person" }, - // new object[] { "Abstract", "InheritedClassPrivateSetters", "Student|Person" }, + new object[] { "Abstract", "InheritedClass", "Student|Person" }, + new object[] { "Abstract", "InheritedClassPrivateSetters", "Student|Person" }, // new object[] { "Abstract", "InheritedClassProtectedMembers", "Student|Person" }, // new object[] { "Abstract", "InheritedClassProtectedSetters", "Student|Person" }, new object[] { "Abstract", "InheritedRecord", "Student|Person" }, From 03c2e32cd01c29e25062a7cb48d837cb9e9fe47d Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:14:26 +0100 Subject: [PATCH 38/67] test: GetPrivateInitPropertyClass --- .../CreateStudent.expected.txt | 15 +++++-------- .../CreateStudent.g.cs | 15 +++++-------- .../GetPrivateInitPropertyClass/UsageTests.cs | 22 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 4 ++-- 4 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.expected.txt index 7a2636b..c91ee68 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GetPrivateInitPropertyClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterPropertyInfo.SetValue(createStudent.student, semester); + SetSemester(createStudent.student, semester); return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -52,4 +46,7 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.g.cs index 7a2636b..c91ee68 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GetPrivateInitPropertyClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterPropertyInfo.SetValue(createStudent.student, semester); + SetSemester(createStudent.student, semester); return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -52,4 +46,7 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/UsageTests.cs new file mode 100644 index 0000000..5a1da40 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/UsageTests.cs @@ -0,0 +1,22 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GetPrivateInitPropertyClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateReadonlyFieldClass() + { + var student = CreateStudent + .InSemester(4); + + Assert.Equal(4, student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 08d813b..90ce701 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] { "InheritedClassPrivateSetters" }, + Filter(new string[] { "GetPrivateInitPropertyClass" }, new List { // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -64,7 +64,7 @@ internal class TestDataProvider : IEnumerable // new object[] { "Abstract", "GenericOverloadedMethodClass", "Student" }, // new object[] { "Abstract", "GenericOverloadedPrivateMethodClass", "Student" }, // new object[] { "Abstract", "GetInitPropertyClass", "Student" }, - // new object[] { "Abstract", "GetPrivateInitPropertyClass", "Student" }, + new object[] { "Abstract", "GetPrivateInitPropertyClass", "Student" }, // new object[] { "Abstract", "GetPrivateSetPropertyClass", "Student" }, // new object[] { "Abstract", "InternalPropertyClass", "Student" }, new object[] { "Abstract", "InheritedClass", "Student|Person" }, From d064ee0e13769972986f637422b58357f5059ea3 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:18:21 +0100 Subject: [PATCH 39/67] test: CollectionNullableArrayClass --- .../CreateStudent.expected.txt | 23 ++++++++----------- .../CreateStudent.g.cs | 23 ++++++++----------- .../UsageTests.cs | 22 ++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 12 +++++----- 4 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.expected.txt index 2a90b10..3767ae1 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.CollectionNullableArrayClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IWhoseFriendsAre { private readonly Student student; - private static readonly PropertyInfo friendsPropertyInfo; - - static CreateStudent() - { - friendsPropertyInfo = typeof(Student).GetProperty("Friends", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,39 +28,39 @@ public class CreateStudent : public static Student WhoseFriendsAre(params string[]? friends) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.friendsPropertyInfo.SetValue(createStudent.student, friends); + SetFriends(createStudent.student, friends); return createStudent.student; } public static Student WhoseFriendIs(string friend) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.friendsPropertyInfo.SetValue(createStudent.student, new string[1]{ friend }); + SetFriends(createStudent.student, new string[1]{ friend }); return createStudent.student; } public static Student WhoHasNoFriends() { CreateStudent createStudent = new CreateStudent(); - CreateStudent.friendsPropertyInfo.SetValue(createStudent.student, new string[0]); + SetFriends(createStudent.student, new string[0]); return createStudent.student; } Student IWhoseFriendsAre.WhoseFriendsAre(params string[]? friends) { - CreateStudent.friendsPropertyInfo.SetValue(student, friends); + SetFriends(student, friends); return student; } Student IWhoseFriendsAre.WhoseFriendIs(string friend) { - CreateStudent.friendsPropertyInfo.SetValue(student, new string[1]{ friend }); + SetFriends(student, new string[1]{ friend }); return student; } Student IWhoseFriendsAre.WhoHasNoFriends() { - CreateStudent.friendsPropertyInfo.SetValue(student, new string[0]); + SetFriends(student, new string[0]); return student; } @@ -82,4 +76,7 @@ public class CreateStudent : Student WhoHasNoFriends(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Friends")] + private static extern void SetFriends(Student student, string[]? value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.g.cs index 2a90b10..3767ae1 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.CollectionNullableArrayClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IWhoseFriendsAre { private readonly Student student; - private static readonly PropertyInfo friendsPropertyInfo; - - static CreateStudent() - { - friendsPropertyInfo = typeof(Student).GetProperty("Friends", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,39 +28,39 @@ public static ICreateStudent InitialStep() public static Student WhoseFriendsAre(params string[]? friends) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.friendsPropertyInfo.SetValue(createStudent.student, friends); + SetFriends(createStudent.student, friends); return createStudent.student; } public static Student WhoseFriendIs(string friend) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.friendsPropertyInfo.SetValue(createStudent.student, new string[1]{ friend }); + SetFriends(createStudent.student, new string[1]{ friend }); return createStudent.student; } public static Student WhoHasNoFriends() { CreateStudent createStudent = new CreateStudent(); - CreateStudent.friendsPropertyInfo.SetValue(createStudent.student, new string[0]); + SetFriends(createStudent.student, new string[0]); return createStudent.student; } Student IWhoseFriendsAre.WhoseFriendsAre(params string[]? friends) { - CreateStudent.friendsPropertyInfo.SetValue(student, friends); + SetFriends(student, friends); return student; } Student IWhoseFriendsAre.WhoseFriendIs(string friend) { - CreateStudent.friendsPropertyInfo.SetValue(student, new string[1]{ friend }); + SetFriends(student, new string[1]{ friend }); return student; } Student IWhoseFriendsAre.WhoHasNoFriends() { - CreateStudent.friendsPropertyInfo.SetValue(student, new string[0]); + SetFriends(student, new string[0]); return student; } @@ -82,4 +76,7 @@ public interface IWhoseFriendsAre Student WhoHasNoFriends(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Friends")] + private static extern void SetFriends(Student student, string[]? value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/UsageTests.cs new file mode 100644 index 0000000..a922ae3 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/UsageTests.cs @@ -0,0 +1,22 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.CollectionNullableArrayClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateReadonlyFieldClass() + { + var student = CreateStudent + .WhoseFriendsAre("Alice", "Bob"); + + Assert.Equal(["Alice", "Bob"], student.Friends); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 90ce701..a886db8 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,14 +7,14 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] { "GetPrivateInitPropertyClass" }, + Filter(new string[] { "CollectionNullableArrayClass" }, new List { - // new object[] { "Abstract", "AliasNamespaceClass", "Student" }, - // new object[] { "Abstract", "CollectionInterfaceMemberClass", "Student" }, - // new object[] { "Abstract", "CollectionMemberClass", "Student" }, - // new object[] { "Abstract", "CollectionMemberClassWithSuppression", "Student" }, - // new object[] { "Abstract", "CollectionNullableArrayClass", "Student" }, + new object[] { "Abstract", "AliasNamespaceClass", "Student" }, + new object[] { "Abstract", "CollectionInterfaceMemberClass", "Student" }, + new object[] { "Abstract", "CollectionMemberClass", "Student" }, + new object[] { "Abstract", "CollectionMemberClassWithSuppression", "Student" }, + new object[] { "Abstract", "CollectionNullableArrayClass", "Student" }, // new object[] { "Abstract", "ContinueWithAfterCompoundClass", "Student" }, // new object[] { "Abstract", "ContinueWithInForkClass", "Student" }, // new object[] { "Abstract", "ContinueWithOfOverloadedMethodClass", "Student" }, From b4a3ac354d318dcc6dd6116207bee4535e8b98ea Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:21:28 +0100 Subject: [PATCH 40/67] test: ContinueWithAfterCompoundClass --- .../CreateStudent.expected.txt | 38 +++++++++---------- .../CreateStudent.g.cs | 38 +++++++++---------- .../UsageTests.cs | 25 ++++++++++++ .../CodeGeneration/TestDataProvider.cs | 4 +- 4 files changed, 65 insertions(+), 40 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.expected.txt index 1c54279..9b4a920 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithAfterCompoundClass; @@ -16,18 +16,6 @@ public class CreateStudent : CreateStudent.IWithProperty2 { private readonly Student student; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - private static readonly PropertyInfo property1PropertyInfo; - private static readonly PropertyInfo property2PropertyInfo; - - static CreateStudent() - { - firstNamePropertyInfo = typeof(Student).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Student).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - property1PropertyInfo = typeof(Student).GetProperty("Property1", BindingFlags.Instance | BindingFlags.Public)!; - property2PropertyInfo = typeof(Student).GetProperty("Property2", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -42,27 +30,27 @@ public class CreateStudent : public static IWithProperty2 WithName(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.firstNamePropertyInfo.SetValue(createStudent.student, firstName); - CreateStudent.lastNamePropertyInfo.SetValue(createStudent.student, lastName); + SetFirstName(createStudent.student, firstName); + SetLastName(createStudent.student, lastName); return createStudent; } IWithProperty2 IWithName.WithName(string firstName, string lastName) { - CreateStudent.firstNamePropertyInfo.SetValue(student, firstName); - CreateStudent.lastNamePropertyInfo.SetValue(student, lastName); + SetFirstName(student, firstName); + SetLastName(student, lastName); return this; } IWithProperty2 IWithProperty1.WithProperty1(string property1) { - CreateStudent.property1PropertyInfo.SetValue(student, property1); + SetProperty1(student, property1); return this; } Student IWithProperty2.WithProperty2(string property2) { - CreateStudent.property2PropertyInfo.SetValue(student, property2); + SetProperty2(student, property2); return student; } @@ -84,4 +72,16 @@ public class CreateStudent : { Student WithProperty2(string property2); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Property1")] + private static extern void SetProperty1(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Property2")] + private static extern void SetProperty2(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.g.cs index 1c54279..9b4a920 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithAfterCompoundClass; @@ -16,18 +16,6 @@ public class CreateStudent : CreateStudent.IWithProperty2 { private readonly Student student; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - private static readonly PropertyInfo property1PropertyInfo; - private static readonly PropertyInfo property2PropertyInfo; - - static CreateStudent() - { - firstNamePropertyInfo = typeof(Student).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Student).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - property1PropertyInfo = typeof(Student).GetProperty("Property1", BindingFlags.Instance | BindingFlags.Public)!; - property2PropertyInfo = typeof(Student).GetProperty("Property2", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -42,27 +30,27 @@ public static ICreateStudent InitialStep() public static IWithProperty2 WithName(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.firstNamePropertyInfo.SetValue(createStudent.student, firstName); - CreateStudent.lastNamePropertyInfo.SetValue(createStudent.student, lastName); + SetFirstName(createStudent.student, firstName); + SetLastName(createStudent.student, lastName); return createStudent; } IWithProperty2 IWithName.WithName(string firstName, string lastName) { - CreateStudent.firstNamePropertyInfo.SetValue(student, firstName); - CreateStudent.lastNamePropertyInfo.SetValue(student, lastName); + SetFirstName(student, firstName); + SetLastName(student, lastName); return this; } IWithProperty2 IWithProperty1.WithProperty1(string property1) { - CreateStudent.property1PropertyInfo.SetValue(student, property1); + SetProperty1(student, property1); return this; } Student IWithProperty2.WithProperty2(string property2) { - CreateStudent.property2PropertyInfo.SetValue(student, property2); + SetProperty2(student, property2); return student; } @@ -84,4 +72,16 @@ public interface IWithProperty2 { Student WithProperty2(string property2); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Property1")] + private static extern void SetProperty1(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Property2")] + private static extern void SetProperty2(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/UsageTests.cs new file mode 100644 index 0000000..b48a33f --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/UsageTests.cs @@ -0,0 +1,25 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithAfterCompoundClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateReadonlyFieldClass() + { + var student = CreateStudent + .WithName("Alice", "King") + .WithProperty2("Physics"); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("King", student.LastName); + Assert.Equal("Physics", student.Property2); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index a886db8..76a2dab 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(new string[] { "CollectionNullableArrayClass" }, + Filter(["ContinueWithAfterCompoundClass"], new List { new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -15,7 +15,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "CollectionMemberClass", "Student" }, new object[] { "Abstract", "CollectionMemberClassWithSuppression", "Student" }, new object[] { "Abstract", "CollectionNullableArrayClass", "Student" }, - // new object[] { "Abstract", "ContinueWithAfterCompoundClass", "Student" }, + new object[] { "Abstract", "ContinueWithAfterCompoundClass", "Student" }, // new object[] { "Abstract", "ContinueWithInForkClass", "Student" }, // new object[] { "Abstract", "ContinueWithOfOverloadedMethodClass", "Student" }, // new object[] { "Abstract", "ContinueWithSelfClass", "Student" }, From ce0ca5e72402af6633fb8a890740e672bc93f29f Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:23:48 +0100 Subject: [PATCH 41/67] test: ContinueWithOfOverloadedMethodClass --- .../CreateStudent.expected.txt | 20 +++++++-------- .../CreateStudent.g.cs | 20 +++++++-------- .../UsageTests.cs | 25 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 6 ++--- 4 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.expected.txt index 74bc6b3..7f74f1d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithOfOverloadedMethodClass; @@ -16,14 +16,6 @@ public class CreateStudent : CreateStudent.IWithProperty2 { private readonly Student student; - private static readonly PropertyInfo property1PropertyInfo; - private static readonly PropertyInfo property2PropertyInfo; - - static CreateStudent() - { - property1PropertyInfo = typeof(Student).GetProperty("Property1", BindingFlags.Instance | BindingFlags.Public)!; - property2PropertyInfo = typeof(Student).GetProperty("Property2", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -63,13 +55,13 @@ public class CreateStudent : IWithProperty2 IWithProperty1.WithProperty1(string property1) { - CreateStudent.property1PropertyInfo.SetValue(student, property1); + SetProperty1(student, property1); return this; } Student IWithProperty2.WithProperty2(string property2) { - CreateStudent.property2PropertyInfo.SetValue(student, property2); + SetProperty2(student, property2); return student; } @@ -93,4 +85,10 @@ public class CreateStudent : { Student WithProperty2(string property2); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Property1")] + private static extern void SetProperty1(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Property2")] + private static extern void SetProperty2(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.g.cs index 74bc6b3..7f74f1d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithOfOverloadedMethodClass; @@ -16,14 +16,6 @@ public class CreateStudent : CreateStudent.IWithProperty2 { private readonly Student student; - private static readonly PropertyInfo property1PropertyInfo; - private static readonly PropertyInfo property2PropertyInfo; - - static CreateStudent() - { - property1PropertyInfo = typeof(Student).GetProperty("Property1", BindingFlags.Instance | BindingFlags.Public)!; - property2PropertyInfo = typeof(Student).GetProperty("Property2", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -63,13 +55,13 @@ IWithProperty2 IMethod1Method1.Method1(int p1) IWithProperty2 IWithProperty1.WithProperty1(string property1) { - CreateStudent.property1PropertyInfo.SetValue(student, property1); + SetProperty1(student, property1); return this; } Student IWithProperty2.WithProperty2(string property2) { - CreateStudent.property2PropertyInfo.SetValue(student, property2); + SetProperty2(student, property2); return student; } @@ -93,4 +85,10 @@ public interface IWithProperty2 { Student WithProperty2(string property2); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Property1")] + private static extern void SetProperty1(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Property2")] + private static extern void SetProperty2(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/UsageTests.cs new file mode 100644 index 0000000..d28a232 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/UsageTests.cs @@ -0,0 +1,25 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithOfOverloadedMethodClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateReadonlyFieldClass() + { + var student = CreateStudent + .Method1() + .WithProperty1("Alice") + .WithProperty2("King"); + + Assert.Equal("Alice", student.Property1); + Assert.Equal("King", student.Property2); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 76a2dab..a4c7ea0 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(["ContinueWithAfterCompoundClass"], + Filter(["ContinueWithOfOverloadedMethodClass"], new List { new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -16,8 +16,8 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "CollectionMemberClassWithSuppression", "Student" }, new object[] { "Abstract", "CollectionNullableArrayClass", "Student" }, new object[] { "Abstract", "ContinueWithAfterCompoundClass", "Student" }, - // new object[] { "Abstract", "ContinueWithInForkClass", "Student" }, - // new object[] { "Abstract", "ContinueWithOfOverloadedMethodClass", "Student" }, + new object[] { "Abstract", "ContinueWithInForkClass", "Student" }, + new object[] { "Abstract", "ContinueWithOfOverloadedMethodClass", "Student" }, // new object[] { "Abstract", "ContinueWithSelfClass", "Student" }, // new object[] { "Abstract", "CustomFluentMethodNameClass", "Student" }, // new object[] { "Abstract", "DefaultFluentMethodNameClass", "Student" }, From f719f786f4e0966d78eb7c7527e7f4bf3f5f676e Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:27:32 +0100 Subject: [PATCH 42/67] test: ContinueWithSelfClass --- .../CreateStudent.expected.txt | 29 +++++++++---------- .../ContinueWithSelfClass/CreateStudent.g.cs | 29 +++++++++---------- .../ContinueWithSelfClass/UsageTests.cs | 28 ++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 8 ++--- 4 files changed, 60 insertions(+), 34 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.expected.txt index af35b7d..fb2be7e 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithSelfClass; @@ -15,16 +15,6 @@ public class CreateStudent : CreateStudent.IWithMiddleNameWithLastName { private readonly Student student; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo middleNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - - static CreateStudent() - { - firstNamePropertyInfo = typeof(Student).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - middleNamePropertyInfo = typeof(Student).GetProperty("MiddleName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Student).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -39,25 +29,25 @@ public class CreateStudent : public static IWithMiddleNameWithLastName WithFirstName(string firstName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.firstNamePropertyInfo.SetValue(createStudent.student, firstName); + SetFirstName(createStudent.student, firstName); return createStudent; } IWithMiddleNameWithLastName IWithFirstName.WithFirstName(string firstName) { - CreateStudent.firstNamePropertyInfo.SetValue(student, firstName); + SetFirstName(student, firstName); return this; } IWithMiddleNameWithLastName IWithMiddleNameWithLastName.WithMiddleName(string? middleName) { - CreateStudent.middleNamePropertyInfo.SetValue(student, middleName); + SetMiddleName(student, middleName); return this; } Student IWithMiddleNameWithLastName.WithLastName(string lastName) { - CreateStudent.lastNamePropertyInfo.SetValue(student, lastName); + SetLastName(student, lastName); return student; } @@ -76,4 +66,13 @@ public class CreateStudent : Student WithLastName(string lastName); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_MiddleName")] + private static extern void SetMiddleName(Student student, string? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.g.cs index af35b7d..fb2be7e 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithSelfClass; @@ -15,16 +15,6 @@ public class CreateStudent : CreateStudent.IWithMiddleNameWithLastName { private readonly Student student; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo middleNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - - static CreateStudent() - { - firstNamePropertyInfo = typeof(Student).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - middleNamePropertyInfo = typeof(Student).GetProperty("MiddleName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Student).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -39,25 +29,25 @@ public static ICreateStudent InitialStep() public static IWithMiddleNameWithLastName WithFirstName(string firstName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.firstNamePropertyInfo.SetValue(createStudent.student, firstName); + SetFirstName(createStudent.student, firstName); return createStudent; } IWithMiddleNameWithLastName IWithFirstName.WithFirstName(string firstName) { - CreateStudent.firstNamePropertyInfo.SetValue(student, firstName); + SetFirstName(student, firstName); return this; } IWithMiddleNameWithLastName IWithMiddleNameWithLastName.WithMiddleName(string? middleName) { - CreateStudent.middleNamePropertyInfo.SetValue(student, middleName); + SetMiddleName(student, middleName); return this; } Student IWithMiddleNameWithLastName.WithLastName(string lastName) { - CreateStudent.lastNamePropertyInfo.SetValue(student, lastName); + SetLastName(student, lastName); return student; } @@ -76,4 +66,13 @@ public interface IWithMiddleNameWithLastName Student WithLastName(string lastName); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_MiddleName")] + private static extern void SetMiddleName(Student student, string? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs new file mode 100644 index 0000000..d0d54f1 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs @@ -0,0 +1,28 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System.Reflection; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithSelfClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteContinueWithSelfClass() + { + Student student = CreateStudent + .WithFirstName("Alice") + .WithMiddleName("Emma") + .WithLastName("King"); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("Emma", student.MiddleName); + Assert.Equal("King", student.LastName); + } +} + +#endif +// todo: check all usage tests. Some have the wrong method names. \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index a4c7ea0..cfab5f8 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(["ContinueWithOfOverloadedMethodClass"], + Filter(["ContinueWithSelfClass"], new List { new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -18,9 +18,9 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "ContinueWithAfterCompoundClass", "Student" }, new object[] { "Abstract", "ContinueWithInForkClass", "Student" }, new object[] { "Abstract", "ContinueWithOfOverloadedMethodClass", "Student" }, - // new object[] { "Abstract", "ContinueWithSelfClass", "Student" }, - // new object[] { "Abstract", "CustomFluentMethodNameClass", "Student" }, - // new object[] { "Abstract", "DefaultFluentMethodNameClass", "Student" }, + new object[] { "Abstract", "ContinueWithSelfClass", "Student" }, + new object[] { "Abstract", "CustomFluentMethodNameClass", "Student" }, + new object[] { "Abstract", "DefaultFluentMethodNameClass", "Student" }, // new object[] { "Abstract", "FluentApiComments", "CommentedCompoundClass", "Student" }, // new object[] { "Abstract", "FluentApiComments", "CommentedLambdaCollectionClass", "Student|Phone" }, // new object[] { "Abstract", "FluentApiComments", "CommentedMethodsClass", "Student" }, From 1645b366e3850dbaf3d339a8dca250dda392841c Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:32:37 +0100 Subject: [PATCH 43/67] test: CommentedMethodsClass --- .../CreateStudent.expected.txt | 41 +++++++------------ .../CommentedMethodsClass/CreateStudent.g.cs | 41 +++++++------------ .../CommentedMethodsClass/UsageTests.cs | 27 ++++++++++++ .../CodeGeneration/TestDataProvider.cs | 8 ++-- 4 files changed, 59 insertions(+), 58 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.expected.txt index 2525ae9..9d94507 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.expected.txt @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentApiComments.CommentedMethodsClass; @@ -16,28 +16,6 @@ public class CreateStudent : CreateStudent.IOfAgeBornOn { private readonly Student student; - private static readonly MethodInfo withNameMethodInfo; - private static readonly PropertyInfo agePropertyInfo; - private static readonly MethodInfo bornOnMethodInfo; - - static CreateStudent() - { - withNameMethodInfo = typeof(Student).GetMethod( - "WithName", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string), typeof(string) }, - null)!; - agePropertyInfo = typeof(Student).GetProperty("Age", BindingFlags.Instance | BindingFlags.Public)!; - bornOnMethodInfo = typeof(Student).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - } private CreateStudent() { @@ -55,27 +33,27 @@ public class CreateStudent : public static IOfAgeBornOn WithName(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.withNameMethodInfo.Invoke(createStudent.student, new object?[] { firstName, lastName }); + CallWithName(createStudent.student, firstName, lastName); return createStudent; } /// IOfAgeBornOn IWithName.WithName(string firstName, string lastName) { - CreateStudent.withNameMethodInfo.Invoke(student, new object?[] { firstName, lastName }); + CallWithName(student, firstName, lastName); return this; } Student IOfAgeBornOn.OfAge(int age) { - CreateStudent.agePropertyInfo.SetValue(student, age); + SetAge(student, age); return student; } /// Student IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.bornOnMethodInfo.Invoke(student, new object?[] { dateOfBirth }); + CallBornOn(student, dateOfBirth); return student; } @@ -99,4 +77,13 @@ public class CreateStudent : /// The student's date of birth. Student BornOn(System.DateOnly dateOfBirth); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] + private static extern void CallWithName(Student student, string firstName, string lastName); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Age")] + private static extern void SetAge(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Student student, System.DateOnly dateOfBirth); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.g.cs index 2525ae9..9d94507 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentApiComments.CommentedMethodsClass; @@ -16,28 +16,6 @@ public class CreateStudent : CreateStudent.IOfAgeBornOn { private readonly Student student; - private static readonly MethodInfo withNameMethodInfo; - private static readonly PropertyInfo agePropertyInfo; - private static readonly MethodInfo bornOnMethodInfo; - - static CreateStudent() - { - withNameMethodInfo = typeof(Student).GetMethod( - "WithName", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string), typeof(string) }, - null)!; - agePropertyInfo = typeof(Student).GetProperty("Age", BindingFlags.Instance | BindingFlags.Public)!; - bornOnMethodInfo = typeof(Student).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - } private CreateStudent() { @@ -55,27 +33,27 @@ public static ICreateStudent InitialStep() public static IOfAgeBornOn WithName(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.withNameMethodInfo.Invoke(createStudent.student, new object?[] { firstName, lastName }); + CallWithName(createStudent.student, firstName, lastName); return createStudent; } /// IOfAgeBornOn IWithName.WithName(string firstName, string lastName) { - CreateStudent.withNameMethodInfo.Invoke(student, new object?[] { firstName, lastName }); + CallWithName(student, firstName, lastName); return this; } Student IOfAgeBornOn.OfAge(int age) { - CreateStudent.agePropertyInfo.SetValue(student, age); + SetAge(student, age); return student; } /// Student IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.bornOnMethodInfo.Invoke(student, new object?[] { dateOfBirth }); + CallBornOn(student, dateOfBirth); return student; } @@ -99,4 +77,13 @@ public interface IOfAgeBornOn /// The student's date of birth. Student BornOn(System.DateOnly dateOfBirth); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithName")] + private static extern void CallWithName(Student student, string firstName, string lastName); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Age")] + private static extern void SetAge(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Student student, System.DateOnly dateOfBirth); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/UsageTests.cs new file mode 100644 index 0000000..b82c199 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentApiComments.CommentedMethodsClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteCommentedMethodsClass() + { + var student = + CreateStudent + .WithName("Alice", "King") + .BornOn(new DateOnly(2004, 9, 25)); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("King", student.LastName); + Assert.Equal(20, student.Age); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index cfab5f8..cdb4afd 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(["ContinueWithSelfClass"], + Filter(["CommentedMethodsClass"], new List { new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -21,9 +21,9 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "ContinueWithSelfClass", "Student" }, new object[] { "Abstract", "CustomFluentMethodNameClass", "Student" }, new object[] { "Abstract", "DefaultFluentMethodNameClass", "Student" }, - // new object[] { "Abstract", "FluentApiComments", "CommentedCompoundClass", "Student" }, - // new object[] { "Abstract", "FluentApiComments", "CommentedLambdaCollectionClass", "Student|Phone" }, - // new object[] { "Abstract", "FluentApiComments", "CommentedMethodsClass", "Student" }, + new object[] { "Abstract", "FluentApiComments", "CommentedCompoundClass", "Student" }, + new object[] { "Abstract", "FluentApiComments", "CommentedLambdaCollectionClass", "Student|Phone" }, + new object[] { "Abstract", "FluentApiComments", "CommentedMethodsClass", "Student" }, // new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClass", "Student" }, // new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClassAdvanced", "Student" }, // new object[] { "Abstract", "FluentApiComments", "IncompletelyCommentedPropertyClass", "Student"}, From c65e49a0d66b13e764ad4a312068b8150c5d0f27 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:43:51 +0100 Subject: [PATCH 44/67] test: CommentedPropertiesClassAdvanced --- .../CreateStudent.expected.txt | 17 +++++------ .../CreateStudent.g.cs | 17 +++++------ .../UsageTests.cs | 30 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 8 ++--- 4 files changed, 48 insertions(+), 24 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.expected.txt index 43cc102..7adb809 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentApiComments.CommentedPropertiesClassAdvanced; @@ -17,12 +17,6 @@ public class CreateStudent : CreateStudent.IWhoIsHappy { private readonly Student student; - private static readonly PropertyInfo isHappyPropertyInfo; - - static CreateStudent() - { - isHappyPropertyInfo = typeof(Student).GetProperty("IsHappy", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -76,19 +70,19 @@ public class CreateStudent : Student IWhoIsHappy.WhoIsHappy(bool? isHappy) { - CreateStudent.isHappyPropertyInfo.SetValue(student, isHappy); + SetIsHappy(student, isHappy); return student; } Student IWhoIsHappy.WhoIsSad() { - CreateStudent.isHappyPropertyInfo.SetValue(student, false); + SetIsHappy(student, false); return student; } Student IWhoIsHappy.WithUnknownMood() { - CreateStudent.isHappyPropertyInfo.SetValue(student, null); + SetIsHappy(student, null); return student; } @@ -129,4 +123,7 @@ public class CreateStudent : Student WithUnknownMood(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_IsHappy")] + private static extern void SetIsHappy(Student student, bool? value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.g.cs index 43cc102..7adb809 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentApiComments.CommentedPropertiesClassAdvanced; @@ -17,12 +17,6 @@ public class CreateStudent : CreateStudent.IWhoIsHappy { private readonly Student student; - private static readonly PropertyInfo isHappyPropertyInfo; - - static CreateStudent() - { - isHappyPropertyInfo = typeof(Student).GetProperty("IsHappy", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -76,19 +70,19 @@ IWhoIsHappy ILivingIn.InUnknownCity() Student IWhoIsHappy.WhoIsHappy(bool? isHappy) { - CreateStudent.isHappyPropertyInfo.SetValue(student, isHappy); + SetIsHappy(student, isHappy); return student; } Student IWhoIsHappy.WhoIsSad() { - CreateStudent.isHappyPropertyInfo.SetValue(student, false); + SetIsHappy(student, false); return student; } Student IWhoIsHappy.WithUnknownMood() { - CreateStudent.isHappyPropertyInfo.SetValue(student, null); + SetIsHappy(student, null); return student; } @@ -129,4 +123,7 @@ public interface IWhoIsHappy Student WithUnknownMood(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_IsHappy")] + private static extern void SetIsHappy(Student student, bool? value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/UsageTests.cs new file mode 100644 index 0000000..ceeb4de --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/UsageTests.cs @@ -0,0 +1,30 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentApiComments.CommentedPropertiesClassAdvanced; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteCommentedPropertiesClassAdvanced() + { + var student = + CreateStudent + .WithName("Alice") + .OfAge(22) + .LivingInBoston() + .WhoIsHappy(); + + Assert.Equal("Alice", student.Name); + Assert.Equal(22, student.Age); + Assert.Equal("Boston", student.City); + Assert.True(student.IsHappy); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index cdb4afd..b907273 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(["CommentedMethodsClass"], + Filter([], new List { new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -24,9 +24,9 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "FluentApiComments", "CommentedCompoundClass", "Student" }, new object[] { "Abstract", "FluentApiComments", "CommentedLambdaCollectionClass", "Student|Phone" }, new object[] { "Abstract", "FluentApiComments", "CommentedMethodsClass", "Student" }, - // new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClass", "Student" }, - // new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClassAdvanced", "Student" }, - // new object[] { "Abstract", "FluentApiComments", "IncompletelyCommentedPropertyClass", "Student"}, + new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClass", "Student" }, + new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClassAdvanced", "Student" }, + new object[] { "Abstract", "FluentApiComments", "IncompletelyCommentedPropertyClass", "Student"}, // new object[] { "Abstract", "FluentApiComments", "RedundantCommentCompoundClass", "Student" }, // new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass", "Student" }, // new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass2", "Student" }, From f8db69adf6fb74dea595f34d67dfd9ad04353ca9 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:49:19 +0100 Subject: [PATCH 45/67] test: FluentNullableNoNullableAnnotationPrivateSetClass --- .../CreateStudent.expected.txt | 19 ++++---- .../CreateStudent.g.cs | 19 ++++---- .../UsageTests.cs | 22 +++++++++ .../CodeGeneration/TestDataProvider.cs | 46 +++++++++---------- 4 files changed, 61 insertions(+), 45 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.expected.txt index 8f488bf..b8da3a6 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentNullableNoNullableAnnotationPrivateSetClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IWithName { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,26 +28,26 @@ public class CreateStudent : public static Student WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent.student; } public static Student WhoseNameIsUnknown() { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, null); + SetName(createStudent.student, null); return createStudent.student; } Student IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return student; } Student IWithName.WhoseNameIsUnknown() { - CreateStudent.namePropertyInfo.SetValue(student, null); + SetName(student, null); return student; } @@ -67,4 +61,7 @@ public class CreateStudent : Student WhoseNameIsUnknown(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.g.cs index 8f488bf..b8da3a6 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentNullableNoNullableAnnotationPrivateSetClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IWithName { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,26 +28,26 @@ public static ICreateStudent InitialStep() public static Student WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent.student; } public static Student WhoseNameIsUnknown() { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, null); + SetName(createStudent.student, null); return createStudent.student; } Student IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return student; } Student IWithName.WhoseNameIsUnknown() { - CreateStudent.namePropertyInfo.SetValue(student, null); + SetName(student, null); return student; } @@ -67,4 +61,7 @@ public interface IWithName Student WhoseNameIsUnknown(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/UsageTests.cs new file mode 100644 index 0000000..0d5e5bc --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/UsageTests.cs @@ -0,0 +1,22 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentNullableNoNullableAnnotationPrivateSetClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentNullableNoNullableAnnotationPrivateSetClass() + { + var student = CreateStudent + .WithName("Alice"); + + Assert.Equal("Alice", student.Name); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index b907273..8d96b47 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter([], + Filter(["FluentNullableNoNullableAnnotationPrivateSetClass"], new List { new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -27,29 +27,29 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClass", "Student" }, new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClassAdvanced", "Student" }, new object[] { "Abstract", "FluentApiComments", "IncompletelyCommentedPropertyClass", "Student"}, - // new object[] { "Abstract", "FluentApiComments", "RedundantCommentCompoundClass", "Student" }, - // new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass", "Student" }, - // new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass2", "Student" }, - // new object[] { "Abstract", "EmptyClass", "Student" }, - // new object[] { "Abstract", "FluentDefaultMemberClass", "Student" }, - // new object[] { "Abstract", "FluentLambdaClass", "Student|Address" }, - // new object[] { "Abstract", "FluentLambdaClassInDifferentNamespace", "Student|Address" }, - // new object[] { "Abstract", "FluentLambdaCollectionClass", "Student|Address" }, - // new object[] { "Abstract", "FluentLambdaCompoundClass", "Student|Address|Phone" }, - // new object[] { "Abstract", "FluentLambdaCompoundOfSameTypeClass", "Student|Address" }, - // new object[] { "Abstract", "FluentLambdaManyCollectionsClass", "Student|Address" }, - // new object[] { "Abstract", "FluentLambdaManyPrivateCollectionsClass", "Student|Address" }, - // new object[] { "Abstract", "FluentLambdaNullablePropertyClass", "Student|Address" }, - // new object[] { "Abstract", "FluentLambdaRecursiveClass", "Student" }, - // new object[] { "Abstract", "FluentLambdaSingleStepClass", "Student|Address" }, - // new object[] { "Abstract", "FluentMethodClass", "Student" }, - // new object[] { "Abstract", "FluentMethodDefaultValuesClass", "Student" }, - // new object[] { "Abstract", "FluentMethodParameterModifiersClass", "Student" }, - // new object[] { "Abstract", "FluentNullableClass", "Student" }, - // new object[] { "Abstract", "FluentNullableNoNullableAnnotationClass", "Student" }, - // new object[] { "Abstract", "FluentNullableNoNullableAnnotationPrivateSetClass", "Student" }, + new object[] { "Abstract", "FluentApiComments", "RedundantCommentCompoundClass", "Student" }, + new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass", "Student" }, + new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass2", "Student" }, + new object[] { "Abstract", "EmptyClass", "Student" }, + new object[] { "Abstract", "FluentDefaultMemberClass", "Student" }, + new object[] { "Abstract", "FluentLambdaClass", "Student|Address" }, + new object[] { "Abstract", "FluentLambdaClassInDifferentNamespace", "Student|Address" }, + new object[] { "Abstract", "FluentLambdaCollectionClass", "Student|Address" }, + new object[] { "Abstract", "FluentLambdaCompoundClass", "Student|Address|Phone" }, + new object[] { "Abstract", "FluentLambdaCompoundOfSameTypeClass", "Student|Address" }, + new object[] { "Abstract", "FluentLambdaManyCollectionsClass", "Student|Address" }, + new object[] { "Abstract", "FluentLambdaManyPrivateCollectionsClass", "Student|Address" }, + new object[] { "Abstract", "FluentLambdaNullablePropertyClass", "Student|Address" }, + new object[] { "Abstract", "FluentLambdaRecursiveClass", "Student" }, + new object[] { "Abstract", "FluentLambdaSingleStepClass", "Student|Address" }, + new object[] { "Abstract", "FluentMethodClass", "Student" }, + new object[] { "Abstract", "FluentMethodDefaultValuesClass", "Student" }, + new object[] { "Abstract", "FluentMethodParameterModifiersClass", "Student" }, + new object[] { "Abstract", "FluentNullableClass", "Student" }, + new object[] { "Abstract", "FluentNullableNoNullableAnnotationClass", "Student" }, + new object[] { "Abstract", "FluentNullableNoNullableAnnotationPrivateSetClass", "Student" }, // new object[] { "Abstract", "FluentReturnMultiStepClass", "Student" }, - new object[] { "Abstract", "FluentReturnMultiStepPrivateMethodsClass", "Student" }, + // new object[] { "Abstract", "FluentReturnMultiStepPrivateMethodsClass", "Student" }, // new object[] { "Abstract", "FluentReturnSingleStepClass", "Student" }, // new object[] { "Abstract", "FluentReturnSingleStepPrivateMethodsClass", "Student" }, // new object[] { "Abstract", "ForkClass", "Student" }, From c8714eff497c860b44ccd43a72371dc9669af7be Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:52:07 +0100 Subject: [PATCH 46/67] test: PublicReadonlyFieldClass --- .../CreateStudent.expected.txt | 15 +++++-------- .../CreateStudent.g.cs | 15 +++++-------- .../PublicReadonlyFieldClass/UsageTests.cs | 22 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 10 ++++----- 4 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.expected.txt index f4abb14..ad07a6d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PublicReadonlyFieldClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly FieldInfo semesterFieldInfo; - - static CreateStudent() - { - semesterFieldInfo = typeof(Student).GetField("Semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterFieldInfo.SetValue(createStudent.student, semester); + SemesterField(createStudent.student) = semester; return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterFieldInfo.SetValue(student, semester); + SemesterField(student) = semester; return student; } @@ -52,4 +46,7 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "Semester")] + private static extern ref int SemesterField(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.g.cs index f4abb14..ad07a6d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PublicReadonlyFieldClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly FieldInfo semesterFieldInfo; - - static CreateStudent() - { - semesterFieldInfo = typeof(Student).GetField("Semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterFieldInfo.SetValue(createStudent.student, semester); + SemesterField(createStudent.student) = semester; return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterFieldInfo.SetValue(student, semester); + SemesterField(student) = semester; return student; } @@ -52,4 +46,7 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "Semester")] + private static extern ref int SemesterField(Student student); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/UsageTests.cs new file mode 100644 index 0000000..03d780d --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/UsageTests.cs @@ -0,0 +1,22 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PublicReadonlyFieldClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePublicReadonlyFieldClass() + { + var student = CreateStudent + .InSemester(4); + + Assert.Equal(4, student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 8d96b47..9c228db 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(["FluentNullableNoNullableAnnotationPrivateSetClass"], + Filter([], new List { new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -38,7 +38,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "FluentLambdaCompoundClass", "Student|Address|Phone" }, new object[] { "Abstract", "FluentLambdaCompoundOfSameTypeClass", "Student|Address" }, new object[] { "Abstract", "FluentLambdaManyCollectionsClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaManyPrivateCollectionsClass", "Student|Address" }, + // new object[] { "Abstract", "FluentLambdaManyPrivateCollectionsClass", "Student|Address" }, new object[] { "Abstract", "FluentLambdaNullablePropertyClass", "Student|Address" }, new object[] { "Abstract", "FluentLambdaRecursiveClass", "Student" }, new object[] { "Abstract", "FluentLambdaSingleStepClass", "Student|Address" }, @@ -81,7 +81,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "ParameterAnnotationsPrivateConstructorClass", "Student" }, new object[] { "Abstract", "ParameterAnnotationsPublicConstructorClass", "Student" }, // new object[] { "Abstract", "PartialClass", "Student1|Student2" }, - // new object[] { "Abstract", "PredicateClass", "Student" }, + new object[] { "Abstract", "PredicateClass", "Student" }, new object[] { "Abstract", "PredicatePrivateFieldClass", "Student" }, new object[] { "Abstract", "PrivateConstructorClass", "Student" }, new object[] { "Abstract", "PrivateFieldClass", "Student" }, @@ -90,8 +90,8 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "PrivateFluentMethodParameterModifiersClass", "Student" }, new object[] { "Abstract", "PrivateReadonlyFieldClass", "Student" }, new object[] { "Abstract", "PrivateUnderscoreFieldClass", "Student" }, - // new object[] { "Abstract", "PublicFieldClass", "Student" }, - // new object[] { "Abstract", "PublicReadonlyFieldClass", "Student" }, + new object[] { "Abstract", "PublicFieldClass", "Student" }, + new object[] { "Abstract", "PublicReadonlyFieldClass", "Student" }, // new object[] { "Abstract", "SameNameMemberClass", "Student" }, // new object[] { "Abstract", "SkippableFirstMemberClass", "Student" }, // new object[] { "Abstract", "SkippableFirstTwoMembersClass", "Student" }, From 030cf4220de0ae6897c143cd911c34316d510b2f Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:54:09 +0100 Subject: [PATCH 47/67] test: PartialClass --- .../PartialClass/CreateStudent.expected.txt | 22 ++++++++--------- .../Abstract/PartialClass/CreateStudent.g.cs | 22 ++++++++--------- .../Abstract/PartialClass/UsageTests.cs | 24 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 2 +- 4 files changed, 45 insertions(+), 25 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.expected.txt index abd6770..b28a572 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PartialClass; @@ -15,14 +15,6 @@ public class CreateStudent : CreateStudent.IWithLastName { private readonly Student student; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - - static CreateStudent() - { - firstNamePropertyInfo = typeof(Student).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Student).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -37,19 +29,19 @@ public class CreateStudent : public static IWithLastName WithFirstName(string firstName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.firstNamePropertyInfo.SetValue(createStudent.student, firstName); + SetFirstName(createStudent.student, firstName); return createStudent; } IWithLastName IWithFirstName.WithFirstName(string firstName) { - CreateStudent.firstNamePropertyInfo.SetValue(student, firstName); + SetFirstName(student, firstName); return this; } Student IWithLastName.WithLastName(string lastName) { - CreateStudent.lastNamePropertyInfo.SetValue(student, lastName); + SetLastName(student, lastName); return student; } @@ -66,4 +58,10 @@ public class CreateStudent : { Student WithLastName(string lastName); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.g.cs index abd6770..b28a572 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PartialClass; @@ -15,14 +15,6 @@ public class CreateStudent : CreateStudent.IWithLastName { private readonly Student student; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - - static CreateStudent() - { - firstNamePropertyInfo = typeof(Student).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Student).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -37,19 +29,19 @@ public static ICreateStudent InitialStep() public static IWithLastName WithFirstName(string firstName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.firstNamePropertyInfo.SetValue(createStudent.student, firstName); + SetFirstName(createStudent.student, firstName); return createStudent; } IWithLastName IWithFirstName.WithFirstName(string firstName) { - CreateStudent.firstNamePropertyInfo.SetValue(student, firstName); + SetFirstName(student, firstName); return this; } Student IWithLastName.WithLastName(string lastName) { - CreateStudent.lastNamePropertyInfo.SetValue(student, lastName); + SetLastName(student, lastName); return student; } @@ -66,4 +58,10 @@ public interface IWithLastName { Student WithLastName(string lastName); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/UsageTests.cs new file mode 100644 index 0000000..29167a3 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/UsageTests.cs @@ -0,0 +1,24 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PartialClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePartialClass() + { + var student = CreateStudent + .WithFirstName("Alice") + .WithLastName("King"); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("King", student.LastName); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 9c228db..b42d6af 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -80,7 +80,7 @@ internal class TestDataProvider : IEnumerable // new object[] { "Abstract", "OverloadedMethodClass", "Student" }, new object[] { "Abstract", "ParameterAnnotationsPrivateConstructorClass", "Student" }, new object[] { "Abstract", "ParameterAnnotationsPublicConstructorClass", "Student" }, - // new object[] { "Abstract", "PartialClass", "Student1|Student2" }, + new object[] { "Abstract", "PartialClass", "Student1|Student2" }, new object[] { "Abstract", "PredicateClass", "Student" }, new object[] { "Abstract", "PredicatePrivateFieldClass", "Student" }, new object[] { "Abstract", "PrivateConstructorClass", "Student" }, From 1e508d4ed847b1022f8ef8a31ba614156c24a56c Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:57:29 +0100 Subject: [PATCH 48/67] test: TryBreakFluentApiClass1 --- .../CreateStudent.expected.txt | 22 +++++----------- .../CreateStudent.g.cs | 22 +++++----------- .../TryBreakFluentApiClass1/UsageTests.cs | 25 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 6 ++--- 4 files changed, 40 insertions(+), 35 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/CreateStudent.expected.txt index b6a12a9..be58272 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/CreateStudent.expected.txt @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass1; @@ -15,18 +14,6 @@ public class CreateStudent : CreateStudent.ISomeMethod { private readonly Student student; - private static readonly MethodInfo someMethodMethodInfo; - - static CreateStudent() - { - someMethodMethodInfo = typeof(Student).GetMethod( - "SomeMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - } private CreateStudent() { @@ -41,13 +28,13 @@ public class CreateStudent : public static Student SomeMethod(string someMethodMethodInfo) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.someMethodMethodInfo.Invoke(createStudent.student, new object?[] { someMethodMethodInfo }); + CallSomeMethod(createStudent.student, someMethodMethodInfo); return createStudent.student; } Student ISomeMethod.SomeMethod(string someMethodMethodInfo) { - CreateStudent.someMethodMethodInfo.Invoke(student, new object?[] { someMethodMethodInfo }); + CallSomeMethod(student, someMethodMethodInfo); return student; } @@ -59,4 +46,7 @@ public class CreateStudent : { Student SomeMethod(string someMethodMethodInfo); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "SomeMethod")] + private static extern void CallSomeMethod(Student student, string someMethodMethodInfo); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/CreateStudent.g.cs index b6a12a9..be58272 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/CreateStudent.g.cs @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass1; @@ -15,18 +14,6 @@ public class CreateStudent : CreateStudent.ISomeMethod { private readonly Student student; - private static readonly MethodInfo someMethodMethodInfo; - - static CreateStudent() - { - someMethodMethodInfo = typeof(Student).GetMethod( - "SomeMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - } private CreateStudent() { @@ -41,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student SomeMethod(string someMethodMethodInfo) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.someMethodMethodInfo.Invoke(createStudent.student, new object?[] { someMethodMethodInfo }); + CallSomeMethod(createStudent.student, someMethodMethodInfo); return createStudent.student; } Student ISomeMethod.SomeMethod(string someMethodMethodInfo) { - CreateStudent.someMethodMethodInfo.Invoke(student, new object?[] { someMethodMethodInfo }); + CallSomeMethod(student, someMethodMethodInfo); return student; } @@ -59,4 +46,7 @@ public interface ISomeMethod { Student SomeMethod(string someMethodMethodInfo); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "SomeMethod")] + private static extern void CallSomeMethod(Student student, string someMethodMethodInfo); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/UsageTests.cs new file mode 100644 index 0000000..e2d6d13 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/UsageTests.cs @@ -0,0 +1,25 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass1; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteTryBreakFluentApiClass1() + { + var exception = Record.Exception(() => + { + Student student = CreateStudent + .SomeMethod("hello world"); + }); + + Assert.Null(exception); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index b42d6af..8e84c80 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -105,10 +105,10 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "ThreeMemberRecordPrimaryConstructor", "Student" }, // new object[] { "Abstract", "ThreeMemberStruct", "Student" }, new object[] { "Abstract", "ThreePrivateMembersClass", "Student" }, - // new object[] { "Abstract", "ThreeMemberRecordStruct", "Student" }, - // new object[] { "Abstract", "TryBreakFluentApiClass1", "Student" }, + new object[] { "Abstract", "ThreeMemberRecordStruct", "Student" }, + new object[] { "Abstract", "TryBreakFluentApiClass1", "Student" }, // new object[] { "Abstract", "TryBreakFluentApiClass2", "Student" }, - // new object[] { "Abstract", "TryBreakFluentApiClass3", "Student|Address" }, + new object[] { "Abstract", "TryBreakFluentApiClass3", "Student|Address" }, // new object[] { "Abstract", "TwoMemberClass", "Student" }, // new object[] { "Abstract", "TwoParameterCompoundClass", "Student" }, // new object[] { "Abstract", "TwoParameterCompoundClassReversedParameters", "Student" }, From 5b98e98529ed06e53fee08e149b749d000e62d9c Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 21:58:27 +0100 Subject: [PATCH 49/67] test: TryBreakFluentApiClass2 --- .../CreateStudent.expected.txt | 22 +++++----------- .../CreateStudent.g.cs | 22 +++++----------- .../TryBreakFluentApiClass2/UsageTests.cs | 25 +++++++++++++++++++ .../CodeGeneration/TestDataProvider.cs | 2 +- 4 files changed, 38 insertions(+), 33 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/CreateStudent.expected.txt index d371a1c..7a55d65 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/CreateStudent.expected.txt @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass2; @@ -15,18 +14,6 @@ public class CreateStudent : CreateStudent.ISomeMethod { private readonly Student student; - private static readonly MethodInfo someMethodMethodInfo; - - static CreateStudent() - { - someMethodMethodInfo = typeof(Student).GetMethod( - "SomeMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - } private CreateStudent() { @@ -41,13 +28,13 @@ public class CreateStudent : public static Student SomeMethod(string createStudent) { CreateStudent createStudent2 = new CreateStudent(); - CreateStudent.someMethodMethodInfo.Invoke(createStudent2.student, new object?[] { createStudent }); + CallSomeMethod(createStudent2.student, createStudent); return createStudent2.student; } Student ISomeMethod.SomeMethod(string createStudent) { - CreateStudent.someMethodMethodInfo.Invoke(student, new object?[] { createStudent }); + CallSomeMethod(student, createStudent); return student; } @@ -59,4 +46,7 @@ public class CreateStudent : { Student SomeMethod(string createStudent); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "SomeMethod")] + private static extern void CallSomeMethod(Student student, string createStudent); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/CreateStudent.g.cs index d371a1c..7a55d65 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/CreateStudent.g.cs @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass2; @@ -15,18 +14,6 @@ public class CreateStudent : CreateStudent.ISomeMethod { private readonly Student student; - private static readonly MethodInfo someMethodMethodInfo; - - static CreateStudent() - { - someMethodMethodInfo = typeof(Student).GetMethod( - "SomeMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - } private CreateStudent() { @@ -41,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student SomeMethod(string createStudent) { CreateStudent createStudent2 = new CreateStudent(); - CreateStudent.someMethodMethodInfo.Invoke(createStudent2.student, new object?[] { createStudent }); + CallSomeMethod(createStudent2.student, createStudent); return createStudent2.student; } Student ISomeMethod.SomeMethod(string createStudent) { - CreateStudent.someMethodMethodInfo.Invoke(student, new object?[] { createStudent }); + CallSomeMethod(student, createStudent); return student; } @@ -59,4 +46,7 @@ public interface ISomeMethod { Student SomeMethod(string createStudent); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "SomeMethod")] + private static extern void CallSomeMethod(Student student, string createStudent); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/UsageTests.cs new file mode 100644 index 0000000..ad3dae3 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/UsageTests.cs @@ -0,0 +1,25 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass2; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteTryBreakFluentApiClass2() + { + var exception = Record.Exception(() => + { + Student student = CreateStudent + .SomeMethod("hello world"); + }); + + Assert.Null(exception); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 8e84c80..569a6d2 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -107,7 +107,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "ThreePrivateMembersClass", "Student" }, new object[] { "Abstract", "ThreeMemberRecordStruct", "Student" }, new object[] { "Abstract", "TryBreakFluentApiClass1", "Student" }, - // new object[] { "Abstract", "TryBreakFluentApiClass2", "Student" }, + new object[] { "Abstract", "TryBreakFluentApiClass2", "Student" }, new object[] { "Abstract", "TryBreakFluentApiClass3", "Student|Address" }, // new object[] { "Abstract", "TwoMemberClass", "Student" }, // new object[] { "Abstract", "TwoParameterCompoundClass", "Student" }, From c3784c7776eea4613d5f9738d621c15ae404756e Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 22:05:01 +0100 Subject: [PATCH 50/67] test: DocumentedStudentClass --- .../CreateDocumentedStudent.expected.txt | 84 +++++++++---------- .../CreateDocumentedStudent.g.cs | 84 +++++++++---------- .../DocumentedStudentClass/UsageTests.cs | 34 ++++++++ .../CodeGeneration/TestDataProvider.cs | 8 +- 4 files changed, 120 insertions(+), 90 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.expected.txt index 9753a24..7f3b16b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.expected.txt @@ -7,7 +7,7 @@ using System; using System.Collections.Generic; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.DocumentedStudentClass; @@ -21,32 +21,6 @@ public class CreateDocumentedStudent : CreateDocumentedStudent.IWhoseFriendsAre { private readonly DocumentedStudent documentedStudent; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - private static readonly PropertyInfo agePropertyInfo; - private static readonly MethodInfo bornOnMethodInfo; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo cityPropertyInfo; - private static readonly PropertyInfo isHappyPropertyInfo; - private static readonly PropertyInfo friendsPropertyInfo; - - static CreateDocumentedStudent() - { - firstNamePropertyInfo = typeof(DocumentedStudent).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(DocumentedStudent).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - agePropertyInfo = typeof(DocumentedStudent).GetProperty("Age", BindingFlags.Instance | BindingFlags.Public)!; - bornOnMethodInfo = typeof(DocumentedStudent).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - semesterPropertyInfo = typeof(DocumentedStudent).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - cityPropertyInfo = typeof(DocumentedStudent).GetProperty("City", BindingFlags.Instance | BindingFlags.Public)!; - isHappyPropertyInfo = typeof(DocumentedStudent).GetProperty("IsHappy", BindingFlags.Instance | BindingFlags.Public)!; - friendsPropertyInfo = typeof(DocumentedStudent).GetProperty("Friends", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateDocumentedStudent() { @@ -65,37 +39,37 @@ public class CreateDocumentedStudent : public static IOfAgeBornOn Named(string firstName, string lastName) { CreateDocumentedStudent createDocumentedStudent = new CreateDocumentedStudent(); - CreateDocumentedStudent.firstNamePropertyInfo.SetValue(createDocumentedStudent.documentedStudent, firstName); - CreateDocumentedStudent.lastNamePropertyInfo.SetValue(createDocumentedStudent.documentedStudent, lastName); + SetFirstName(createDocumentedStudent.documentedStudent, firstName); + SetLastName(createDocumentedStudent.documentedStudent, lastName); return createDocumentedStudent; } /// IOfAgeBornOn INamed.Named(string firstName, string lastName) { - CreateDocumentedStudent.firstNamePropertyInfo.SetValue(documentedStudent, firstName); - CreateDocumentedStudent.lastNamePropertyInfo.SetValue(documentedStudent, lastName); + SetFirstName(documentedStudent, firstName); + SetLastName(documentedStudent, lastName); return this; } /// IInSemester IOfAgeBornOn.OfAge(int age) { - CreateDocumentedStudent.agePropertyInfo.SetValue(documentedStudent, age); + SetAge(documentedStudent, age); return this; } /// IInSemester IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateDocumentedStudent.bornOnMethodInfo.Invoke(documentedStudent, new object?[] { dateOfBirth }); + CallBornOn(documentedStudent, dateOfBirth); return this; } /// ILivingIn IInSemester.InSemester(int semester) { - CreateDocumentedStudent.semesterPropertyInfo.SetValue(documentedStudent, semester); + SetSemester(documentedStudent, semester); return this; } @@ -108,7 +82,7 @@ public class CreateDocumentedStudent : /// IWhoIsHappy ILivingIn.LivingIn(string? city) { - CreateDocumentedStudent.cityPropertyInfo.SetValue(documentedStudent, city); + SetCity(documentedStudent, city); return this; } @@ -121,56 +95,56 @@ public class CreateDocumentedStudent : /// IWhoIsHappy ILivingIn.InUnknownCity() { - CreateDocumentedStudent.cityPropertyInfo.SetValue(documentedStudent, null); + SetCity(documentedStudent, null); return this; } /// IWhoseFriendsAre IWhoIsHappy.WhoIsHappy(bool? isHappy) { - CreateDocumentedStudent.isHappyPropertyInfo.SetValue(documentedStudent, isHappy); + SetIsHappy(documentedStudent, isHappy); return this; } /// IWhoseFriendsAre IWhoIsHappy.WhoIsSad() { - CreateDocumentedStudent.isHappyPropertyInfo.SetValue(documentedStudent, false); + SetIsHappy(documentedStudent, false); return this; } /// IWhoseFriendsAre IWhoIsHappy.WithUnknownMood() { - CreateDocumentedStudent.isHappyPropertyInfo.SetValue(documentedStudent, null); + SetIsHappy(documentedStudent, null); return this; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendsAre(System.Collections.Generic.IReadOnlyCollection friends) { - CreateDocumentedStudent.friendsPropertyInfo.SetValue(documentedStudent, friends); + SetFriends(documentedStudent, friends); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendsAre(params string[] friends) { - CreateDocumentedStudent.friendsPropertyInfo.SetValue(documentedStudent, friends); + SetFriends(documentedStudent, friends); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendIs(string friend) { - CreateDocumentedStudent.friendsPropertyInfo.SetValue(documentedStudent, new string[1]{ friend }); + SetFriends(documentedStudent, new string[1]{ friend }); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoHasNoFriends() { - CreateDocumentedStudent.friendsPropertyInfo.SetValue(documentedStudent, new string[0]); + SetFriends(documentedStudent, new string[0]); return documentedStudent; } @@ -265,4 +239,28 @@ public class CreateDocumentedStudent : /// The . DocumentedStudent WhoHasNoFriends(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(DocumentedStudent documentedStudent, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(DocumentedStudent documentedStudent, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Age")] + private static extern void SetAge(DocumentedStudent documentedStudent, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(DocumentedStudent documentedStudent, System.DateOnly dateOfBirth); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(DocumentedStudent documentedStudent, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_City")] + private static extern void SetCity(DocumentedStudent documentedStudent, string? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_IsHappy")] + private static extern void SetIsHappy(DocumentedStudent documentedStudent, bool? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Friends")] + private static extern void SetFriends(DocumentedStudent documentedStudent, System.Collections.Generic.IReadOnlyCollection value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.g.cs index 9753a24..7f3b16b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.g.cs @@ -7,7 +7,7 @@ using System; using System.Collections.Generic; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.DocumentedStudentClass; @@ -21,32 +21,6 @@ public class CreateDocumentedStudent : CreateDocumentedStudent.IWhoseFriendsAre { private readonly DocumentedStudent documentedStudent; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - private static readonly PropertyInfo agePropertyInfo; - private static readonly MethodInfo bornOnMethodInfo; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo cityPropertyInfo; - private static readonly PropertyInfo isHappyPropertyInfo; - private static readonly PropertyInfo friendsPropertyInfo; - - static CreateDocumentedStudent() - { - firstNamePropertyInfo = typeof(DocumentedStudent).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(DocumentedStudent).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - agePropertyInfo = typeof(DocumentedStudent).GetProperty("Age", BindingFlags.Instance | BindingFlags.Public)!; - bornOnMethodInfo = typeof(DocumentedStudent).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - semesterPropertyInfo = typeof(DocumentedStudent).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - cityPropertyInfo = typeof(DocumentedStudent).GetProperty("City", BindingFlags.Instance | BindingFlags.Public)!; - isHappyPropertyInfo = typeof(DocumentedStudent).GetProperty("IsHappy", BindingFlags.Instance | BindingFlags.Public)!; - friendsPropertyInfo = typeof(DocumentedStudent).GetProperty("Friends", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateDocumentedStudent() { @@ -65,37 +39,37 @@ public static ICreateDocumentedStudent InitialStep() public static IOfAgeBornOn Named(string firstName, string lastName) { CreateDocumentedStudent createDocumentedStudent = new CreateDocumentedStudent(); - CreateDocumentedStudent.firstNamePropertyInfo.SetValue(createDocumentedStudent.documentedStudent, firstName); - CreateDocumentedStudent.lastNamePropertyInfo.SetValue(createDocumentedStudent.documentedStudent, lastName); + SetFirstName(createDocumentedStudent.documentedStudent, firstName); + SetLastName(createDocumentedStudent.documentedStudent, lastName); return createDocumentedStudent; } /// IOfAgeBornOn INamed.Named(string firstName, string lastName) { - CreateDocumentedStudent.firstNamePropertyInfo.SetValue(documentedStudent, firstName); - CreateDocumentedStudent.lastNamePropertyInfo.SetValue(documentedStudent, lastName); + SetFirstName(documentedStudent, firstName); + SetLastName(documentedStudent, lastName); return this; } /// IInSemester IOfAgeBornOn.OfAge(int age) { - CreateDocumentedStudent.agePropertyInfo.SetValue(documentedStudent, age); + SetAge(documentedStudent, age); return this; } /// IInSemester IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateDocumentedStudent.bornOnMethodInfo.Invoke(documentedStudent, new object?[] { dateOfBirth }); + CallBornOn(documentedStudent, dateOfBirth); return this; } /// ILivingIn IInSemester.InSemester(int semester) { - CreateDocumentedStudent.semesterPropertyInfo.SetValue(documentedStudent, semester); + SetSemester(documentedStudent, semester); return this; } @@ -108,7 +82,7 @@ ILivingIn IInSemester.WhoStartsUniversity() /// IWhoIsHappy ILivingIn.LivingIn(string? city) { - CreateDocumentedStudent.cityPropertyInfo.SetValue(documentedStudent, city); + SetCity(documentedStudent, city); return this; } @@ -121,56 +95,56 @@ IWhoIsHappy ILivingIn.LivingInBoston() /// IWhoIsHappy ILivingIn.InUnknownCity() { - CreateDocumentedStudent.cityPropertyInfo.SetValue(documentedStudent, null); + SetCity(documentedStudent, null); return this; } /// IWhoseFriendsAre IWhoIsHappy.WhoIsHappy(bool? isHappy) { - CreateDocumentedStudent.isHappyPropertyInfo.SetValue(documentedStudent, isHappy); + SetIsHappy(documentedStudent, isHappy); return this; } /// IWhoseFriendsAre IWhoIsHappy.WhoIsSad() { - CreateDocumentedStudent.isHappyPropertyInfo.SetValue(documentedStudent, false); + SetIsHappy(documentedStudent, false); return this; } /// IWhoseFriendsAre IWhoIsHappy.WithUnknownMood() { - CreateDocumentedStudent.isHappyPropertyInfo.SetValue(documentedStudent, null); + SetIsHappy(documentedStudent, null); return this; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendsAre(System.Collections.Generic.IReadOnlyCollection friends) { - CreateDocumentedStudent.friendsPropertyInfo.SetValue(documentedStudent, friends); + SetFriends(documentedStudent, friends); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendsAre(params string[] friends) { - CreateDocumentedStudent.friendsPropertyInfo.SetValue(documentedStudent, friends); + SetFriends(documentedStudent, friends); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendIs(string friend) { - CreateDocumentedStudent.friendsPropertyInfo.SetValue(documentedStudent, new string[1]{ friend }); + SetFriends(documentedStudent, new string[1]{ friend }); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoHasNoFriends() { - CreateDocumentedStudent.friendsPropertyInfo.SetValue(documentedStudent, new string[0]); + SetFriends(documentedStudent, new string[0]); return documentedStudent; } @@ -265,4 +239,28 @@ public interface IWhoseFriendsAre /// The . DocumentedStudent WhoHasNoFriends(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(DocumentedStudent documentedStudent, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(DocumentedStudent documentedStudent, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Age")] + private static extern void SetAge(DocumentedStudent documentedStudent, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(DocumentedStudent documentedStudent, System.DateOnly dateOfBirth); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(DocumentedStudent documentedStudent, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_City")] + private static extern void SetCity(DocumentedStudent documentedStudent, string? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_IsHappy")] + private static extern void SetIsHappy(DocumentedStudent documentedStudent, bool? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Friends")] + private static extern void SetFriends(DocumentedStudent documentedStudent, System.Collections.Generic.IReadOnlyCollection value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/UsageTests.cs new file mode 100644 index 0000000..83e20a6 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/UsageTests.cs @@ -0,0 +1,34 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.DocumentedStudentClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteDocumentedStudentClass() + { + DocumentedStudent student = CreateDocumentedStudent + .Named("Alice", "King") + .BornOn(new DateOnly(2002, 7, 4)) + .InSemester(4) + .LivingInBoston() + .WhoIsHappy() + .WhoseFriendsAre("Bob"); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("King", student.LastName); + Assert.True(student.Age > 0); + Assert.Equal(4, student.Semester); + Assert.Equal("Boston", student.City); + Assert.True(student.IsHappy); + Assert.Equal(["Bob"], student.Friends); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 569a6d2..767b2df 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -109,10 +109,10 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "TryBreakFluentApiClass1", "Student" }, new object[] { "Abstract", "TryBreakFluentApiClass2", "Student" }, new object[] { "Abstract", "TryBreakFluentApiClass3", "Student|Address" }, - // new object[] { "Abstract", "TwoMemberClass", "Student" }, - // new object[] { "Abstract", "TwoParameterCompoundClass", "Student" }, - // new object[] { "Abstract", "TwoParameterCompoundClassReversedParameters", "Student" }, - // new object[] { "DocumentedStudentClass", "DocumentedStudent" }, + new object[] { "Abstract", "TwoMemberClass", "Student" }, + new object[] { "Abstract", "TwoParameterCompoundClass", "Student" }, + new object[] { "Abstract", "TwoParameterCompoundClassReversedParameters", "Student" }, + new object[] { "DocumentedStudentClass", "DocumentedStudent" }, // new object[] { "PersonClass", "Person" }, // new object[] { "StudentClass", "Student" } }).Select(l => new string[] { "..", "..", "..", "CodeGeneration", "TestClasses" } From 3a167ebd99620e148625148b6fecfa29e6e726a2 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 22:06:15 +0100 Subject: [PATCH 51/67] test: Student --- .../StudentClass/CreateStudent.expected.txt | 84 +++++++++---------- .../StudentClass/CreateStudent.g.cs | 84 +++++++++---------- .../TestClasses/StudentClass/UsageTests.cs | 34 ++++++++ .../CodeGeneration/TestDataProvider.cs | 2 +- 4 files changed, 117 insertions(+), 87 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.expected.txt index c986c10..02af185 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.expected.txt @@ -7,7 +7,7 @@ using System; using System.Collections.Generic; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.StudentClass; @@ -21,32 +21,6 @@ public class CreateStudent : CreateStudent.IWhoseFriendsAre { private readonly Student student; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - private static readonly PropertyInfo agePropertyInfo; - private static readonly MethodInfo bornOnMethodInfo; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo cityPropertyInfo; - private static readonly PropertyInfo isHappyPropertyInfo; - private static readonly PropertyInfo friendsPropertyInfo; - - static CreateStudent() - { - firstNamePropertyInfo = typeof(Student).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Student).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - agePropertyInfo = typeof(Student).GetProperty("Age", BindingFlags.Instance | BindingFlags.Public)!; - bornOnMethodInfo = typeof(Student).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - cityPropertyInfo = typeof(Student).GetProperty("City", BindingFlags.Instance | BindingFlags.Public)!; - isHappyPropertyInfo = typeof(Student).GetProperty("IsHappy", BindingFlags.Instance | BindingFlags.Public)!; - friendsPropertyInfo = typeof(Student).GetProperty("Friends", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -61,33 +35,33 @@ public class CreateStudent : public static IOfAgeBornOn Named(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.firstNamePropertyInfo.SetValue(createStudent.student, firstName); - CreateStudent.lastNamePropertyInfo.SetValue(createStudent.student, lastName); + SetFirstName(createStudent.student, firstName); + SetLastName(createStudent.student, lastName); return createStudent; } IOfAgeBornOn INamed.Named(string firstName, string lastName) { - CreateStudent.firstNamePropertyInfo.SetValue(student, firstName); - CreateStudent.lastNamePropertyInfo.SetValue(student, lastName); + SetFirstName(student, firstName); + SetLastName(student, lastName); return this; } IInSemester IOfAgeBornOn.OfAge(int age) { - CreateStudent.agePropertyInfo.SetValue(student, age); + SetAge(student, age); return this; } IInSemester IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.bornOnMethodInfo.Invoke(student, new object?[] { dateOfBirth }); + CallBornOn(student, dateOfBirth); return this; } ILivingIn IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return this; } @@ -98,7 +72,7 @@ public class CreateStudent : IWhoIsHappy ILivingIn.LivingIn(string? city) { - CreateStudent.cityPropertyInfo.SetValue(student, city); + SetCity(student, city); return this; } @@ -109,49 +83,49 @@ public class CreateStudent : IWhoIsHappy ILivingIn.InUnknownCity() { - CreateStudent.cityPropertyInfo.SetValue(student, null); + SetCity(student, null); return this; } IWhoseFriendsAre IWhoIsHappy.WhoIsHappy(bool? isHappy) { - CreateStudent.isHappyPropertyInfo.SetValue(student, isHappy); + SetIsHappy(student, isHappy); return this; } IWhoseFriendsAre IWhoIsHappy.WhoIsSad() { - CreateStudent.isHappyPropertyInfo.SetValue(student, false); + SetIsHappy(student, false); return this; } IWhoseFriendsAre IWhoIsHappy.WithUnknownMood() { - CreateStudent.isHappyPropertyInfo.SetValue(student, null); + SetIsHappy(student, null); return this; } Student IWhoseFriendsAre.WhoseFriendsAre(System.Collections.Generic.IReadOnlyCollection friends) { - CreateStudent.friendsPropertyInfo.SetValue(student, friends); + SetFriends(student, friends); return student; } Student IWhoseFriendsAre.WhoseFriendsAre(params string[] friends) { - CreateStudent.friendsPropertyInfo.SetValue(student, friends); + SetFriends(student, friends); return student; } Student IWhoseFriendsAre.WhoseFriendIs(string friend) { - CreateStudent.friendsPropertyInfo.SetValue(student, new string[1]{ friend }); + SetFriends(student, new string[1]{ friend }); return student; } Student IWhoseFriendsAre.WhoHasNoFriends() { - CreateStudent.friendsPropertyInfo.SetValue(student, new string[0]); + SetFriends(student, new string[0]); return student; } @@ -206,4 +180,28 @@ public class CreateStudent : Student WhoHasNoFriends(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Age")] + private static extern void SetAge(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Student student, System.DateOnly dateOfBirth); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_City")] + private static extern void SetCity(Student student, string? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_IsHappy")] + private static extern void SetIsHappy(Student student, bool? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Friends")] + private static extern void SetFriends(Student student, System.Collections.Generic.IReadOnlyCollection value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.g.cs index c986c10..02af185 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.g.cs @@ -7,7 +7,7 @@ using System; using System.Collections.Generic; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.StudentClass; @@ -21,32 +21,6 @@ public class CreateStudent : CreateStudent.IWhoseFriendsAre { private readonly Student student; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - private static readonly PropertyInfo agePropertyInfo; - private static readonly MethodInfo bornOnMethodInfo; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo cityPropertyInfo; - private static readonly PropertyInfo isHappyPropertyInfo; - private static readonly PropertyInfo friendsPropertyInfo; - - static CreateStudent() - { - firstNamePropertyInfo = typeof(Student).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Student).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - agePropertyInfo = typeof(Student).GetProperty("Age", BindingFlags.Instance | BindingFlags.Public)!; - bornOnMethodInfo = typeof(Student).GetMethod( - "BornOn", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(System.DateOnly) }, - null)!; - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - cityPropertyInfo = typeof(Student).GetProperty("City", BindingFlags.Instance | BindingFlags.Public)!; - isHappyPropertyInfo = typeof(Student).GetProperty("IsHappy", BindingFlags.Instance | BindingFlags.Public)!; - friendsPropertyInfo = typeof(Student).GetProperty("Friends", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -61,33 +35,33 @@ public static ICreateStudent InitialStep() public static IOfAgeBornOn Named(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.firstNamePropertyInfo.SetValue(createStudent.student, firstName); - CreateStudent.lastNamePropertyInfo.SetValue(createStudent.student, lastName); + SetFirstName(createStudent.student, firstName); + SetLastName(createStudent.student, lastName); return createStudent; } IOfAgeBornOn INamed.Named(string firstName, string lastName) { - CreateStudent.firstNamePropertyInfo.SetValue(student, firstName); - CreateStudent.lastNamePropertyInfo.SetValue(student, lastName); + SetFirstName(student, firstName); + SetLastName(student, lastName); return this; } IInSemester IOfAgeBornOn.OfAge(int age) { - CreateStudent.agePropertyInfo.SetValue(student, age); + SetAge(student, age); return this; } IInSemester IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.bornOnMethodInfo.Invoke(student, new object?[] { dateOfBirth }); + CallBornOn(student, dateOfBirth); return this; } ILivingIn IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return this; } @@ -98,7 +72,7 @@ ILivingIn IInSemester.WhoStartsUniversity() IWhoIsHappy ILivingIn.LivingIn(string? city) { - CreateStudent.cityPropertyInfo.SetValue(student, city); + SetCity(student, city); return this; } @@ -109,49 +83,49 @@ IWhoIsHappy ILivingIn.LivingInBoston() IWhoIsHappy ILivingIn.InUnknownCity() { - CreateStudent.cityPropertyInfo.SetValue(student, null); + SetCity(student, null); return this; } IWhoseFriendsAre IWhoIsHappy.WhoIsHappy(bool? isHappy) { - CreateStudent.isHappyPropertyInfo.SetValue(student, isHappy); + SetIsHappy(student, isHappy); return this; } IWhoseFriendsAre IWhoIsHappy.WhoIsSad() { - CreateStudent.isHappyPropertyInfo.SetValue(student, false); + SetIsHappy(student, false); return this; } IWhoseFriendsAre IWhoIsHappy.WithUnknownMood() { - CreateStudent.isHappyPropertyInfo.SetValue(student, null); + SetIsHappy(student, null); return this; } Student IWhoseFriendsAre.WhoseFriendsAre(System.Collections.Generic.IReadOnlyCollection friends) { - CreateStudent.friendsPropertyInfo.SetValue(student, friends); + SetFriends(student, friends); return student; } Student IWhoseFriendsAre.WhoseFriendsAre(params string[] friends) { - CreateStudent.friendsPropertyInfo.SetValue(student, friends); + SetFriends(student, friends); return student; } Student IWhoseFriendsAre.WhoseFriendIs(string friend) { - CreateStudent.friendsPropertyInfo.SetValue(student, new string[1]{ friend }); + SetFriends(student, new string[1]{ friend }); return student; } Student IWhoseFriendsAre.WhoHasNoFriends() { - CreateStudent.friendsPropertyInfo.SetValue(student, new string[0]); + SetFriends(student, new string[0]); return student; } @@ -206,4 +180,28 @@ public interface IWhoseFriendsAre Student WhoHasNoFriends(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Age")] + private static extern void SetAge(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "BornOn")] + private static extern void CallBornOn(Student student, System.DateOnly dateOfBirth); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_City")] + private static extern void SetCity(Student student, string? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_IsHappy")] + private static extern void SetIsHappy(Student student, bool? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Friends")] + private static extern void SetFriends(Student student, System.Collections.Generic.IReadOnlyCollection value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/UsageTests.cs new file mode 100644 index 0000000..bec4cd0 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/UsageTests.cs @@ -0,0 +1,34 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.StudentClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteStudentClass() + { + Student student = CreateStudent + .Named("Alice", "King") + .BornOn(new DateOnly(2002, 7, 4)) + .InSemester(4) + .LivingInBoston() + .WhoIsHappy() + .WhoseFriendsAre("Bob"); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("King", student.LastName); + Assert.True(student.Age > 0); + Assert.Equal(4, student.Semester); + Assert.Equal("Boston", student.City); + Assert.True(student.IsHappy); + Assert.Equal(["Bob"], student.Friends); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 767b2df..1c59f7b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -114,7 +114,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "TwoParameterCompoundClassReversedParameters", "Student" }, new object[] { "DocumentedStudentClass", "DocumentedStudent" }, // new object[] { "PersonClass", "Person" }, - // new object[] { "StudentClass", "Student" } + new object[] { "StudentClass", "Student" } }).Select(l => new string[] { "..", "..", "..", "CodeGeneration", "TestClasses" } .Concat(l).Reverse().ToArray()).ToList(); // reversed for better readability in the unit test panel From 15ea6dfc16e5a6602236afbab1b5ea3304f4e2d4 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Mon, 29 Dec 2025 22:06:51 +0100 Subject: [PATCH 52/67] test: ThreeMemberStruct --- src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 1c59f7b..6c4ab27 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -103,7 +103,7 @@ internal class TestDataProvider : IEnumerable // new object[] { "Abstract", "ThreeMemberClass", "Student" }, // new object[] { "Abstract", "ThreeMemberRecord", "Student" }, new object[] { "Abstract", "ThreeMemberRecordPrimaryConstructor", "Student" }, - // new object[] { "Abstract", "ThreeMemberStruct", "Student" }, + new object[] { "Abstract", "ThreeMemberStruct", "Student" }, new object[] { "Abstract", "ThreePrivateMembersClass", "Student" }, new object[] { "Abstract", "ThreeMemberRecordStruct", "Student" }, new object[] { "Abstract", "TryBreakFluentApiClass1", "Student" }, From 2a0f619652e9141a344d04375fff866bd6c20886 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 07:53:38 +0100 Subject: [PATCH 53/67] usage test: ContinueWithInForkClass --- .../CodeGenerationExecutionTests.cs | 1356 ++++++++--------- .../ContinueWithInForkClass/UsageTests.cs | 44 + .../ContinueWithSelfClass/UsageTests.cs | 4 +- 3 files changed, 709 insertions(+), 695 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithInForkClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs index 1130411..46c43d5 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs @@ -1,693 +1,663 @@ -// #define TEST_GENERATED_CODE -// #if TEST_GENERATED_CODE -// -// // ReSharper disable NotAccessedVariable -// -// using System; -// using System.Collections.Generic; -// using System.Reflection; -// using M31.FluentApi.Tests.CodeGeneration.Helpers; -// using Xunit; -// using Xunit.Priority; -// -// namespace M31.FluentApi.Tests.CodeGeneration; -// -// public partial class CodeGenerationTests -// { -// [Fact, Priority(1)] -// public void CanExecuteContinueWithInForkClass() -// { -// { -// var student = TestClasses.Abstract.ContinueWithInForkClass -// .CreateStudent -// .WithMember1("1") -// .WithMember2A("2A") -// .WithMember3("3") -// .WithMember4("4"); -// -// Assert.Equal("1", student.Member1); -// Assert.Equal("2A", student.Member2A); -// Assert.Null(student.Member2B); -// Assert.Equal("3", student.Member3); -// Assert.Equal("4", student.Member4); -// } -// { -// var student = TestClasses.Abstract.ContinueWithInForkClass -// .CreateStudent -// .WithMember1("1") -// .WithMember2B("2B") -// .WithMember4("4"); -// -// Assert.Equal("1", student.Member1); -// Assert.Null(student.Member2A); -// Assert.Equal("2B", student.Member2B); -// Assert.Null(student.Member3); -// Assert.Equal("4", student.Member4); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentLambdaClass() -// { -// var student = TestClasses.Abstract.FluentLambdaClass -// .CreateStudent -// .WithName("Alice") -// .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal("23", student.Address.HouseNumber); -// Assert.Equal("Market Street", student.Address.Street); -// Assert.Equal("San Francisco", student.Address.City); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentLambdaCollectionClass() -// { -// var student = TestClasses.Abstract.FluentLambdaCollectionClass -// .CreateStudent -// .WithName("Alice") -// .WithAddresses( -// a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), -// a => a.WithHouseNumber("108").WithStreet("5th Avenue").InCity("New York")); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(2, student.Addresses.Count); -// Assert.Equal("23", student.Addresses[0].HouseNumber); -// Assert.Equal("Market Street", student.Addresses[0].Street); -// Assert.Equal("San Francisco", student.Addresses[0].City); -// Assert.Equal("108", student.Addresses[1].HouseNumber); -// Assert.Equal("5th Avenue", student.Addresses[1].Street); -// Assert.Equal("New York", student.Addresses[1].City); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentLambdaCompoundClass() -// { -// var student = TestClasses.Abstract.FluentLambdaCompoundClass -// .CreateStudent -// .WithName("Alice") -// .WithDetails( -// a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), -// p => p.WithNumber("222-222-2222").WithUsage("CELL")); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal("23", student.Address.HouseNumber); -// Assert.Equal("Market Street", student.Address.Street); -// Assert.Equal("San Francisco", student.Address.City); -// Assert.Equal("222-222-2222", student.Phone.Number); -// Assert.Equal("CELL", student.Phone.Usage); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentLambdaManyCollectionsClass() -// { -// { -// var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass -// .CreateStudent -// .WithName("Alice") -// .WithAddressesE(createAddressesE: null); -// -// Assert.Equal("Alice", student.Name); -// Assert.Null(student.AddressesE); -// } -// { -// var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass -// .CreateStudent -// .WithName("Alice") -// .WithAddressesF(createAddressesF: _ => null); -// -// Assert.Single(student.AddressesF); -// Assert.Null(student.AddressesF[0]); -// } -// { -// var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass -// .CreateStudent -// .WithName("Alice") -// .WithAddressesG(createAddressesG: null); -// -// Assert.Equal("Alice", student.Name); -// Assert.Null(student.AddressesG); -// } -// { -// var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass -// .CreateStudent -// .WithName("Alice") -// .WithAddressesG(createAddressesG: _ => null); -// -// Assert.Equal("Alice", student.Name); -// Assert.NotNull(student.AddressesG); -// Assert.Single(student.AddressesG!); -// Assert.Null(student.AddressesG![0]); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentLambdaManyPrivateCollectionsClass() -// { -// { -// var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass -// .CreateStudent -// .WithName("Alice") -// .WithAddressesE(createAddressesE: null); -// -// Assert.Equal("Alice", student.Name); -// Assert.Null(student.AddressesE); -// } -// { -// var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass -// .CreateStudent -// .WithName("Alice") -// .WithAddressesF(createAddressesF: _ => null); -// -// Assert.Single(student.AddressesF); -// Assert.Null(student.AddressesF[0]); -// } -// { -// var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass -// .CreateStudent -// .WithName("Alice") -// .WithAddressesG(createAddressesG: null); -// -// Assert.Equal("Alice", student.Name); -// Assert.Null(student.AddressesG); -// } -// { -// var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass -// .CreateStudent -// .WithName("Alice") -// .WithAddressesG(createAddressesG: _ => null); -// -// Assert.Equal("Alice", student.Name); -// Assert.NotNull(student.AddressesG); -// Assert.Single(student.AddressesG!); -// Assert.Null(student.AddressesG![0]); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentLambdaNullablePropertyClass() -// { -// { -// var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass -// .CreateStudent -// .WithName("Alice") -// .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal("23", student.Address!.HouseNumber); -// Assert.Equal("Market Street", student.Address!.Street); -// Assert.Equal("San Francisco", student.Address!.City); -// } -// { -// var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass -// .CreateStudent -// .WithName("Alice") -// .WithoutAddress(); -// -// Assert.Equal("Alice", student.Name); -// Assert.Null(student.Address); -// } -// { -// var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass -// .CreateStudent -// .WithName("Alice") -// .WithAddress(_ => null); -// -// Assert.Equal("Alice", student.Name); -// Assert.Null(student.Address); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentLambdaRecursiveClass() -// { -// var student = TestClasses.Abstract.FluentLambdaRecursiveClass -// .CreateStudent -// .WithName("Alice") -// .WithFriend(f => f -// .WithName("Bob") -// .WithFriend(f2 => f2 -// .WithName("Eve") -// .WithoutFriend())); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal("Bob", student.Friend!.Name); -// Assert.Equal("Eve", student.Friend!.Friend!.Name); -// Assert.Null(student.Friend!.Friend!.Friend); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentLambdaSingleStepClass() -// { -// var student = TestClasses.Abstract.FluentLambdaSingleStepClass -// .CreateStudent -// .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); -// -// Assert.Equal("23", student.Address.HouseNumber); -// Assert.Equal("Market Street", student.Address.Street); -// Assert.Equal("San Francisco", student.Address.City); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentMethodClass() -// { -// var student = TestClasses.Abstract.FluentMethodClass -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); -// Assert.Equal(2, student.Semester); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentReturnMultiStepPrivateMethodsClass() -// { -// { -// TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass -// .CreateStudent.WithName("Alice").ReturnVoidMethod(); -// } -// { -// int result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass -// .CreateStudent.WithName("Alice").ReturnIntMethod(); -// Assert.Equal(24, result); -// } -// { -// string string1 = "string1"; -// int result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass -// .CreateStudent.WithName("Alice").ReturnIntMethodWithRefParameter(ref string1); -// Assert.Equal(28, result); -// } -// { -// List result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass -// .CreateStudent.WithName("Alice").ReturnListMethod(); -// Assert.Equal(new List() { 1, 2, 3 }, result); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteFluentReturnSingleStepPrivateMethodsClass() -// { -// { -// TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass -// .CreateStudent.ReturnVoidMethod(); -// } -// { -// int result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass -// .CreateStudent.ReturnIntMethod(); -// Assert.Equal(24, result); -// } -// { -// string string1 = "string1"; -// int result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass -// .CreateStudent.ReturnIntMethodWithRefParameter(ref string1); -// Assert.Equal(28, result); -// } -// { -// List result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass -// .CreateStudent.ReturnListMethod(); -// Assert.Equal(new List() { 1, 2, 3 }, result); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteGenericClassWithGenericMethods() -// { -// var student = TestClasses.Abstract.GenericClassWithGenericMethods -// .CreateStudent -// .WithProperty1("property1") -// .WithProperty2(null) -// .WithProperty3(0) -// .WithProperty4(0) -// .WithProperty5(0) -// .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) -// .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), -// new List()) -// .Method3, Dictionary, List>("string1"); -// -// string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; -// Assert.Equal(expectedLogs, student.Logs); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteGenericClassWithPrivateGenericMethods() -// { -// var student = TestClasses.Abstract.GenericClassWithPrivateGenericMethods -// .CreateStudent -// .WithProperty1("property1") -// .WithProperty2(null) -// .WithProperty3(0) -// .WithProperty4(0) -// .WithProperty5(0) -// .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) -// .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), -// new List()) -// .Method3, Dictionary, List>("string1"); -// -// string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; -// Assert.Equal(expectedLogs, student.Logs); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteGenericOverloadedMethodClass() -// { -// { -// var student = TestClasses.Abstract.GenericOverloadedMethodClass -// .CreateStudent.Method1(0, "string1"); -// Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); -// } -// { -// var student = TestClasses.Abstract.GenericOverloadedMethodClass -// .CreateStudent.Method1(0, "string1"); -// Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); -// } -// { -// var student = TestClasses.Abstract.GenericOverloadedMethodClass -// .CreateStudent.Method1("string1", "string2"); -// Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); -// } -// { -// var student = TestClasses.Abstract.GenericOverloadedMethodClass -// .CreateStudent.Method1(0, "string1"); -// Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); -// } -// { -// string string1 = "string1"; -// var student = TestClasses.Abstract.GenericOverloadedMethodClass -// .CreateStudent.Method1(0, out string1); -// Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); -// } -// { -// int i = 0; -// var student = TestClasses.Abstract.GenericOverloadedMethodClass -// .CreateStudent.Method1(in i, "string1"); -// Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); -// } -// { -// int i = 0; -// string string1 = "string1"; -// var student = TestClasses.Abstract.GenericOverloadedMethodClass -// .CreateStudent.Method1(in i, ref string1); -// Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteGenericOverloadedPrivateMethodClass() -// { -// { -// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass -// .CreateStudent.Method1(0, "string1"); -// Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); -// } -// { -// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass -// .CreateStudent.Method1(0, "string1"); -// Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); -// } -// { -// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass -// .CreateStudent.Method1("string1", "string2"); -// Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); -// } -// { -// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass -// .CreateStudent.Method1(0, "string1"); -// Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); -// } -// { -// string string1 = "string1"; -// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass -// .CreateStudent.Method1(0, out string1); -// Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); -// } -// { -// int i = 0; -// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass -// .CreateStudent.Method1(in i, "string1"); -// Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); -// } -// { -// int i = 0; -// string string1 = "string"; -// var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass -// .CreateStudent.Method1(in i, ref string1); -// Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteInheritedClass() -// { -// var student = TestClasses.Abstract.InheritedClass -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); -// Assert.Equal(2, student.Semester); -// } -// -// -// [Fact, Priority(1)] -// public void CanExecuteInheritedClassProtectedMembers() -// { -// var student = TestClasses.Abstract.InheritedClassProtectedMembers -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", GetProperty("Name")); -// Assert.Equal(new DateOnly(2002, 8, 3), GetProperty("DateOfBirth")); -// Assert.Equal(2, GetProperty("Semester")); -// -// object GetProperty(string propertyName) -// { -// return typeof(TestClasses.Abstract.InheritedClassProtectedMembers.Student) -// .GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic)? -// .GetValue(student)!; -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteInheritedClassProtectedSetters() -// { -// var student = TestClasses.Abstract.InheritedClassProtectedSetters -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); -// Assert.Equal(2, student.Semester); -// } -// -// -// [Fact, Priority(1)] -// public void CanExecutePartialClass() -// { -// var student = TestClasses.Abstract.PartialClass -// .CreateStudent -// .WithFirstName("Alice") -// .WithLastName("King"); -// -// Assert.Equal("Alice", student.FirstName); -// Assert.Equal("King", student.LastName); -// } -// -// [Fact, Priority(1)] -// public void CanExecutePrivateConstructorClass() -// { -// var student = TestClasses.Abstract.PrivateConstructorClass -// .CreateStudent -// .InSemester(2); -// -// Assert.Equal(2, student.Semester); -// } -// -// [Fact, Priority(1)] -// public void CanExecutePrivateFieldClass() -// { -// var student = TestClasses.Abstract.PrivateFieldClass -// .CreateStudent -// .InSemester(2); -// -// Assert.Equal(2, student.Semester); -// } -// -// [Fact, Priority(1)] -// public void CanExecutePrivateFluentMethodClass() -// { -// var student = TestClasses.Abstract.PrivateFluentMethodClass -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); -// Assert.Equal(2, student.Semester); -// } -// -// [Fact, Priority(1)] -// public void CanExecutePrivateMethodFluentNullableParameterClass() -// { -// var student = TestClasses.Abstract.PrivateFluentMethodNullableParameterClass -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(null); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); -// Assert.Null(student.Semester); -// } -// -// [Fact, Priority(1)] -// public void CanExecutePublicReadonlyFieldClass() -// { -// var student = TestClasses.Abstract.PublicReadonlyFieldClass -// .CreateStudent -// .InSemester(2); -// -// Assert.Equal(2, student.Semester); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteSkippableMemberClass() -// { -// { -// var student = TestClasses.Abstract.SkippableMemberClass -// .CreateStudent -// .WithFirstName("Alice") -// .WithMiddleName("Sophia") -// .WithLastName("King"); -// -// Assert.Equal("Alice", student.FirstName); -// Assert.Equal("Sophia", student.MiddleName); -// Assert.Equal("King", student.LastName); -// } -// { -// var student = TestClasses.Abstract.SkippableMemberClass -// .CreateStudent -// .WithFirstName("Alice") -// .WithLastName("King"); -// -// Assert.Equal("Alice", student.FirstName); -// Assert.Null(student.MiddleName); -// Assert.Equal("King", student.LastName); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteSkippableFirstMemberClass() -// { -// { -// var student = TestClasses.Abstract.SkippableFirstMemberClass -// .CreateStudent -// .WithFirstName("Alice") -// .WithLastName("King"); -// -// Assert.Equal("Alice", student.FirstName); -// Assert.Equal("King", student.LastName); -// } -// { -// var student = TestClasses.Abstract.SkippableFirstMemberClass -// .CreateStudent -// .WithLastName("King"); -// -// Assert.Null(student.FirstName); -// Assert.Equal("King", student.LastName); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteSkippableLoopClass() -// { -// var student = TestClasses.Abstract.SkippableLoopClass -// .CreateStudent -// .WithMember3("3") -// .WithMember1("1") -// .WithMember4("4"); -// -// Assert.Equal("1", student.Member1); -// Assert.Null(student.Member2); -// Assert.Equal("3", student.Member3); -// Assert.Equal("4", student.Member4); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteSkippableSeveralMembersClass() -// { -// { -// var student = TestClasses.Abstract.SkippableSeveralMembersClass -// .CreateStudent -// .WithMember2("2") -// .WithMember4("4"); -// -// Assert.Null(student.Member1); -// Assert.Equal("2", student.Member2); -// Assert.Null(student.Member3); -// Assert.Equal("4", student.Member4); -// } -// { -// var student = TestClasses.Abstract.SkippableSeveralMembersClass -// .CreateStudent -// .WithMember4("4"); -// -// Assert.Null(student.Member1); -// Assert.Null(student.Member2); -// Assert.Null(student.Member3); -// Assert.Equal("4", student.Member4); -// } -// } -// -// [Fact, Priority(1)] -// public void CanExecuteThreeMemberClass() -// { -// var student = TestClasses.Abstract.ThreeMemberClass -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); -// Assert.Equal(2, student.Semester); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteThreeMemberRecordPrimaryConstructor() -// { -// var student = TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", student.name); -// Assert.Equal(new DateOnly(2002, 8, 3), student.dateOfBirth); -// Assert.Equal(2, student.semester); -// } -// -// [Fact, Priority(1)] -// public void CanExecuteThreePrivateMembersClass() -// { -// var student = TestClasses.Abstract.ThreePrivateMembersClass -// .CreateStudent -// .WithName("Alice") -// .BornOn(new DateOnly(2002, 8, 3)) -// .InSemester(2); -// -// Assert.Equal("Alice", student.Name); -// Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); -// Assert.Equal(2, student.Semester); -// } -// } -// #endif \ No newline at end of file +#define TEST_GENERATED_CODE +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using System.Collections.Generic; +using System.Reflection; +using M31.FluentApi.Tests.CodeGeneration.Helpers; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration; + +public partial class CodeGenerationTests +{ + + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaClass() + { + var student = TestClasses.Abstract.FluentLambdaClass + .CreateStudent + .WithName("Alice") + .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); + + Assert.Equal("Alice", student.Name); + Assert.Equal("23", student.Address.HouseNumber); + Assert.Equal("Market Street", student.Address.Street); + Assert.Equal("San Francisco", student.Address.City); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaCollectionClass() + { + var student = TestClasses.Abstract.FluentLambdaCollectionClass + .CreateStudent + .WithName("Alice") + .WithAddresses( + a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), + a => a.WithHouseNumber("108").WithStreet("5th Avenue").InCity("New York")); + + Assert.Equal("Alice", student.Name); + Assert.Equal(2, student.Addresses.Count); + Assert.Equal("23", student.Addresses[0].HouseNumber); + Assert.Equal("Market Street", student.Addresses[0].Street); + Assert.Equal("San Francisco", student.Addresses[0].City); + Assert.Equal("108", student.Addresses[1].HouseNumber); + Assert.Equal("5th Avenue", student.Addresses[1].Street); + Assert.Equal("New York", student.Addresses[1].City); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaCompoundClass() + { + var student = TestClasses.Abstract.FluentLambdaCompoundClass + .CreateStudent + .WithName("Alice") + .WithDetails( + a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), + p => p.WithNumber("222-222-2222").WithUsage("CELL")); + + Assert.Equal("Alice", student.Name); + Assert.Equal("23", student.Address.HouseNumber); + Assert.Equal("Market Street", student.Address.Street); + Assert.Equal("San Francisco", student.Address.City); + Assert.Equal("222-222-2222", student.Phone.Number); + Assert.Equal("CELL", student.Phone.Usage); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaManyCollectionsClass() + { + { + var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass + .CreateStudent + .WithName("Alice") + .WithAddressesE(createAddressesE: null); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.AddressesE); + } + { + var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass + .CreateStudent + .WithName("Alice") + .WithAddressesF(createAddressesF: _ => null); + + Assert.Single(student.AddressesF); + Assert.Null(student.AddressesF[0]); + } + { + var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass + .CreateStudent + .WithName("Alice") + .WithAddressesG(createAddressesG: null); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.AddressesG); + } + { + var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass + .CreateStudent + .WithName("Alice") + .WithAddressesG(createAddressesG: _ => null); + + Assert.Equal("Alice", student.Name); + Assert.NotNull(student.AddressesG); + Assert.Single(student.AddressesG!); + Assert.Null(student.AddressesG![0]); + } + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaManyPrivateCollectionsClass() + { + { + var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass + .CreateStudent + .WithName("Alice") + .WithAddressesE(createAddressesE: null); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.AddressesE); + } + { + var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass + .CreateStudent + .WithName("Alice") + .WithAddressesF(createAddressesF: _ => null); + + Assert.Single(student.AddressesF); + Assert.Null(student.AddressesF[0]); + } + { + var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass + .CreateStudent + .WithName("Alice") + .WithAddressesG(createAddressesG: null); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.AddressesG); + } + { + var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass + .CreateStudent + .WithName("Alice") + .WithAddressesG(createAddressesG: _ => null); + + Assert.Equal("Alice", student.Name); + Assert.NotNull(student.AddressesG); + Assert.Single(student.AddressesG!); + Assert.Null(student.AddressesG![0]); + } + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaNullablePropertyClass() + { + { + var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass + .CreateStudent + .WithName("Alice") + .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); + + Assert.Equal("Alice", student.Name); + Assert.Equal("23", student.Address!.HouseNumber); + Assert.Equal("Market Street", student.Address!.Street); + Assert.Equal("San Francisco", student.Address!.City); + } + { + var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass + .CreateStudent + .WithName("Alice") + .WithoutAddress(); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.Address); + } + { + var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass + .CreateStudent + .WithName("Alice") + .WithAddress(_ => null); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.Address); + } + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaRecursiveClass() + { + var student = TestClasses.Abstract.FluentLambdaRecursiveClass + .CreateStudent + .WithName("Alice") + .WithFriend(f => f + .WithName("Bob") + .WithFriend(f2 => f2 + .WithName("Eve") + .WithoutFriend())); + + Assert.Equal("Alice", student.Name); + Assert.Equal("Bob", student.Friend!.Name); + Assert.Equal("Eve", student.Friend!.Friend!.Name); + Assert.Null(student.Friend!.Friend!.Friend); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaSingleStepClass() + { + var student = TestClasses.Abstract.FluentLambdaSingleStepClass + .CreateStudent + .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); + + Assert.Equal("23", student.Address.HouseNumber); + Assert.Equal("Market Street", student.Address.Street); + Assert.Equal("San Francisco", student.Address.City); + } + + [Fact, Priority(1)] + public void CanExecuteFluentMethodClass() + { + var student = TestClasses.Abstract.FluentMethodClass + .CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } + + [Fact, Priority(1)] + public void CanExecuteFluentReturnMultiStepPrivateMethodsClass() + { + { + TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass + .CreateStudent.WithName("Alice").ReturnVoidMethod(); + } + { + int result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass + .CreateStudent.WithName("Alice").ReturnIntMethod(); + Assert.Equal(24, result); + } + { + string string1 = "string1"; + int result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass + .CreateStudent.WithName("Alice").ReturnIntMethodWithRefParameter(ref string1); + Assert.Equal(28, result); + } + { + List result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass + .CreateStudent.WithName("Alice").ReturnListMethod(); + Assert.Equal(new List() { 1, 2, 3 }, result); + } + } + + [Fact, Priority(1)] + public void CanExecuteFluentReturnSingleStepPrivateMethodsClass() + { + { + TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass + .CreateStudent.ReturnVoidMethod(); + } + { + int result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass + .CreateStudent.ReturnIntMethod(); + Assert.Equal(24, result); + } + { + string string1 = "string1"; + int result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass + .CreateStudent.ReturnIntMethodWithRefParameter(ref string1); + Assert.Equal(28, result); + } + { + List result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass + .CreateStudent.ReturnListMethod(); + Assert.Equal(new List() { 1, 2, 3 }, result); + } + } + + [Fact, Priority(1)] + public void CanExecuteGenericClassWithGenericMethods() + { + var student = TestClasses.Abstract.GenericClassWithGenericMethods + .CreateStudent + .WithProperty1("property1") + .WithProperty2(null) + .WithProperty3(0) + .WithProperty4(0) + .WithProperty5(0) + .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) + .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), + new List()) + .Method3, Dictionary, List>("string1"); + + string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; + Assert.Equal(expectedLogs, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericClassWithPrivateGenericMethods() + { + var student = TestClasses.Abstract.GenericClassWithPrivateGenericMethods + .CreateStudent + .WithProperty1("property1") + .WithProperty2(null) + .WithProperty3(0) + .WithProperty4(0) + .WithProperty5(0) + .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) + .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), + new List()) + .Method3, Dictionary, List>("string1"); + + string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; + Assert.Equal(expectedLogs, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedMethodClass() + { + { + var student = TestClasses.Abstract.GenericOverloadedMethodClass + .CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); + } + { + var student = TestClasses.Abstract.GenericOverloadedMethodClass + .CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); + } + { + var student = TestClasses.Abstract.GenericOverloadedMethodClass + .CreateStudent.Method1("string1", "string2"); + Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); + } + { + var student = TestClasses.Abstract.GenericOverloadedMethodClass + .CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); + } + { + string string1 = "string1"; + var student = TestClasses.Abstract.GenericOverloadedMethodClass + .CreateStudent.Method1(0, out string1); + Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); + } + { + int i = 0; + var student = TestClasses.Abstract.GenericOverloadedMethodClass + .CreateStudent.Method1(in i, "string1"); + Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); + } + { + int i = 0; + string string1 = "string1"; + var student = TestClasses.Abstract.GenericOverloadedMethodClass + .CreateStudent.Method1(in i, ref string1); + Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); + } + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedPrivateMethodClass() + { + { + var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass + .CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); + } + { + var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass + .CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); + } + { + var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass + .CreateStudent.Method1("string1", "string2"); + Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); + } + { + var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass + .CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); + } + { + string string1 = "string1"; + var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass + .CreateStudent.Method1(0, out string1); + Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); + } + { + int i = 0; + var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass + .CreateStudent.Method1(in i, "string1"); + Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); + } + { + int i = 0; + string string1 = "string"; + var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass + .CreateStudent.Method1(in i, ref string1); + Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); + } + } + + [Fact, Priority(1)] + public void CanExecuteInheritedClass() + { + var student = TestClasses.Abstract.InheritedClass + .CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } + + + [Fact, Priority(1)] + public void CanExecuteInheritedClassProtectedMembers() + { + var student = TestClasses.Abstract.InheritedClassProtectedMembers + .CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", GetProperty("Name")); + Assert.Equal(new DateOnly(2002, 8, 3), GetProperty("DateOfBirth")); + Assert.Equal(2, GetProperty("Semester")); + + object GetProperty(string propertyName) + { + return typeof(TestClasses.Abstract.InheritedClassProtectedMembers.Student) + .GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic)? + .GetValue(student)!; + } + } + + [Fact, Priority(1)] + public void CanExecuteInheritedClassProtectedSetters() + { + var student = TestClasses.Abstract.InheritedClassProtectedSetters + .CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } + + + [Fact, Priority(1)] + public void CanExecutePartialClass() + { + var student = TestClasses.Abstract.PartialClass + .CreateStudent + .WithFirstName("Alice") + .WithLastName("King"); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("King", student.LastName); + } + + [Fact, Priority(1)] + public void CanExecutePrivateConstructorClass() + { + var student = TestClasses.Abstract.PrivateConstructorClass + .CreateStudent + .InSemester(2); + + Assert.Equal(2, student.Semester); + } + + [Fact, Priority(1)] + public void CanExecutePrivateFieldClass() + { + var student = TestClasses.Abstract.PrivateFieldClass + .CreateStudent + .InSemester(2); + + Assert.Equal(2, student.Semester); + } + + [Fact, Priority(1)] + public void CanExecutePrivateFluentMethodClass() + { + var student = TestClasses.Abstract.PrivateFluentMethodClass + .CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } + + [Fact, Priority(1)] + public void CanExecutePrivateMethodFluentNullableParameterClass() + { + var student = TestClasses.Abstract.PrivateFluentMethodNullableParameterClass + .CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(null); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Null(student.Semester); + } + + [Fact, Priority(1)] + public void CanExecutePublicReadonlyFieldClass() + { + var student = TestClasses.Abstract.PublicReadonlyFieldClass + .CreateStudent + .InSemester(2); + + Assert.Equal(2, student.Semester); + } + + [Fact, Priority(1)] + public void CanExecuteSkippableMemberClass() + { + { + var student = TestClasses.Abstract.SkippableMemberClass + .CreateStudent + .WithFirstName("Alice") + .WithMiddleName("Sophia") + .WithLastName("King"); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("Sophia", student.MiddleName); + Assert.Equal("King", student.LastName); + } + { + var student = TestClasses.Abstract.SkippableMemberClass + .CreateStudent + .WithFirstName("Alice") + .WithLastName("King"); + + Assert.Equal("Alice", student.FirstName); + Assert.Null(student.MiddleName); + Assert.Equal("King", student.LastName); + } + } + + [Fact, Priority(1)] + public void CanExecuteSkippableFirstMemberClass() + { + { + var student = TestClasses.Abstract.SkippableFirstMemberClass + .CreateStudent + .WithFirstName("Alice") + .WithLastName("King"); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("King", student.LastName); + } + { + var student = TestClasses.Abstract.SkippableFirstMemberClass + .CreateStudent + .WithLastName("King"); + + Assert.Null(student.FirstName); + Assert.Equal("King", student.LastName); + } + } + + [Fact, Priority(1)] + public void CanExecuteSkippableLoopClass() + { + var student = TestClasses.Abstract.SkippableLoopClass + .CreateStudent + .WithMember3("3") + .WithMember1("1") + .WithMember4("4"); + + Assert.Equal("1", student.Member1); + Assert.Null(student.Member2); + Assert.Equal("3", student.Member3); + Assert.Equal("4", student.Member4); + } + + [Fact, Priority(1)] + public void CanExecuteSkippableSeveralMembersClass() + { + { + var student = TestClasses.Abstract.SkippableSeveralMembersClass + .CreateStudent + .WithMember2("2") + .WithMember4("4"); + + Assert.Null(student.Member1); + Assert.Equal("2", student.Member2); + Assert.Null(student.Member3); + Assert.Equal("4", student.Member4); + } + { + var student = TestClasses.Abstract.SkippableSeveralMembersClass + .CreateStudent + .WithMember4("4"); + + Assert.Null(student.Member1); + Assert.Null(student.Member2); + Assert.Null(student.Member3); + Assert.Equal("4", student.Member4); + } + } + + [Fact, Priority(1)] + public void CanExecuteThreeMemberClass() + { + var student = TestClasses.Abstract.ThreeMemberClass + .CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } + + [Fact, Priority(1)] + public void CanExecuteThreeMemberRecordPrimaryConstructor() + { + var student = TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor + .CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.name); + Assert.Equal(new DateOnly(2002, 8, 3), student.dateOfBirth); + Assert.Equal(2, student.semester); + } + + [Fact, Priority(1)] + public void CanExecuteThreePrivateMembersClass() + { + var student = TestClasses.Abstract.ThreePrivateMembersClass + .CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } +} +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithInForkClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithInForkClass/UsageTests.cs new file mode 100644 index 0000000..a6ec1bf --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithInForkClass/UsageTests.cs @@ -0,0 +1,44 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithInForkClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteContinueWithInForkClassTest1() + { + var student = CreateStudent + .WithMember1("1") + .WithMember2A("2A") + .WithMember3("3") + .WithMember4("4"); + + Assert.Equal("1", student.Member1); + Assert.Equal("2A", student.Member2A); + Assert.Null(student.Member2B); + Assert.Equal("3", student.Member3); + Assert.Equal("4", student.Member4); + } + + [Fact, Priority(1)] + public void CanExecuteContinueWithInForkClassTest2() + { + var student = CreateStudent + .WithMember1("1") + .WithMember2B("2B") + .WithMember4("4"); + + Assert.Equal("1", student.Member1); + Assert.Null(student.Member2A); + Assert.Equal("2B", student.Member2B); + Assert.Null(student.Member3); + Assert.Equal("4", student.Member4); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs index d0d54f1..492f0aa 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs @@ -2,7 +2,6 @@ // ReSharper disable NotAccessedVariable -using System.Reflection; using Xunit; using Xunit.Priority; @@ -25,4 +24,5 @@ public void CanExecuteContinueWithSelfClass() } #endif -// todo: check all usage tests. Some have the wrong method names. \ No newline at end of file +// todo: check all usage tests. Some have the wrong method names. +// todo: all tests with UnsafeAccessor should have a usage test. \ No newline at end of file From 92fe1821b3e923be6ba00b133cc69a7067af3cc1 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 08:01:19 +0100 Subject: [PATCH 54/67] test: move usage tests --- .../CodeGenerationExecutionTests.cs | 202 ------------------ .../Abstract/FluentLambdaClass/UsageTests.cs | 26 +++ .../FluentLambdaCollectionClass/UsageTests.cs | 32 +++ .../FluentLambdaCompoundClass/UsageTests.cs | 30 +++ .../UsageTests.cs | 59 +++++ .../UsageTests.cs | 59 +++++ .../UsageTests.cs | 48 +++++ .../FluentLambdaRecursiveClass/UsageTests.cs | 30 +++ .../FluentLambdaSingleStepClass/UsageTests.cs | 24 +++ 9 files changed, 308 insertions(+), 202 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaNullablePropertyClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaSingleStepClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs index 46c43d5..ebfabe3 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs @@ -16,208 +16,6 @@ public partial class CodeGenerationTests { - [Fact, Priority(1)] - public void CanExecuteFluentLambdaClass() - { - var student = TestClasses.Abstract.FluentLambdaClass - .CreateStudent - .WithName("Alice") - .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); - - Assert.Equal("Alice", student.Name); - Assert.Equal("23", student.Address.HouseNumber); - Assert.Equal("Market Street", student.Address.Street); - Assert.Equal("San Francisco", student.Address.City); - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaCollectionClass() - { - var student = TestClasses.Abstract.FluentLambdaCollectionClass - .CreateStudent - .WithName("Alice") - .WithAddresses( - a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), - a => a.WithHouseNumber("108").WithStreet("5th Avenue").InCity("New York")); - - Assert.Equal("Alice", student.Name); - Assert.Equal(2, student.Addresses.Count); - Assert.Equal("23", student.Addresses[0].HouseNumber); - Assert.Equal("Market Street", student.Addresses[0].Street); - Assert.Equal("San Francisco", student.Addresses[0].City); - Assert.Equal("108", student.Addresses[1].HouseNumber); - Assert.Equal("5th Avenue", student.Addresses[1].Street); - Assert.Equal("New York", student.Addresses[1].City); - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaCompoundClass() - { - var student = TestClasses.Abstract.FluentLambdaCompoundClass - .CreateStudent - .WithName("Alice") - .WithDetails( - a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), - p => p.WithNumber("222-222-2222").WithUsage("CELL")); - - Assert.Equal("Alice", student.Name); - Assert.Equal("23", student.Address.HouseNumber); - Assert.Equal("Market Street", student.Address.Street); - Assert.Equal("San Francisco", student.Address.City); - Assert.Equal("222-222-2222", student.Phone.Number); - Assert.Equal("CELL", student.Phone.Usage); - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaManyCollectionsClass() - { - { - var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesE(createAddressesE: null); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.AddressesE); - } - { - var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesF(createAddressesF: _ => null); - - Assert.Single(student.AddressesF); - Assert.Null(student.AddressesF[0]); - } - { - var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesG(createAddressesG: null); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.AddressesG); - } - { - var student = TestClasses.Abstract.FluentLambdaManyCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesG(createAddressesG: _ => null); - - Assert.Equal("Alice", student.Name); - Assert.NotNull(student.AddressesG); - Assert.Single(student.AddressesG!); - Assert.Null(student.AddressesG![0]); - } - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaManyPrivateCollectionsClass() - { - { - var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesE(createAddressesE: null); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.AddressesE); - } - { - var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesF(createAddressesF: _ => null); - - Assert.Single(student.AddressesF); - Assert.Null(student.AddressesF[0]); - } - { - var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesG(createAddressesG: null); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.AddressesG); - } - { - var student = TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass - .CreateStudent - .WithName("Alice") - .WithAddressesG(createAddressesG: _ => null); - - Assert.Equal("Alice", student.Name); - Assert.NotNull(student.AddressesG); - Assert.Single(student.AddressesG!); - Assert.Null(student.AddressesG![0]); - } - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaNullablePropertyClass() - { - { - var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass - .CreateStudent - .WithName("Alice") - .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); - - Assert.Equal("Alice", student.Name); - Assert.Equal("23", student.Address!.HouseNumber); - Assert.Equal("Market Street", student.Address!.Street); - Assert.Equal("San Francisco", student.Address!.City); - } - { - var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass - .CreateStudent - .WithName("Alice") - .WithoutAddress(); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.Address); - } - { - var student = TestClasses.Abstract.FluentLambdaNullablePropertyClass - .CreateStudent - .WithName("Alice") - .WithAddress(_ => null); - - Assert.Equal("Alice", student.Name); - Assert.Null(student.Address); - } - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaRecursiveClass() - { - var student = TestClasses.Abstract.FluentLambdaRecursiveClass - .CreateStudent - .WithName("Alice") - .WithFriend(f => f - .WithName("Bob") - .WithFriend(f2 => f2 - .WithName("Eve") - .WithoutFriend())); - - Assert.Equal("Alice", student.Name); - Assert.Equal("Bob", student.Friend!.Name); - Assert.Equal("Eve", student.Friend!.Friend!.Name); - Assert.Null(student.Friend!.Friend!.Friend); - } - - [Fact, Priority(1)] - public void CanExecuteFluentLambdaSingleStepClass() - { - var student = TestClasses.Abstract.FluentLambdaSingleStepClass - .CreateStudent - .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); - - Assert.Equal("23", student.Address.HouseNumber); - Assert.Equal("Market Street", student.Address.Street); - Assert.Equal("San Francisco", student.Address.City); - } - [Fact, Priority(1)] public void CanExecuteFluentMethodClass() { diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClass/UsageTests.cs new file mode 100644 index 0000000..5107fc6 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClass/UsageTests.cs @@ -0,0 +1,26 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentLambdaClass() + { + var student = CreateStudent + .WithName("Alice") + .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); + + Assert.Equal("Alice", student.Name); + Assert.Equal("23", student.Address.HouseNumber); + Assert.Equal("Market Street", student.Address.Street); + Assert.Equal("San Francisco", student.Address.City); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/UsageTests.cs new file mode 100644 index 0000000..53ec0b4 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/UsageTests.cs @@ -0,0 +1,32 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentLambdaCollectionClass() + { + var student = CreateStudent + .WithName("Alice") + .WithAddresses( + a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), + a => a.WithHouseNumber("108").WithStreet("5th Avenue").InCity("New York")); + + Assert.Equal("Alice", student.Name); + Assert.Equal(2, student.Addresses.Count); + Assert.Equal("23", student.Addresses[0].HouseNumber); + Assert.Equal("Market Street", student.Addresses[0].Street); + Assert.Equal("San Francisco", student.Addresses[0].City); + Assert.Equal("108", student.Addresses[1].HouseNumber); + Assert.Equal("5th Avenue", student.Addresses[1].Street); + Assert.Equal("New York", student.Addresses[1].City); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/UsageTests.cs new file mode 100644 index 0000000..3e8a70a --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/UsageTests.cs @@ -0,0 +1,30 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentLambdaCompoundClass() + { + var student = CreateStudent + .WithName("Alice") + .WithDetails( + a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), + p => p.WithNumber("222-222-2222").WithUsage("CELL")); + + Assert.Equal("Alice", student.Name); + Assert.Equal("23", student.Address.HouseNumber); + Assert.Equal("Market Street", student.Address.Street); + Assert.Equal("San Francisco", student.Address.City); + Assert.Equal("222-222-2222", student.Phone.Number); + Assert.Equal("CELL", student.Phone.Usage); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/UsageTests.cs new file mode 100644 index 0000000..52bdee5 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/UsageTests.cs @@ -0,0 +1,59 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentLambdaManyCollectionsClassTest1() + { + Student student = CreateStudent + .WithName("Alice") + .WithAddressesE(createAddressesE: null); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.AddressesE); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaManyCollectionsClassTest2() + { + Student student = CreateStudent + .WithName("Alice") + .WithAddressesF(createAddressesF: _ => null); + + Assert.Single(student.AddressesF); + Assert.Null(student.AddressesF[0]); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaManyCollectionsClassTest3() + { + Student student = CreateStudent + .WithName("Alice") + .WithAddressesG(createAddressesG: null); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.AddressesG); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaManyCollectionsClassTest4() + { + Student student = CreateStudent + .WithName("Alice") + .WithAddressesG(createAddressesG: _ => null); + + Assert.Equal("Alice", student.Name); + Assert.NotNull(student.AddressesG); + Assert.Single(student.AddressesG!); + Assert.Null(student.AddressesG![0]); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/UsageTests.cs new file mode 100644 index 0000000..f51d375 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/UsageTests.cs @@ -0,0 +1,59 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentLambdaManyPrivateCollectionsClassTest1() + { + Student student = CreateStudent + .WithName("Alice") + .WithAddressesE(createAddressesE: null); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.AddressesE); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaManyPrivateCollectionsClassTest2() + { + Student student = CreateStudent + .WithName("Alice") + .WithAddressesF(createAddressesF: _ => null); + + Assert.Single(student.AddressesF); + Assert.Null(student.AddressesF[0]); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaManyPrivateCollectionsClassTest3() + { + Student student = CreateStudent + .WithName("Alice") + .WithAddressesG(createAddressesG: null); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.AddressesG); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaManyPrivateCollectionsClassTest4() + { + Student student = CreateStudent + .WithName("Alice") + .WithAddressesG(createAddressesG: _ => null); + + Assert.Equal("Alice", student.Name); + Assert.NotNull(student.AddressesG); + Assert.Single(student.AddressesG!); + Assert.Null(student.AddressesG![0]); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaNullablePropertyClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaNullablePropertyClass/UsageTests.cs new file mode 100644 index 0000000..8dcee52 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaNullablePropertyClass/UsageTests.cs @@ -0,0 +1,48 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaNullablePropertyClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentLambdaNullablePropertyClassTest1() + { + Student student = CreateStudent + .WithName("Alice") + .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); + + Assert.Equal("Alice", student.Name); + Assert.Equal("23", student.Address!.HouseNumber); + Assert.Equal("Market Street", student.Address!.Street); + Assert.Equal("San Francisco", student.Address!.City); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaNullablePropertyClassTest2() + { + Student student = CreateStudent + .WithName("Alice") + .WithoutAddress(); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.Address); + } + + [Fact, Priority(1)] + public void CanExecuteFluentLambdaNullablePropertyClassTest3() + { + Student student = CreateStudent + .WithName("Alice") + .WithAddress(_ => null); + + Assert.Equal("Alice", student.Name); + Assert.Null(student.Address); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/UsageTests.cs new file mode 100644 index 0000000..1b32cb9 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/UsageTests.cs @@ -0,0 +1,30 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaRecursiveClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentLambdaRecursiveClass() + { + Student student = CreateStudent + .WithName("Alice") + .WithFriend(f => f + .WithName("Bob") + .WithFriend(f2 => f2 + .WithName("Eve") + .WithoutFriend())); + + Assert.Equal("Alice", student.Name); + Assert.Equal("Bob", student.Friend!.Name); + Assert.Equal("Eve", student.Friend!.Friend!.Name); + Assert.Null(student.Friend!.Friend!.Friend); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaSingleStepClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaSingleStepClass/UsageTests.cs new file mode 100644 index 0000000..b39d8c1 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaSingleStepClass/UsageTests.cs @@ -0,0 +1,24 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaSingleStepClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentLambdaSingleStepClass() + { + Student student = CreateStudent + .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); + + Assert.Equal("23", student.Address.HouseNumber); + Assert.Equal("Market Street", student.Address.Street); + Assert.Equal("San Francisco", student.Address.City); + } +} + +#endif \ No newline at end of file From c3a639000586a4a1d1faffa1d604623e9fb30820 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 08:25:05 +0100 Subject: [PATCH 55/67] usage tests: migrated all tests --- .../CodeGenerationExecutionTests.cs | 461 ------------------ .../Abstract/FluentMethodClass/UsageTests.cs | 27 + .../UsageTests.cs | 44 ++ .../UsageTests.cs | 44 ++ .../UsageTests.cs | 33 ++ .../UsageTests.cs | 33 ++ .../UsageTests.cs | 66 +++ .../UsageTests.cs | 66 +++ .../Abstract/InheritedClass/UsageTests.cs | 27 + .../UsageTests.cs | 35 ++ .../UsageTests.cs | 27 + .../PrivateConstructorClass/UsageTests.cs | 22 + .../Abstract/PrivateFieldClass/UsageTests.cs | 11 +- .../PrivateFluentMethodClass/UsageTests.cs | 27 + .../UsageTests.cs | 27 + .../SkippableFirstMemberClass/UsageTests.cs | 34 ++ .../Abstract/SkippableLoopClass/UsageTests.cs | 27 + .../SkippableMemberClass/UsageTests.cs | 38 ++ .../UsageTests.cs | 38 ++ .../Abstract/ThreeMemberClass/UsageTests.cs | 27 + .../ThreePrivateMembersClass/UsageTests.cs | 27 + .../TryBreakFluentApiClass1/UsageTests.cs | 3 +- .../TryBreakFluentApiClass2/UsageTests.cs | 3 +- 23 files changed, 676 insertions(+), 471 deletions(-) delete mode 100644 src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentMethodClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedMethodClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableFirstMemberClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableLoopClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableMemberClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableSeveralMembersClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberClass/UsageTests.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs deleted file mode 100644 index ebfabe3..0000000 --- a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs +++ /dev/null @@ -1,461 +0,0 @@ -#define TEST_GENERATED_CODE -#if TEST_GENERATED_CODE - -// ReSharper disable NotAccessedVariable - -using System; -using System.Collections.Generic; -using System.Reflection; -using M31.FluentApi.Tests.CodeGeneration.Helpers; -using Xunit; -using Xunit.Priority; - -namespace M31.FluentApi.Tests.CodeGeneration; - -public partial class CodeGenerationTests -{ - - - [Fact, Priority(1)] - public void CanExecuteFluentMethodClass() - { - var student = TestClasses.Abstract.FluentMethodClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecuteFluentReturnMultiStepPrivateMethodsClass() - { - { - TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnVoidMethod(); - } - { - int result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnIntMethod(); - Assert.Equal(24, result); - } - { - string string1 = "string1"; - int result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnIntMethodWithRefParameter(ref string1); - Assert.Equal(28, result); - } - { - List result = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnListMethod(); - Assert.Equal(new List() { 1, 2, 3 }, result); - } - } - - [Fact, Priority(1)] - public void CanExecuteFluentReturnSingleStepPrivateMethodsClass() - { - { - TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnVoidMethod(); - } - { - int result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnIntMethod(); - Assert.Equal(24, result); - } - { - string string1 = "string1"; - int result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnIntMethodWithRefParameter(ref string1); - Assert.Equal(28, result); - } - { - List result = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnListMethod(); - Assert.Equal(new List() { 1, 2, 3 }, result); - } - } - - [Fact, Priority(1)] - public void CanExecuteGenericClassWithGenericMethods() - { - var student = TestClasses.Abstract.GenericClassWithGenericMethods - .CreateStudent - .WithProperty1("property1") - .WithProperty2(null) - .WithProperty3(0) - .WithProperty4(0) - .WithProperty5(0) - .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) - .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), - new List()) - .Method3, Dictionary, List>("string1"); - - string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; - Assert.Equal(expectedLogs, student.Logs); - } - - [Fact, Priority(1)] - public void CanExecuteGenericClassWithPrivateGenericMethods() - { - var student = TestClasses.Abstract.GenericClassWithPrivateGenericMethods - .CreateStudent - .WithProperty1("property1") - .WithProperty2(null) - .WithProperty3(0) - .WithProperty4(0) - .WithProperty5(0) - .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) - .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), - new List()) - .Method3, Dictionary, List>("string1"); - - string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; - Assert.Equal(expectedLogs, student.Logs); - } - - [Fact, Priority(1)] - public void CanExecuteGenericOverloadedMethodClass() - { - { - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1("string1", "string2"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); - } - { - string string1 = "string1"; - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, out string1); - Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); - } - { - int i = 0; - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(in i, "string1"); - Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); - } - { - int i = 0; - string string1 = "string1"; - var student = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(in i, ref string1); - Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); - } - } - - [Fact, Priority(1)] - public void CanExecuteGenericOverloadedPrivateMethodClass() - { - { - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1("string1", "string2"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); - } - { - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); - } - { - string string1 = "string1"; - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, out string1); - Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); - } - { - int i = 0; - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(in i, "string1"); - Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); - } - { - int i = 0; - string string1 = "string"; - var student = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(in i, ref string1); - Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); - } - } - - [Fact, Priority(1)] - public void CanExecuteInheritedClass() - { - var student = TestClasses.Abstract.InheritedClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - - [Fact, Priority(1)] - public void CanExecuteInheritedClassProtectedMembers() - { - var student = TestClasses.Abstract.InheritedClassProtectedMembers - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", GetProperty("Name")); - Assert.Equal(new DateOnly(2002, 8, 3), GetProperty("DateOfBirth")); - Assert.Equal(2, GetProperty("Semester")); - - object GetProperty(string propertyName) - { - return typeof(TestClasses.Abstract.InheritedClassProtectedMembers.Student) - .GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic)? - .GetValue(student)!; - } - } - - [Fact, Priority(1)] - public void CanExecuteInheritedClassProtectedSetters() - { - var student = TestClasses.Abstract.InheritedClassProtectedSetters - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - - [Fact, Priority(1)] - public void CanExecutePartialClass() - { - var student = TestClasses.Abstract.PartialClass - .CreateStudent - .WithFirstName("Alice") - .WithLastName("King"); - - Assert.Equal("Alice", student.FirstName); - Assert.Equal("King", student.LastName); - } - - [Fact, Priority(1)] - public void CanExecutePrivateConstructorClass() - { - var student = TestClasses.Abstract.PrivateConstructorClass - .CreateStudent - .InSemester(2); - - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecutePrivateFieldClass() - { - var student = TestClasses.Abstract.PrivateFieldClass - .CreateStudent - .InSemester(2); - - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecutePrivateFluentMethodClass() - { - var student = TestClasses.Abstract.PrivateFluentMethodClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecutePrivateMethodFluentNullableParameterClass() - { - var student = TestClasses.Abstract.PrivateFluentMethodNullableParameterClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(null); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Null(student.Semester); - } - - [Fact, Priority(1)] - public void CanExecutePublicReadonlyFieldClass() - { - var student = TestClasses.Abstract.PublicReadonlyFieldClass - .CreateStudent - .InSemester(2); - - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecuteSkippableMemberClass() - { - { - var student = TestClasses.Abstract.SkippableMemberClass - .CreateStudent - .WithFirstName("Alice") - .WithMiddleName("Sophia") - .WithLastName("King"); - - Assert.Equal("Alice", student.FirstName); - Assert.Equal("Sophia", student.MiddleName); - Assert.Equal("King", student.LastName); - } - { - var student = TestClasses.Abstract.SkippableMemberClass - .CreateStudent - .WithFirstName("Alice") - .WithLastName("King"); - - Assert.Equal("Alice", student.FirstName); - Assert.Null(student.MiddleName); - Assert.Equal("King", student.LastName); - } - } - - [Fact, Priority(1)] - public void CanExecuteSkippableFirstMemberClass() - { - { - var student = TestClasses.Abstract.SkippableFirstMemberClass - .CreateStudent - .WithFirstName("Alice") - .WithLastName("King"); - - Assert.Equal("Alice", student.FirstName); - Assert.Equal("King", student.LastName); - } - { - var student = TestClasses.Abstract.SkippableFirstMemberClass - .CreateStudent - .WithLastName("King"); - - Assert.Null(student.FirstName); - Assert.Equal("King", student.LastName); - } - } - - [Fact, Priority(1)] - public void CanExecuteSkippableLoopClass() - { - var student = TestClasses.Abstract.SkippableLoopClass - .CreateStudent - .WithMember3("3") - .WithMember1("1") - .WithMember4("4"); - - Assert.Equal("1", student.Member1); - Assert.Null(student.Member2); - Assert.Equal("3", student.Member3); - Assert.Equal("4", student.Member4); - } - - [Fact, Priority(1)] - public void CanExecuteSkippableSeveralMembersClass() - { - { - var student = TestClasses.Abstract.SkippableSeveralMembersClass - .CreateStudent - .WithMember2("2") - .WithMember4("4"); - - Assert.Null(student.Member1); - Assert.Equal("2", student.Member2); - Assert.Null(student.Member3); - Assert.Equal("4", student.Member4); - } - { - var student = TestClasses.Abstract.SkippableSeveralMembersClass - .CreateStudent - .WithMember4("4"); - - Assert.Null(student.Member1); - Assert.Null(student.Member2); - Assert.Null(student.Member3); - Assert.Equal("4", student.Member4); - } - } - - [Fact, Priority(1)] - public void CanExecuteThreeMemberClass() - { - var student = TestClasses.Abstract.ThreeMemberClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } - - [Fact, Priority(1)] - public void CanExecuteThreeMemberRecordPrimaryConstructor() - { - var student = TestClasses.Abstract.ThreeMemberRecordPrimaryConstructor - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.name); - Assert.Equal(new DateOnly(2002, 8, 3), student.dateOfBirth); - Assert.Equal(2, student.semester); - } - - [Fact, Priority(1)] - public void CanExecuteThreePrivateMembersClass() - { - var student = TestClasses.Abstract.ThreePrivateMembersClass - .CreateStudent - .WithName("Alice") - .BornOn(new DateOnly(2002, 8, 3)) - .InSemester(2); - - Assert.Equal("Alice", student.Name); - Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); - Assert.Equal(2, student.Semester); - } -} -#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentMethodClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentMethodClass/UsageTests.cs new file mode 100644 index 0000000..c88f398 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentMethodClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentMethodClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentMethodClass() + { + Student student = CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/UsageTests.cs new file mode 100644 index 0000000..ef619e0 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/UsageTests.cs @@ -0,0 +1,44 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using System.Collections.Generic; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentReturnMultiStepPrivateMethodsClassTest1() + { + Exception? exception = Record.Exception(() => CreateStudent.WithName("Alice").ReturnVoidMethod()); + Assert.Null(exception); + } + + [Fact, Priority(1)] + public void CanExecuteFluentReturnMultiStepPrivateMethodsClassTest2() + { + int result = CreateStudent.WithName("Alice").ReturnIntMethod(); + Assert.Equal(24, result); + } + + [Fact, Priority(1)] + public void CanExecuteFluentReturnMultiStepPrivateMethodsClassTest3() + { + string string1 = "string1"; + int result = CreateStudent.WithName("Alice").ReturnIntMethodWithRefParameter(ref string1); + Assert.Equal(28, result); + } + + [Fact, Priority(1)] + public void CanExecuteFluentReturnMultiStepPrivateMethodsClassTest4() + { + List result = CreateStudent.WithName("Alice").ReturnListMethod(); + Assert.Equal(new List() { 1, 2, 3 }, result); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/UsageTests.cs new file mode 100644 index 0000000..4b5bfd4 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/UsageTests.cs @@ -0,0 +1,44 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using System.Collections.Generic; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteFluentReturnSingleStepPrivateMethodsClassTest1() + { + Exception? exception = Record.Exception(() => CreateStudent.ReturnIntMethod()); + Assert.Null(exception); + } + + [Fact, Priority(1)] + public void CanExecuteFluentReturnSingleStepPrivateMethodsClassTest2() + { + int result = CreateStudent.ReturnIntMethod(); + Assert.Equal(24, result); + } + + [Fact, Priority(1)] + public void CanExecuteFluentReturnSingleStepPrivateMethodsClassTest3() + { + string string1 = "string1"; + int result = CreateStudent.ReturnIntMethodWithRefParameter(ref string1); + Assert.Equal(28, result); + } + + [Fact, Priority(1)] + public void CanExecuteFluentReturnSingleStepPrivateMethodsClassTest4() + { + List result = CreateStudent.ReturnListMethod(); + Assert.Equal(new List() { 1, 2, 3 }, result); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/UsageTests.cs new file mode 100644 index 0000000..01944f8 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/UsageTests.cs @@ -0,0 +1,33 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System.Collections.Generic; +using M31.FluentApi.Tests.CodeGeneration.Helpers; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassWithGenericMethods; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteGenericClassWithGenericMethods() + { + var student = CreateStudent + .WithProperty1("property1") + .WithProperty2(null) + .WithProperty3(0) + .WithProperty4(0) + .WithProperty5(0) + .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) + .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), + new List()) + .Method3, Dictionary, List>("string1"); + + string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; + Assert.Equal(expectedLogs, student.Logs); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/UsageTests.cs new file mode 100644 index 0000000..23f5fbc --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/UsageTests.cs @@ -0,0 +1,33 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System.Collections.Generic; +using M31.FluentApi.Tests.CodeGeneration.Helpers; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassWithPrivateGenericMethods; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteGenericClassWithGenericMethods() + { + var student = CreateStudent + .WithProperty1("property1") + .WithProperty2(null) + .WithProperty3(0) + .WithProperty4(0) + .WithProperty5(0) + .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) + .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), + new List()) + .Method3, Dictionary, List>("string1"); + + string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; + Assert.Equal(expectedLogs, student.Logs); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedMethodClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedMethodClass/UsageTests.cs new file mode 100644 index 0000000..53b9353 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedMethodClass/UsageTests.cs @@ -0,0 +1,66 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericOverloadedMethodClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedMethodClassTest1() + { + Student student = CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedMethodClassTest2() + { + Student student = CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedMethodClassTest3() + { + Student student = CreateStudent.Method1("string1", "string2"); + Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedMethodClassTest4() + { + Student student = CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedMethodClassTest5() + { + string string1 = "string1"; + Student student = CreateStudent.Method1(0, out string1); + Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedMethodClassTest6() + { + int i = 0; + Student student = CreateStudent.Method1(in i, "string1"); + Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedMethodClassTest7() + { + int i = 0; + string string1 = "string1"; + Student student = CreateStudent.Method1(in i, ref string1); + Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/UsageTests.cs new file mode 100644 index 0000000..f8afac7 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/UsageTests.cs @@ -0,0 +1,66 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericOverloadedPrivateMethodClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedPrivateMethodClassTest1() + { + Student student = CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedPrivateMethodClassTest2() + { + Student student = CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedPrivateMethodClassTest3() + { + Student student = CreateStudent.Method1("string1", "string2"); + Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedPrivateMethodClassTest4() + { + Student student = CreateStudent.Method1(0, "string1"); + Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedPrivateMethodClassTest5() + { + string string1 = "string1"; + Student student = CreateStudent.Method1(0, out string1); + Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedPrivateMethodClassTest6() + { + int i = 0; + Student student = CreateStudent.Method1(in i, "string1"); + Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); + } + + [Fact, Priority(1)] + public void CanExecuteGenericOverloadedPrivateMethodClassTest7() + { + int i = 0; + string string1 = "string"; + Student student = CreateStudent.Method1(in i, ref string1); + Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClass/UsageTests.cs new file mode 100644 index 0000000..3db1f42 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteInheritedClass() + { + Student student = CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/UsageTests.cs new file mode 100644 index 0000000..12fb690 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/UsageTests.cs @@ -0,0 +1,35 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using System.Reflection; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassProtectedMembers; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteInheritedClassProtectedMembers() + { + Student student = CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", GetProperty("Name")); + Assert.Equal(new DateOnly(2002, 8, 3), GetProperty("DateOfBirth")); + Assert.Equal(2, GetProperty("Semester")); + + object GetProperty(string propertyName) + { + return typeof(Student) + .GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic)? + .GetValue(student)!; + } + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/UsageTests.cs new file mode 100644 index 0000000..022ba52 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassProtectedSetters; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteInheritedClassProtectedSetters() + { + Student student = CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/UsageTests.cs new file mode 100644 index 0000000..6b38efa --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClass/UsageTests.cs @@ -0,0 +1,22 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateConstructorClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateConstructorClass() + { + Student student = CreateStudent + .InSemester(2); + + Assert.Equal(2, student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/UsageTests.cs index 9128bb7..6fa3a4e 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/UsageTests.cs @@ -2,7 +2,6 @@ // ReSharper disable NotAccessedVariable -using System.Reflection; using Xunit; using Xunit.Priority; @@ -11,16 +10,12 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFieldCl public class UsageTests { [Fact, Priority(1)] - public void CanExecutePrivateReadonlyFieldClass() + public void CanExecutePrivateFieldClass() { var student = CreateStudent - .InSemester(4); + .InSemester(2); - int semester = (int)typeof(Student).GetField( - "semester", - BindingFlags.Instance | BindingFlags.NonPublic) - !.GetValue(student)!; - Assert.Equal(4, semester); + Assert.Equal(2, student.Semester); } } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/UsageTests.cs new file mode 100644 index 0000000..1a1d2b0 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFluentMethodClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateFluentMethodClass() + { + Student student = CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/UsageTests.cs new file mode 100644 index 0000000..0fe4b99 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFluentMethodNullableParameterClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateFluentMethodNullableParameterClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateMethodFluentNullableParameterClass() + { + Student student = CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(null); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Null(student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableFirstMemberClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableFirstMemberClass/UsageTests.cs new file mode 100644 index 0000000..4b3e25f --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableFirstMemberClass/UsageTests.cs @@ -0,0 +1,34 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.SkippableFirstMemberClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteSkippableFirstMemberClassTest1() + { + Student student = CreateStudent + .WithFirstName("Alice") + .WithLastName("King"); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("King", student.LastName); + } + + [Fact, Priority(1)] + public void CanExecuteSkippableFirstMemberClassTest2() + { + Student student = CreateStudent + .WithLastName("King"); + + Assert.Null(student.FirstName); + Assert.Equal("King", student.LastName); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableLoopClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableLoopClass/UsageTests.cs new file mode 100644 index 0000000..ad71f42 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableLoopClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.SkippableLoopClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteSkippableLoopClass() + { + Student student = CreateStudent + .WithMember3("3") + .WithMember1("1") + .WithMember4("4"); + + Assert.Equal("1", student.Member1); + Assert.Null(student.Member2); + Assert.Equal("3", student.Member3); + Assert.Equal("4", student.Member4); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableMemberClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableMemberClass/UsageTests.cs new file mode 100644 index 0000000..35a45b0 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableMemberClass/UsageTests.cs @@ -0,0 +1,38 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.SkippableMemberClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteSkippableMemberClassTest1() + { + Student student = CreateStudent + .WithFirstName("Alice") + .WithMiddleName("Sophia") + .WithLastName("King"); + + Assert.Equal("Alice", student.FirstName); + Assert.Equal("Sophia", student.MiddleName); + Assert.Equal("King", student.LastName); + } + + [Fact, Priority(1)] + public void CanExecuteSkippableMemberClassTest2() + { + Student student = CreateStudent + .WithFirstName("Alice") + .WithLastName("King"); + + Assert.Equal("Alice", student.FirstName); + Assert.Null(student.MiddleName); + Assert.Equal("King", student.LastName); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableSeveralMembersClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableSeveralMembersClass/UsageTests.cs new file mode 100644 index 0000000..1d0c5c8 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SkippableSeveralMembersClass/UsageTests.cs @@ -0,0 +1,38 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.SkippableSeveralMembersClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteSkippableSeveralMembersClassTest1() + { + Student student = CreateStudent + .WithMember2("2") + .WithMember4("4"); + + Assert.Null(student.Member1); + Assert.Equal("2", student.Member2); + Assert.Null(student.Member3); + Assert.Equal("4", student.Member4); + } + + [Fact, Priority(1)] + public void CanExecuteSkippableSeveralMembersClassTest2() + { + Student student = CreateStudent + .WithMember4("4"); + + Assert.Null(student.Member1); + Assert.Null(student.Member2); + Assert.Null(student.Member3); + Assert.Equal("4", student.Member4); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberClass/UsageTests.cs new file mode 100644 index 0000000..8904ce7 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreeMemberClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteThreeMemberClass() + { + Student student = CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/UsageTests.cs new file mode 100644 index 0000000..92107ed --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/UsageTests.cs @@ -0,0 +1,27 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using System; +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ThreePrivateMembersClass; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecuteThreePrivateMembersClass() + { + var student = CreateStudent + .WithName("Alice") + .BornOn(new DateOnly(2002, 8, 3)) + .InSemester(2); + + Assert.Equal("Alice", student.Name); + Assert.Equal(new DateOnly(2002, 8, 3), student.DateOfBirth); + Assert.Equal(2, student.Semester); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/UsageTests.cs index e2d6d13..d1c75df 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass1/UsageTests.cs @@ -2,6 +2,7 @@ // ReSharper disable NotAccessedVariable +using System; using Xunit; using Xunit.Priority; @@ -12,7 +13,7 @@ public class UsageTests [Fact, Priority(1)] public void CanExecuteTryBreakFluentApiClass1() { - var exception = Record.Exception(() => + Exception? exception = Record.Exception(() => { Student student = CreateStudent .SomeMethod("hello world"); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/UsageTests.cs index ad3dae3..750733d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass2/UsageTests.cs @@ -2,6 +2,7 @@ // ReSharper disable NotAccessedVariable +using System; using Xunit; using Xunit.Priority; @@ -12,7 +13,7 @@ public class UsageTests [Fact, Priority(1)] public void CanExecuteTryBreakFluentApiClass2() { - var exception = Record.Exception(() => + Exception? exception = Record.Exception(() => { Student student = CreateStudent .SomeMethod("hello world"); From 08c4045f69b0328d9601a2ea59c9d53c0175c538 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 10:55:14 +0100 Subject: [PATCH 56/67] fix: declaring class name --- .../InnerBodyForMemberGenerator.cs | 4 +- .../InnerBodyForMethodGenerator.cs | 2 +- .../CodeBoardElements/FluentApiSymbolInfo.cs | 8 +- .../CodeBoardElements/MemberSymbolInfo.cs | 9 ++- .../CodeBoardElements/MethodSymbolInfo.cs | 9 ++- .../SourceGenerators/ClassInfoFactory.cs | 9 ++- .../SourceGenerators/FluentApiInfoCreator.cs | 6 +- .../SourceGenerators/SymbolInfoCreator.cs | 14 +++- .../CreateStudent.expected.txt | 58 +++++++-------- .../CreateStudent.g.cs | 58 +++++++-------- .../CodeGeneration/TestDataProvider.cs | 74 +++++++++---------- 11 files changed, 137 insertions(+), 114 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs index d947bfa..bfb9c35 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs @@ -49,7 +49,7 @@ private void GenerateInnerBodyForPrivateProperty(MemberSymbolInfo symbolInfo) unsafeAccessorSignature.AddParameter( symbolInfo.DeclaringClassNameWithTypeParameters, - symbolInfo.DeclaringClassNameWithTypeParameters.FirstCharToLower()); // Student student + symbolInfo.DeclaringClassName.FirstCharToLower()); // Student student unsafeAccessorSignature.AddParameter(symbolInfo.TypeForCodeGeneration, "value"); unsafeAccessorSignature.AddAttribute( @@ -75,7 +75,7 @@ private void GenerateInnerBodyForPrivateField(MemberSymbolInfo symbolInfo) unsafeAccessorSignature.AddParameter( symbolInfo.DeclaringClassNameWithTypeParameters, - symbolInfo.DeclaringClassNameWithTypeParameters.FirstCharToLower()); // Student student + symbolInfo.DeclaringClassName.FirstCharToLower()); // Student student unsafeAccessorSignature.AddAttribute( $"[UnsafeAccessor(UnsafeAccessorKind.Field, Name = \"{symbolInfo.Name}\")]"); diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index bfcbd70..780748f 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -54,7 +54,7 @@ protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbo // Student student unsafeAccessorSignature.AddParameter( symbolInfo.DeclaringClassNameWithTypeParameters, - symbolInfo.DeclaringClassNameWithTypeParameters.FirstCharToLower()); + symbolInfo.DeclaringClassName.FirstCharToLower()); List parameters = CodeBuildingHelpers.CreateParameters(symbolInfo.ParameterInfos); parameters.ForEach(unsafeAccessorSignature.AddParameter); diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs index 8acf082..8809061 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/FluentApiSymbolInfo.cs @@ -8,6 +8,7 @@ internal abstract class FluentApiSymbolInfo { internal FluentApiSymbolInfo( string name, + string declaringClassName, string declaringClassNameWithTypeParameters, Accessibility accessibility, bool publiclyWritable, @@ -16,6 +17,7 @@ internal FluentApiSymbolInfo( Name = name; NameInCamelCase = Name.TrimStart('_').FirstCharToLower(); NameInPascalCase = Name.TrimStart('_').FirstCharToUpper(); + DeclaringClassName = declaringClassName; DeclaringClassNameWithTypeParameters = declaringClassNameWithTypeParameters; Accessibility = accessibility; PubliclyWritable = publiclyWritable; @@ -25,6 +27,7 @@ internal FluentApiSymbolInfo( internal string Name { get; } internal string NameInCamelCase { get; } internal string NameInPascalCase { get; } + internal string DeclaringClassName { get; } internal string DeclaringClassNameWithTypeParameters { get; } internal Accessibility Accessibility { get; } internal bool PubliclyWritable { get; } @@ -33,6 +36,7 @@ internal FluentApiSymbolInfo( protected bool Equals(FluentApiSymbolInfo other) { return Name == other.Name && + DeclaringClassName == other.DeclaringClassName && DeclaringClassNameWithTypeParameters == other.DeclaringClassNameWithTypeParameters && Accessibility == other.Accessibility && PubliclyWritable == other.PubliclyWritable && @@ -50,6 +54,8 @@ public override bool Equals(object? obj) public override int GetHashCode() { return new HashCode() - .Add(Name, DeclaringClassNameWithTypeParameters, Accessibility, PubliclyWritable, Comments); + .Add(Name) + .Add(DeclaringClassName, DeclaringClassNameWithTypeParameters) + .Add(Accessibility, PubliclyWritable, Comments); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs index 2b5b9aa..3f358ce 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MemberSymbolInfo.cs @@ -10,6 +10,7 @@ internal class MemberSymbolInfo : FluentApiSymbolInfo internal MemberSymbolInfo( string name, string type, + string declaringClassName, string declaringClassNameWithTypeParameters, Accessibility accessibility, bool publiclyWritable, @@ -18,7 +19,13 @@ internal MemberSymbolInfo( bool isProperty, CollectionType? collectionType, Comments comments) - : base(name, declaringClassNameWithTypeParameters, accessibility, publiclyWritable, comments) + : base( + name, + declaringClassName, + declaringClassNameWithTypeParameters, + accessibility, + publiclyWritable, + comments) { Type = type; TypeForCodeGeneration = typeForCodeGeneration; diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs index 124410e..bfffecf 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardElements/MethodSymbolInfo.cs @@ -9,6 +9,7 @@ internal class MethodSymbolInfo : FluentApiSymbolInfo { internal MethodSymbolInfo( string name, + string declaringClassName, string declaringClassNameWithTypeParameters, Accessibility accessibility, bool publiclyWritable, @@ -16,7 +17,13 @@ internal MethodSymbolInfo( IReadOnlyCollection parameterInfos, string returnType, Comments comments) - : base(name, declaringClassNameWithTypeParameters, accessibility, publiclyWritable, comments) + : base( + name, + declaringClassName, + declaringClassNameWithTypeParameters, + accessibility, + publiclyWritable, + comments) { GenericInfo = genericInfo; ParameterInfos = parameterInfos; diff --git a/src/M31.FluentApi.Generator/SourceGenerators/ClassInfoFactory.cs b/src/M31.FluentApi.Generator/SourceGenerators/ClassInfoFactory.cs index e92149a..78522b2 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/ClassInfoFactory.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/ClassInfoFactory.cs @@ -109,7 +109,7 @@ private ClassInfoResult CreateFluentApiClassInfoInternal( } FluentApiInfo? fluentApiInfo = TryCreateFluentApiInfo( - member, declaringClassNameWithGenericParameters, cancellationToken); + member, namedTypeSymbol.Name, declaringClassNameWithGenericParameters, cancellationToken); if (fluentApiInfo != null) { @@ -201,7 +201,10 @@ with the fewest parameters that is explicitly declared. */ } private FluentApiInfo? TryCreateFluentApiInfo( - ISymbol symbol, string declaringClassNameWithTypeParameters, CancellationToken cancellationToken) + ISymbol symbol, + string declaringClassName, + string declaringClassNameWithTypeParameters, + CancellationToken cancellationToken) { AttributeDataExtractor extractor = new AttributeDataExtractor(report); FluentApiAttributeData? attributeData = extractor.GetAttributeData(symbol); @@ -219,7 +222,7 @@ with the fewest parameters that is explicitly declared. */ FluentApiInfoCreator fluentApiInfoCreator = new FluentApiInfoCreator(report); return fluentApiInfoCreator.Create( - symbol, attributeData, declaringClassNameWithTypeParameters, cancellationToken); + symbol, attributeData, declaringClassName, declaringClassNameWithTypeParameters, cancellationToken); } public static string AugmentTypeNameWithGenericParameters(string typeName, GenericInfo? genericInfo) diff --git a/src/M31.FluentApi.Generator/SourceGenerators/FluentApiInfoCreator.cs b/src/M31.FluentApi.Generator/SourceGenerators/FluentApiInfoCreator.cs index 272cf3f..e3a8afe 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/FluentApiInfoCreator.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/FluentApiInfoCreator.cs @@ -20,6 +20,7 @@ internal FluentApiInfoCreator(ClassInfoReport classInfoReport) internal FluentApiInfo? Create( ISymbol symbol, FluentApiAttributeData attributeData, + string declaringClassName, string declaringClassNameWithTypeParameters, CancellationToken cancellationToken) { @@ -28,7 +29,10 @@ internal FluentApiInfoCreator(ClassInfoReport classInfoReport) return null; } - FluentApiSymbolInfo symbolInfo = SymbolInfoCreator.Create(symbol, declaringClassNameWithTypeParameters); + FluentApiSymbolInfo symbolInfo = SymbolInfoCreator.Create( + symbol, + declaringClassName, + declaringClassNameWithTypeParameters); AttributeInfoBase? attributeInfo = CreateAttributeInfo(attributeData.MainAttributeData, symbol, symbolInfo); if (attributeInfo == null || cancellationToken.IsCancellationRequested) diff --git a/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs b/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs index 6f35fb0..f4811b6 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/SymbolInfoCreator.cs @@ -12,18 +12,24 @@ namespace M31.FluentApi.Generator.SourceGenerators; internal static class SymbolInfoCreator { - internal static FluentApiSymbolInfo Create(ISymbol symbol, string declaringClassNameWithTypeParameters) + internal static FluentApiSymbolInfo Create( + ISymbol symbol, + string declaringClassName, + string declaringClassNameWithTypeParameters) { return symbol switch { IPropertySymbol propertySymbol => CreateMemberSymbolInfo( propertySymbol, + declaringClassName, declaringClassNameWithTypeParameters), IFieldSymbol fieldSymbol => CreateMemberSymbolInfo( fieldSymbol, + declaringClassName, declaringClassNameWithTypeParameters), IMethodSymbol methodSymbol => CreateMethodSymbolInfo( methodSymbol, + declaringClassName, declaringClassNameWithTypeParameters), _ => throw new ArgumentException($"Unexpected symbol type: {symbol.GetType()}."), }; @@ -41,11 +47,13 @@ internal static ConstructorInfo CreateConstructorInfo(IMethodSymbol constructor) private static MemberSymbolInfo CreateMemberSymbolInfo( IFieldSymbol fieldSymbol, + string declaringClassName, string declaringClassNameWithTypeParameters) { return new MemberSymbolInfo( fieldSymbol.Name, fieldSymbol.Type.ToString(), + declaringClassName, declaringClassNameWithTypeParameters, fieldSymbol.DeclaredAccessibility, PubliclyWritable(fieldSymbol), @@ -58,11 +66,13 @@ private static MemberSymbolInfo CreateMemberSymbolInfo( private static MemberSymbolInfo CreateMemberSymbolInfo( IPropertySymbol propertySymbol, + string declaringClassName, string declaringClassNameWithTypeParameters) { return new MemberSymbolInfo( propertySymbol.Name, propertySymbol.Type.ToString(), + declaringClassName, declaringClassNameWithTypeParameters, propertySymbol.DeclaredAccessibility, PubliclyWritable(propertySymbol), @@ -75,12 +85,14 @@ private static MemberSymbolInfo CreateMemberSymbolInfo( private static MethodSymbolInfo CreateMethodSymbolInfo( IMethodSymbol methodSymbol, + string declaringClassName, string declaringClassNameWithTypeParameters) { GenericInfo? genericInfo = GetGenericInfo(methodSymbol); return new MethodSymbolInfo( methodSymbol.Name, + declaringClassName, declaringClassNameWithTypeParameters, methodSymbol.DeclaredAccessibility, PubliclyWritable(methodSymbol), diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/CreateStudent.expected.txt index f6111be..f9702a1 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/CreateStudent.expected.txt @@ -6,8 +6,7 @@ #nullable enable using System.Collections.Generic; -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassWithPrivateGenericMethods; @@ -28,34 +27,6 @@ public class CreateStudent : where T5 : new() { private readonly Student student; - private static readonly MethodInfo method1MethodInfo; - private static readonly MethodInfo method2MethodInfo; - private static readonly MethodInfo method3MethodInfo; - - static CreateStudent() - { - method1MethodInfo = typeof(Student).GetMethod( - "Method1", - 4, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(1), Type.MakeGenericMethodParameter(2), Type.MakeGenericMethodParameter(3) }, - null)!; - method2MethodInfo = typeof(Student).GetMethod( - "Method2", - 4, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(1), Type.MakeGenericMethodParameter(2), Type.MakeGenericMethodParameter(3) }, - null)!; - method3MethodInfo = typeof(Student).GetMethod( - "Method3", - 4, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(T1) }, - null)!; - } private CreateStudent() { @@ -106,19 +77,19 @@ public class CreateStudent : IMethod2 IMethod1.Method1(T6 p1, T7 p2, T8 p3, T9 p4) { - CreateStudent.method1MethodInfo.MakeGenericMethod(typeof(T6), typeof(T7), typeof(T8), typeof(T9)).Invoke(student, new object?[] { p1, p2, p3, p4 }); + CallMethod1(student, p1, p2, p3, p4); return this; } IMethod3 IMethod2.Method2(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) { - CreateStudent.method2MethodInfo.MakeGenericMethod(typeof(T6), typeof(T7), typeof(T8), typeof(T9)).Invoke(student, new object?[] { p1, p2, p3, p4, p5, p6, p7, p8, p9 }); + CallMethod2(student, p1, p2, p3, p4, p5, p6, p7, p8, p9); return this; } Student IMethod3.Method3(T1 p1) { - CreateStudent.method3MethodInfo.MakeGenericMethod(typeof(T6), typeof(T7), typeof(T8), typeof(T9)).Invoke(student, new object?[] { p1 }); + CallMethod3(student, p1); return student; } @@ -177,4 +148,25 @@ public class CreateStudent : where T8 : class, System.Collections.Generic.IDictionary where T9 : System.Collections.Generic.List, new(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, T6 p1, T7 p2, T8 p3, T9 p4) + where T6 : unmanaged + where T7 : System.Collections.Generic.List, System.Collections.Generic.IDictionary + where T8 : class, System.Collections.Generic.IDictionary + where T9 : System.Collections.Generic.List, new(); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method2")] + private static extern void CallMethod2(Student student, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) + where T6 : unmanaged + where T7 : System.Collections.Generic.List, System.Collections.Generic.IDictionary + where T8 : class, System.Collections.Generic.IDictionary + where T9 : System.Collections.Generic.List, new(); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method3")] + private static extern void CallMethod3(Student student, T1 p1) + where T6 : unmanaged + where T7 : System.Collections.Generic.List, System.Collections.Generic.IDictionary + where T8 : class, System.Collections.Generic.IDictionary + where T9 : System.Collections.Generic.List, new(); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/CreateStudent.g.cs index f6111be..f9702a1 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/CreateStudent.g.cs @@ -6,8 +6,7 @@ #nullable enable using System.Collections.Generic; -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassWithPrivateGenericMethods; @@ -28,34 +27,6 @@ public class CreateStudent : where T5 : new() { private readonly Student student; - private static readonly MethodInfo method1MethodInfo; - private static readonly MethodInfo method2MethodInfo; - private static readonly MethodInfo method3MethodInfo; - - static CreateStudent() - { - method1MethodInfo = typeof(Student).GetMethod( - "Method1", - 4, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(1), Type.MakeGenericMethodParameter(2), Type.MakeGenericMethodParameter(3) }, - null)!; - method2MethodInfo = typeof(Student).GetMethod( - "Method2", - 4, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), Type.MakeGenericMethodParameter(0), Type.MakeGenericMethodParameter(1), Type.MakeGenericMethodParameter(2), Type.MakeGenericMethodParameter(3) }, - null)!; - method3MethodInfo = typeof(Student).GetMethod( - "Method3", - 4, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(T1) }, - null)!; - } private CreateStudent() { @@ -106,19 +77,19 @@ IMethod1 IWithProperty5.WithProperty5(T5 property5) IMethod2 IMethod1.Method1(T6 p1, T7 p2, T8 p3, T9 p4) { - CreateStudent.method1MethodInfo.MakeGenericMethod(typeof(T6), typeof(T7), typeof(T8), typeof(T9)).Invoke(student, new object?[] { p1, p2, p3, p4 }); + CallMethod1(student, p1, p2, p3, p4); return this; } IMethod3 IMethod2.Method2(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) { - CreateStudent.method2MethodInfo.MakeGenericMethod(typeof(T6), typeof(T7), typeof(T8), typeof(T9)).Invoke(student, new object?[] { p1, p2, p3, p4, p5, p6, p7, p8, p9 }); + CallMethod2(student, p1, p2, p3, p4, p5, p6, p7, p8, p9); return this; } Student IMethod3.Method3(T1 p1) { - CreateStudent.method3MethodInfo.MakeGenericMethod(typeof(T6), typeof(T7), typeof(T8), typeof(T9)).Invoke(student, new object?[] { p1 }); + CallMethod3(student, p1); return student; } @@ -177,4 +148,25 @@ Student Method3(T1 p1) where T8 : class, System.Collections.Generic.IDictionary where T9 : System.Collections.Generic.List, new(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, T6 p1, T7 p2, T8 p3, T9 p4) + where T6 : unmanaged + where T7 : System.Collections.Generic.List, System.Collections.Generic.IDictionary + where T8 : class, System.Collections.Generic.IDictionary + where T9 : System.Collections.Generic.List, new(); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method2")] + private static extern void CallMethod2(Student student, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) + where T6 : unmanaged + where T7 : System.Collections.Generic.List, System.Collections.Generic.IDictionary + where T8 : class, System.Collections.Generic.IDictionary + where T9 : System.Collections.Generic.List, new(); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method3")] + private static extern void CallMethod3(Student student, T1 p1) + where T6 : unmanaged + where T7 : System.Collections.Generic.List, System.Collections.Generic.IDictionary + where T8 : class, System.Collections.Generic.IDictionary + where T9 : System.Collections.Generic.List, new(); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 6c4ab27..5f11054 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,7 +7,7 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter([], + Filter(["GenericClassWithPrivateGenericMethods"], new List { new object[] { "Abstract", "AliasNamespaceClass", "Student" }, @@ -38,7 +38,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "FluentLambdaCompoundClass", "Student|Address|Phone" }, new object[] { "Abstract", "FluentLambdaCompoundOfSameTypeClass", "Student|Address" }, new object[] { "Abstract", "FluentLambdaManyCollectionsClass", "Student|Address" }, - // new object[] { "Abstract", "FluentLambdaManyPrivateCollectionsClass", "Student|Address" }, + new object[] { "Abstract", "FluentLambdaManyPrivateCollectionsClass", "Student|Address" }, new object[] { "Abstract", "FluentLambdaNullablePropertyClass", "Student|Address" }, new object[] { "Abstract", "FluentLambdaRecursiveClass", "Student" }, new object[] { "Abstract", "FluentLambdaSingleStepClass", "Student|Address" }, @@ -48,36 +48,36 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "FluentNullableClass", "Student" }, new object[] { "Abstract", "FluentNullableNoNullableAnnotationClass", "Student" }, new object[] { "Abstract", "FluentNullableNoNullableAnnotationPrivateSetClass", "Student" }, - // new object[] { "Abstract", "FluentReturnMultiStepClass", "Student" }, - // new object[] { "Abstract", "FluentReturnMultiStepPrivateMethodsClass", "Student" }, - // new object[] { "Abstract", "FluentReturnSingleStepClass", "Student" }, - // new object[] { "Abstract", "FluentReturnSingleStepPrivateMethodsClass", "Student" }, - // new object[] { "Abstract", "ForkClass", "Student" }, - // new object[] { "Abstract", "FullyQualifiedTypeClass", "Student" }, - // new object[] { "Abstract", "GenericClass", "Student" }, + new object[] { "Abstract", "FluentReturnMultiStepClass", "Student" }, + new object[] { "Abstract", "FluentReturnMultiStepPrivateMethodsClass", "Student" }, + new object[] { "Abstract", "FluentReturnSingleStepClass", "Student" }, + new object[] { "Abstract", "FluentReturnSingleStepPrivateMethodsClass", "Student" }, + new object[] { "Abstract", "ForkClass", "Student" }, + new object[] { "Abstract", "FullyQualifiedTypeClass", "Student" }, + new object[] { "Abstract", "GenericClass", "Student" }, new object[] { "Abstract", "GenericClassPrivateConstructor", "Student" }, new object[] { "Abstract", "GenericClassPrivateDefaultConstructor", "Student" }, - // new object[] { "Abstract", "GenericClassWithConstraints", "Student" }, - // new object[] { "Abstract", "GenericClassWithGenericMethods", "Student" }, - // new object[] { "Abstract", "GenericClassWithPrivateGenericMethods", "Student" }, - // new object[] { "Abstract", "GenericMethodWithConstraintsClass", "Student" }, - // new object[] { "Abstract", "GenericOverloadedMethodClass", "Student" }, - // new object[] { "Abstract", "GenericOverloadedPrivateMethodClass", "Student" }, - // new object[] { "Abstract", "GetInitPropertyClass", "Student" }, + new object[] { "Abstract", "GenericClassWithConstraints", "Student" }, + new object[] { "Abstract", "GenericClassWithGenericMethods", "Student" }, + new object[] { "Abstract", "GenericClassWithPrivateGenericMethods", "Student" }, + new object[] { "Abstract", "GenericMethodWithConstraintsClass", "Student" }, + new object[] { "Abstract", "GenericOverloadedMethodClass", "Student" }, + new object[] { "Abstract", "GenericOverloadedPrivateMethodClass", "Student" }, + new object[] { "Abstract", "GetInitPropertyClass", "Student" }, new object[] { "Abstract", "GetPrivateInitPropertyClass", "Student" }, - // new object[] { "Abstract", "GetPrivateSetPropertyClass", "Student" }, - // new object[] { "Abstract", "InternalPropertyClass", "Student" }, + new object[] { "Abstract", "GetPrivateSetPropertyClass", "Student" }, + new object[] { "Abstract", "InternalPropertyClass", "Student" }, new object[] { "Abstract", "InheritedClass", "Student|Person" }, new object[] { "Abstract", "InheritedClassPrivateSetters", "Student|Person" }, - // new object[] { "Abstract", "InheritedClassProtectedMembers", "Student|Person" }, - // new object[] { "Abstract", "InheritedClassProtectedSetters", "Student|Person" }, + new object[] { "Abstract", "InheritedClassProtectedMembers", "Student|Person" }, + new object[] { "Abstract", "InheritedClassProtectedSetters", "Student|Person" }, new object[] { "Abstract", "InheritedRecord", "Student|Person" }, - // new object[] { "Abstract", "InternalClass", "Student" }, - // new object[] { "Abstract", "KeywordClass", "Student"}, - // new object[] { "Abstract", "NonGenericCollectionMemberClass", "Student" }, - // new object[] { "Abstract", "NullablePredicateAndCollectionClass", "Student" }, - // new object[] { "Abstract", "OneMemberClass", "Student" }, - // new object[] { "Abstract", "OverloadedMethodClass", "Student" }, + new object[] { "Abstract", "InternalClass", "Student" }, + new object[] { "Abstract", "KeywordClass", "Student"}, + new object[] { "Abstract", "NonGenericCollectionMemberClass", "Student" }, + new object[] { "Abstract", "NullablePredicateAndCollectionClass", "Student" }, + new object[] { "Abstract", "OneMemberClass", "Student" }, + new object[] { "Abstract", "OverloadedMethodClass", "Student" }, new object[] { "Abstract", "ParameterAnnotationsPrivateConstructorClass", "Student" }, new object[] { "Abstract", "ParameterAnnotationsPublicConstructorClass", "Student" }, new object[] { "Abstract", "PartialClass", "Student1|Student2" }, @@ -92,16 +92,16 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "PrivateUnderscoreFieldClass", "Student" }, new object[] { "Abstract", "PublicFieldClass", "Student" }, new object[] { "Abstract", "PublicReadonlyFieldClass", "Student" }, - // new object[] { "Abstract", "SameNameMemberClass", "Student" }, - // new object[] { "Abstract", "SkippableFirstMemberClass", "Student" }, - // new object[] { "Abstract", "SkippableFirstTwoMembersClass", "Student" }, - // new object[] { "Abstract", "SkippableForkMembersClass", "Student" }, - // new object[] { "Abstract", "SkippableLoopClass", "Student" }, - // new object[] { "Abstract", "SkippableMemberClass", "Student" }, - // new object[] { "Abstract", "SkippableSeveralMembersClass", "Student" }, - // new object[] { "Abstract", "SkippableTwoLoopsClass", "Student" }, - // new object[] { "Abstract", "ThreeMemberClass", "Student" }, - // new object[] { "Abstract", "ThreeMemberRecord", "Student" }, + new object[] { "Abstract", "SameNameMemberClass", "Student" }, + new object[] { "Abstract", "SkippableFirstMemberClass", "Student" }, + new object[] { "Abstract", "SkippableFirstTwoMembersClass", "Student" }, + new object[] { "Abstract", "SkippableForkMembersClass", "Student" }, + new object[] { "Abstract", "SkippableLoopClass", "Student" }, + new object[] { "Abstract", "SkippableMemberClass", "Student" }, + new object[] { "Abstract", "SkippableSeveralMembersClass", "Student" }, + new object[] { "Abstract", "SkippableTwoLoopsClass", "Student" }, + new object[] { "Abstract", "ThreeMemberClass", "Student" }, + new object[] { "Abstract", "ThreeMemberRecord", "Student" }, new object[] { "Abstract", "ThreeMemberRecordPrimaryConstructor", "Student" }, new object[] { "Abstract", "ThreeMemberStruct", "Student" }, new object[] { "Abstract", "ThreePrivateMembersClass", "Student" }, @@ -113,7 +113,7 @@ internal class TestDataProvider : IEnumerable new object[] { "Abstract", "TwoParameterCompoundClass", "Student" }, new object[] { "Abstract", "TwoParameterCompoundClassReversedParameters", "Student" }, new object[] { "DocumentedStudentClass", "DocumentedStudent" }, - // new object[] { "PersonClass", "Person" }, + new object[] { "PersonClass", "Person" }, new object[] { "StudentClass", "Student" } }).Select(l => new string[] { "..", "..", "..", "CodeGeneration", "TestClasses" } .Concat(l).Reverse().ToArray()).ToList(); // reversed for better readability in the unit test panel From cfa661e265d64d4f1494fee03c167a5a0fb3969e Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 11:00:32 +0100 Subject: [PATCH 57/67] test: GenericOverloadedPrivateMethodClass --- .../CreateStudent.expected.txt | 120 +++------- .../CreateStudent.g.cs | 120 +++------- .../UsageTests.cs | 14 +- .../CodeGeneration/TestDataProvider.cs | 217 +++++++++--------- 4 files changed, 187 insertions(+), 284 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/CreateStudent.expected.txt index bcf0035..cfba9f6 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/CreateStudent.expected.txt @@ -6,8 +6,7 @@ #nullable enable using System.Collections.Generic; -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericOverloadedPrivateMethodClass; @@ -16,66 +15,6 @@ public class CreateStudent : CreateStudent.IMethod1Method1Method1Method1Method1Method1Method1 { private readonly Student student; - private static readonly MethodInfo method1MethodInfo; - private static readonly MethodInfo method1MethodInfo2; - private static readonly MethodInfo method1MethodInfo3; - private static readonly MethodInfo method1MethodInfo4; - private static readonly MethodInfo method1MethodInfo5; - private static readonly MethodInfo method1MethodInfo6; - private static readonly MethodInfo method1MethodInfo7; - - static CreateStudent() - { - method1MethodInfo = typeof(Student).GetMethod( - "Method1", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int), typeof(string) }, - null)!; - method1MethodInfo2 = typeof(Student).GetMethod( - "Method1", - 1, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int), typeof(string) }, - null)!; - method1MethodInfo3 = typeof(Student).GetMethod( - "Method1", - 1, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(0), typeof(string) }, - null)!; - method1MethodInfo4 = typeof(Student).GetMethod( - "Method1", - 2, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(1), typeof(string) }, - null)!; - method1MethodInfo5 = typeof(Student).GetMethod( - "Method1", - 2, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(1), typeof(string).MakeByRefType() }, - null)!; - method1MethodInfo6 = typeof(Student).GetMethod( - "Method1", - 2, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(1).MakeByRefType(), typeof(string) }, - null)!; - method1MethodInfo7 = typeof(Student).GetMethod( - "Method1", - 2, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(1).MakeByRefType(), typeof(string).MakeByRefType() }, - null)!; - } private CreateStudent() { @@ -90,99 +29,91 @@ public class CreateStudent : public static Student Method1(int p1, string p2) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.method1MethodInfo.Invoke(createStudent.student, new object?[] { p1, p2 }); + CallMethod1(createStudent.student, p1, p2); return createStudent.student; } public static Student Method1(int p1, string p2) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.method1MethodInfo2.MakeGenericMethod(typeof(T)).Invoke(createStudent.student, new object?[] { p1, p2 }); + CallMethod1(createStudent.student, p1, p2); return createStudent.student; } public static Student Method1(T p1, string p2) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.method1MethodInfo3.MakeGenericMethod(typeof(T)).Invoke(createStudent.student, new object?[] { p1, p2 }); + CallMethod1(createStudent.student, p1, p2); return createStudent.student; } public static Student Method1(T p1, string p2) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.method1MethodInfo4.MakeGenericMethod(typeof(S), typeof(T)).Invoke(createStudent.student, new object?[] { p1, p2 }); + CallMethod1(createStudent.student, p1, p2); return createStudent.student; } public static Student Method1(T p1, out string p2) { CreateStudent createStudent = new CreateStudent(); - object?[] args = new object?[] { p1, null }; - CreateStudent.method1MethodInfo5.MakeGenericMethod(typeof(S), typeof(T)).Invoke(createStudent.student, args); - p2 = (string) args[1]!; + CallMethod1(createStudent.student, p1, out p2); return createStudent.student; } public static Student Method1(in T p1, string p2) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.method1MethodInfo6.MakeGenericMethod(typeof(S), typeof(T)).Invoke(createStudent.student, new object?[] { p1, p2 }); + CallMethod1(createStudent.student, in p1, p2); return createStudent.student; } public static Student Method1(in T p1, ref string p2) { CreateStudent createStudent = new CreateStudent(); - object?[] args = new object?[] { p1, p2 }; - CreateStudent.method1MethodInfo7.MakeGenericMethod(typeof(S), typeof(T)).Invoke(createStudent.student, args); - p2 = (string) args[1]!; + CallMethod1(createStudent.student, in p1, ref p2); return createStudent.student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(int p1, string p2) { - CreateStudent.method1MethodInfo.Invoke(student, new object?[] { p1, p2 }); + CallMethod1(student, p1, p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(int p1, string p2) { - CreateStudent.method1MethodInfo2.MakeGenericMethod(typeof(T)).Invoke(student, new object?[] { p1, p2 }); + CallMethod1(student, p1, p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(T p1, string p2) { - CreateStudent.method1MethodInfo3.MakeGenericMethod(typeof(T)).Invoke(student, new object?[] { p1, p2 }); + CallMethod1(student, p1, p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(T p1, string p2) { - CreateStudent.method1MethodInfo4.MakeGenericMethod(typeof(S), typeof(T)).Invoke(student, new object?[] { p1, p2 }); + CallMethod1(student, p1, p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(T p1, out string p2) { - object?[] args = new object?[] { p1, null }; - CreateStudent.method1MethodInfo5.MakeGenericMethod(typeof(S), typeof(T)).Invoke(student, args); - p2 = (string) args[1]!; + CallMethod1(student, p1, out p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(in T p1, string p2) { - CreateStudent.method1MethodInfo6.MakeGenericMethod(typeof(S), typeof(T)).Invoke(student, new object?[] { p1, p2 }); + CallMethod1(student, in p1, p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(in T p1, ref string p2) { - object?[] args = new object?[] { p1, p2 }; - CreateStudent.method1MethodInfo7.MakeGenericMethod(typeof(S), typeof(T)).Invoke(student, args); - p2 = (string) args[1]!; + CallMethod1(student, in p1, ref p2); return student; } @@ -206,4 +137,25 @@ public class CreateStudent : Student Method1(in T p1, ref string p2); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, int p1, string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, int p1, string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, T p1, string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, T p1, string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, T p1, out string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, in T p1, string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, in T p1, ref string p2); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/CreateStudent.g.cs index bcf0035..cfba9f6 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/CreateStudent.g.cs @@ -6,8 +6,7 @@ #nullable enable using System.Collections.Generic; -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericOverloadedPrivateMethodClass; @@ -16,66 +15,6 @@ public class CreateStudent : CreateStudent.IMethod1Method1Method1Method1Method1Method1Method1 { private readonly Student student; - private static readonly MethodInfo method1MethodInfo; - private static readonly MethodInfo method1MethodInfo2; - private static readonly MethodInfo method1MethodInfo3; - private static readonly MethodInfo method1MethodInfo4; - private static readonly MethodInfo method1MethodInfo5; - private static readonly MethodInfo method1MethodInfo6; - private static readonly MethodInfo method1MethodInfo7; - - static CreateStudent() - { - method1MethodInfo = typeof(Student).GetMethod( - "Method1", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int), typeof(string) }, - null)!; - method1MethodInfo2 = typeof(Student).GetMethod( - "Method1", - 1, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(int), typeof(string) }, - null)!; - method1MethodInfo3 = typeof(Student).GetMethod( - "Method1", - 1, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(0), typeof(string) }, - null)!; - method1MethodInfo4 = typeof(Student).GetMethod( - "Method1", - 2, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(1), typeof(string) }, - null)!; - method1MethodInfo5 = typeof(Student).GetMethod( - "Method1", - 2, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(1), typeof(string).MakeByRefType() }, - null)!; - method1MethodInfo6 = typeof(Student).GetMethod( - "Method1", - 2, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(1).MakeByRefType(), typeof(string) }, - null)!; - method1MethodInfo7 = typeof(Student).GetMethod( - "Method1", - 2, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { Type.MakeGenericMethodParameter(1).MakeByRefType(), typeof(string).MakeByRefType() }, - null)!; - } private CreateStudent() { @@ -90,99 +29,91 @@ public static ICreateStudent InitialStep() public static Student Method1(int p1, string p2) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.method1MethodInfo.Invoke(createStudent.student, new object?[] { p1, p2 }); + CallMethod1(createStudent.student, p1, p2); return createStudent.student; } public static Student Method1(int p1, string p2) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.method1MethodInfo2.MakeGenericMethod(typeof(T)).Invoke(createStudent.student, new object?[] { p1, p2 }); + CallMethod1(createStudent.student, p1, p2); return createStudent.student; } public static Student Method1(T p1, string p2) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.method1MethodInfo3.MakeGenericMethod(typeof(T)).Invoke(createStudent.student, new object?[] { p1, p2 }); + CallMethod1(createStudent.student, p1, p2); return createStudent.student; } public static Student Method1(T p1, string p2) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.method1MethodInfo4.MakeGenericMethod(typeof(S), typeof(T)).Invoke(createStudent.student, new object?[] { p1, p2 }); + CallMethod1(createStudent.student, p1, p2); return createStudent.student; } public static Student Method1(T p1, out string p2) { CreateStudent createStudent = new CreateStudent(); - object?[] args = new object?[] { p1, null }; - CreateStudent.method1MethodInfo5.MakeGenericMethod(typeof(S), typeof(T)).Invoke(createStudent.student, args); - p2 = (string) args[1]!; + CallMethod1(createStudent.student, p1, out p2); return createStudent.student; } public static Student Method1(in T p1, string p2) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.method1MethodInfo6.MakeGenericMethod(typeof(S), typeof(T)).Invoke(createStudent.student, new object?[] { p1, p2 }); + CallMethod1(createStudent.student, in p1, p2); return createStudent.student; } public static Student Method1(in T p1, ref string p2) { CreateStudent createStudent = new CreateStudent(); - object?[] args = new object?[] { p1, p2 }; - CreateStudent.method1MethodInfo7.MakeGenericMethod(typeof(S), typeof(T)).Invoke(createStudent.student, args); - p2 = (string) args[1]!; + CallMethod1(createStudent.student, in p1, ref p2); return createStudent.student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(int p1, string p2) { - CreateStudent.method1MethodInfo.Invoke(student, new object?[] { p1, p2 }); + CallMethod1(student, p1, p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(int p1, string p2) { - CreateStudent.method1MethodInfo2.MakeGenericMethod(typeof(T)).Invoke(student, new object?[] { p1, p2 }); + CallMethod1(student, p1, p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(T p1, string p2) { - CreateStudent.method1MethodInfo3.MakeGenericMethod(typeof(T)).Invoke(student, new object?[] { p1, p2 }); + CallMethod1(student, p1, p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(T p1, string p2) { - CreateStudent.method1MethodInfo4.MakeGenericMethod(typeof(S), typeof(T)).Invoke(student, new object?[] { p1, p2 }); + CallMethod1(student, p1, p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(T p1, out string p2) { - object?[] args = new object?[] { p1, null }; - CreateStudent.method1MethodInfo5.MakeGenericMethod(typeof(S), typeof(T)).Invoke(student, args); - p2 = (string) args[1]!; + CallMethod1(student, p1, out p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(in T p1, string p2) { - CreateStudent.method1MethodInfo6.MakeGenericMethod(typeof(S), typeof(T)).Invoke(student, new object?[] { p1, p2 }); + CallMethod1(student, in p1, p2); return student; } Student IMethod1Method1Method1Method1Method1Method1Method1.Method1(in T p1, ref string p2) { - object?[] args = new object?[] { p1, p2 }; - CreateStudent.method1MethodInfo7.MakeGenericMethod(typeof(S), typeof(T)).Invoke(student, args); - p2 = (string) args[1]!; + CallMethod1(student, in p1, ref p2); return student; } @@ -206,4 +137,25 @@ public interface IMethod1Method1Method1Method1Method1Method1Method1 Student Method1(in T p1, ref string p2); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, int p1, string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, int p1, string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, T p1, string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, T p1, string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, T p1, out string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, in T p1, string p2); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Method1")] + private static extern void CallMethod1(Student student, in T p1, ref string p2); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/UsageTests.cs index f8afac7..29cf83f 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericOverloadedPrivateMethodClass/UsageTests.cs @@ -13,28 +13,28 @@ public class UsageTests public void CanExecuteGenericOverloadedPrivateMethodClassTest1() { Student student = CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); + Assert.Equal(new[] { "Called Method1(int, string)" }, student.Logs); } [Fact, Priority(1)] public void CanExecuteGenericOverloadedPrivateMethodClassTest2() { Student student = CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student.Logs); + Assert.Equal(new[] { "Called Method1(int, string)" }, student.Logs); } [Fact, Priority(1)] public void CanExecuteGenericOverloadedPrivateMethodClassTest3() { Student student = CreateStudent.Method1("string1", "string2"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); + Assert.Equal(new[] { "Called Method1(T, string)" }, student.Logs); } [Fact, Priority(1)] public void CanExecuteGenericOverloadedPrivateMethodClassTest4() { Student student = CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student.Logs); + Assert.Equal(new[] { "Called Method1(T, string)" }, student.Logs); } [Fact, Priority(1)] @@ -42,7 +42,7 @@ public void CanExecuteGenericOverloadedPrivateMethodClassTest5() { string string1 = "string1"; Student student = CreateStudent.Method1(0, out string1); - Assert.Equal(new string[] { "Called Method1(T, out string)" }, student.Logs); + Assert.Equal(new[] { "Called Method1(T, out string)" }, student.Logs); } [Fact, Priority(1)] @@ -50,7 +50,7 @@ public void CanExecuteGenericOverloadedPrivateMethodClassTest6() { int i = 0; Student student = CreateStudent.Method1(in i, "string1"); - Assert.Equal(new string[] { "Called Method1(in T, string)" }, student.Logs); + Assert.Equal(new[] { "Called Method1(in T, string)" }, student.Logs); } [Fact, Priority(1)] @@ -59,7 +59,7 @@ public void CanExecuteGenericOverloadedPrivateMethodClassTest7() int i = 0; string string1 = "string"; Student student = CreateStudent.Method1(in i, ref string1); - Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student.Logs); + Assert.Equal(new[] { "Called Method1(in T, ref string)" }, student.Logs); } } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 5f11054..26ccb97 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -7,115 +7,114 @@ namespace M31.FluentApi.Tests.CodeGeneration; internal class TestDataProvider : IEnumerable { private readonly List testClasses = - Filter(["GenericClassWithPrivateGenericMethods"], - new List - { - new object[] { "Abstract", "AliasNamespaceClass", "Student" }, - new object[] { "Abstract", "CollectionInterfaceMemberClass", "Student" }, - new object[] { "Abstract", "CollectionMemberClass", "Student" }, - new object[] { "Abstract", "CollectionMemberClassWithSuppression", "Student" }, - new object[] { "Abstract", "CollectionNullableArrayClass", "Student" }, - new object[] { "Abstract", "ContinueWithAfterCompoundClass", "Student" }, - new object[] { "Abstract", "ContinueWithInForkClass", "Student" }, - new object[] { "Abstract", "ContinueWithOfOverloadedMethodClass", "Student" }, - new object[] { "Abstract", "ContinueWithSelfClass", "Student" }, - new object[] { "Abstract", "CustomFluentMethodNameClass", "Student" }, - new object[] { "Abstract", "DefaultFluentMethodNameClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "CommentedCompoundClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "CommentedLambdaCollectionClass", "Student|Phone" }, - new object[] { "Abstract", "FluentApiComments", "CommentedMethodsClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "CommentedPropertiesClassAdvanced", "Student" }, - new object[] { "Abstract", "FluentApiComments", "IncompletelyCommentedPropertyClass", "Student"}, - new object[] { "Abstract", "FluentApiComments", "RedundantCommentCompoundClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass", "Student" }, - new object[] { "Abstract", "FluentApiComments", "WronglyCommentedClass2", "Student" }, - new object[] { "Abstract", "EmptyClass", "Student" }, - new object[] { "Abstract", "FluentDefaultMemberClass", "Student" }, - new object[] { "Abstract", "FluentLambdaClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaClassInDifferentNamespace", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaCollectionClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaCompoundClass", "Student|Address|Phone" }, - new object[] { "Abstract", "FluentLambdaCompoundOfSameTypeClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaManyCollectionsClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaManyPrivateCollectionsClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaNullablePropertyClass", "Student|Address" }, - new object[] { "Abstract", "FluentLambdaRecursiveClass", "Student" }, - new object[] { "Abstract", "FluentLambdaSingleStepClass", "Student|Address" }, - new object[] { "Abstract", "FluentMethodClass", "Student" }, - new object[] { "Abstract", "FluentMethodDefaultValuesClass", "Student" }, - new object[] { "Abstract", "FluentMethodParameterModifiersClass", "Student" }, - new object[] { "Abstract", "FluentNullableClass", "Student" }, - new object[] { "Abstract", "FluentNullableNoNullableAnnotationClass", "Student" }, - new object[] { "Abstract", "FluentNullableNoNullableAnnotationPrivateSetClass", "Student" }, - new object[] { "Abstract", "FluentReturnMultiStepClass", "Student" }, - new object[] { "Abstract", "FluentReturnMultiStepPrivateMethodsClass", "Student" }, - new object[] { "Abstract", "FluentReturnSingleStepClass", "Student" }, - new object[] { "Abstract", "FluentReturnSingleStepPrivateMethodsClass", "Student" }, - new object[] { "Abstract", "ForkClass", "Student" }, - new object[] { "Abstract", "FullyQualifiedTypeClass", "Student" }, - new object[] { "Abstract", "GenericClass", "Student" }, - new object[] { "Abstract", "GenericClassPrivateConstructor", "Student" }, - new object[] { "Abstract", "GenericClassPrivateDefaultConstructor", "Student" }, - new object[] { "Abstract", "GenericClassWithConstraints", "Student" }, - new object[] { "Abstract", "GenericClassWithGenericMethods", "Student" }, - new object[] { "Abstract", "GenericClassWithPrivateGenericMethods", "Student" }, - new object[] { "Abstract", "GenericMethodWithConstraintsClass", "Student" }, - new object[] { "Abstract", "GenericOverloadedMethodClass", "Student" }, - new object[] { "Abstract", "GenericOverloadedPrivateMethodClass", "Student" }, - new object[] { "Abstract", "GetInitPropertyClass", "Student" }, - new object[] { "Abstract", "GetPrivateInitPropertyClass", "Student" }, - new object[] { "Abstract", "GetPrivateSetPropertyClass", "Student" }, - new object[] { "Abstract", "InternalPropertyClass", "Student" }, - new object[] { "Abstract", "InheritedClass", "Student|Person" }, - new object[] { "Abstract", "InheritedClassPrivateSetters", "Student|Person" }, - new object[] { "Abstract", "InheritedClassProtectedMembers", "Student|Person" }, - new object[] { "Abstract", "InheritedClassProtectedSetters", "Student|Person" }, - new object[] { "Abstract", "InheritedRecord", "Student|Person" }, - new object[] { "Abstract", "InternalClass", "Student" }, - new object[] { "Abstract", "KeywordClass", "Student"}, - new object[] { "Abstract", "NonGenericCollectionMemberClass", "Student" }, - new object[] { "Abstract", "NullablePredicateAndCollectionClass", "Student" }, - new object[] { "Abstract", "OneMemberClass", "Student" }, - new object[] { "Abstract", "OverloadedMethodClass", "Student" }, - new object[] { "Abstract", "ParameterAnnotationsPrivateConstructorClass", "Student" }, - new object[] { "Abstract", "ParameterAnnotationsPublicConstructorClass", "Student" }, - new object[] { "Abstract", "PartialClass", "Student1|Student2" }, - new object[] { "Abstract", "PredicateClass", "Student" }, - new object[] { "Abstract", "PredicatePrivateFieldClass", "Student" }, - new object[] { "Abstract", "PrivateConstructorClass", "Student" }, - new object[] { "Abstract", "PrivateFieldClass", "Student" }, - new object[] { "Abstract", "PrivateFluentMethodClass", "Student" }, - new object[] { "Abstract", "PrivateFluentMethodNullableParameterClass", "Student" }, - new object[] { "Abstract", "PrivateFluentMethodParameterModifiersClass", "Student" }, - new object[] { "Abstract", "PrivateReadonlyFieldClass", "Student" }, - new object[] { "Abstract", "PrivateUnderscoreFieldClass", "Student" }, - new object[] { "Abstract", "PublicFieldClass", "Student" }, - new object[] { "Abstract", "PublicReadonlyFieldClass", "Student" }, - new object[] { "Abstract", "SameNameMemberClass", "Student" }, - new object[] { "Abstract", "SkippableFirstMemberClass", "Student" }, - new object[] { "Abstract", "SkippableFirstTwoMembersClass", "Student" }, - new object[] { "Abstract", "SkippableForkMembersClass", "Student" }, - new object[] { "Abstract", "SkippableLoopClass", "Student" }, - new object[] { "Abstract", "SkippableMemberClass", "Student" }, - new object[] { "Abstract", "SkippableSeveralMembersClass", "Student" }, - new object[] { "Abstract", "SkippableTwoLoopsClass", "Student" }, - new object[] { "Abstract", "ThreeMemberClass", "Student" }, - new object[] { "Abstract", "ThreeMemberRecord", "Student" }, - new object[] { "Abstract", "ThreeMemberRecordPrimaryConstructor", "Student" }, - new object[] { "Abstract", "ThreeMemberStruct", "Student" }, - new object[] { "Abstract", "ThreePrivateMembersClass", "Student" }, - new object[] { "Abstract", "ThreeMemberRecordStruct", "Student" }, - new object[] { "Abstract", "TryBreakFluentApiClass1", "Student" }, - new object[] { "Abstract", "TryBreakFluentApiClass2", "Student" }, - new object[] { "Abstract", "TryBreakFluentApiClass3", "Student|Address" }, - new object[] { "Abstract", "TwoMemberClass", "Student" }, - new object[] { "Abstract", "TwoParameterCompoundClass", "Student" }, - new object[] { "Abstract", "TwoParameterCompoundClassReversedParameters", "Student" }, - new object[] { "DocumentedStudentClass", "DocumentedStudent" }, - new object[] { "PersonClass", "Person" }, - new object[] { "StudentClass", "Student" } - }).Select(l => new string[] { "..", "..", "..", "CodeGeneration", "TestClasses" } + Filter([], + [ + ["Abstract", "AliasNamespaceClass", "Student"], + ["Abstract", "CollectionInterfaceMemberClass", "Student"], + ["Abstract", "CollectionMemberClass", "Student"], + ["Abstract", "CollectionMemberClassWithSuppression", "Student"], + ["Abstract", "CollectionNullableArrayClass", "Student"], + ["Abstract", "ContinueWithAfterCompoundClass", "Student"], + ["Abstract", "ContinueWithInForkClass", "Student"], + ["Abstract", "ContinueWithOfOverloadedMethodClass", "Student"], + ["Abstract", "ContinueWithSelfClass", "Student"], + ["Abstract", "CustomFluentMethodNameClass", "Student"], + ["Abstract", "DefaultFluentMethodNameClass", "Student"], + ["Abstract", "FluentApiComments", "CommentedCompoundClass", "Student"], + ["Abstract", "FluentApiComments", "CommentedLambdaCollectionClass", "Student|Phone"], + ["Abstract", "FluentApiComments", "CommentedMethodsClass", "Student"], + ["Abstract", "FluentApiComments", "CommentedPropertiesClass", "Student"], + ["Abstract", "FluentApiComments", "CommentedPropertiesClassAdvanced", "Student"], + ["Abstract", "FluentApiComments", "IncompletelyCommentedPropertyClass", "Student"], + ["Abstract", "FluentApiComments", "RedundantCommentCompoundClass", "Student"], + ["Abstract", "FluentApiComments", "WronglyCommentedClass", "Student"], + ["Abstract", "FluentApiComments", "WronglyCommentedClass2", "Student"], + ["Abstract", "EmptyClass", "Student"], + ["Abstract", "FluentDefaultMemberClass", "Student"], + ["Abstract", "FluentLambdaClass", "Student|Address"], + ["Abstract", "FluentLambdaClassInDifferentNamespace", "Student|Address"], + ["Abstract", "FluentLambdaCollectionClass", "Student|Address"], + ["Abstract", "FluentLambdaCompoundClass", "Student|Address|Phone"], + ["Abstract", "FluentLambdaCompoundOfSameTypeClass", "Student|Address"], + ["Abstract", "FluentLambdaManyCollectionsClass", "Student|Address"], + ["Abstract", "FluentLambdaManyPrivateCollectionsClass", "Student|Address"], + ["Abstract", "FluentLambdaNullablePropertyClass", "Student|Address"], + ["Abstract", "FluentLambdaRecursiveClass", "Student"], + ["Abstract", "FluentLambdaSingleStepClass", "Student|Address"], + ["Abstract", "FluentMethodClass", "Student"], + ["Abstract", "FluentMethodDefaultValuesClass", "Student"], + ["Abstract", "FluentMethodParameterModifiersClass", "Student"], + ["Abstract", "FluentNullableClass", "Student"], + ["Abstract", "FluentNullableNoNullableAnnotationClass", "Student"], + ["Abstract", "FluentNullableNoNullableAnnotationPrivateSetClass", "Student"], + ["Abstract", "FluentReturnMultiStepClass", "Student"], + ["Abstract", "FluentReturnMultiStepPrivateMethodsClass", "Student"], + ["Abstract", "FluentReturnSingleStepClass", "Student"], + ["Abstract", "FluentReturnSingleStepPrivateMethodsClass", "Student"], + ["Abstract", "ForkClass", "Student"], + ["Abstract", "FullyQualifiedTypeClass", "Student"], + ["Abstract", "GenericClass", "Student"], + ["Abstract", "GenericClassPrivateConstructor", "Student"], + ["Abstract", "GenericClassPrivateDefaultConstructor", "Student"], + ["Abstract", "GenericClassWithConstraints", "Student"], + ["Abstract", "GenericClassWithGenericMethods", "Student"], + ["Abstract", "GenericClassWithPrivateGenericMethods", "Student"], + ["Abstract", "GenericMethodWithConstraintsClass", "Student"], + ["Abstract", "GenericOverloadedMethodClass", "Student"], + ["Abstract", "GenericOverloadedPrivateMethodClass", "Student"], + ["Abstract", "GetInitPropertyClass", "Student"], + ["Abstract", "GetPrivateInitPropertyClass", "Student"], + ["Abstract", "GetPrivateSetPropertyClass", "Student"], + ["Abstract", "InternalPropertyClass", "Student"], + ["Abstract", "InheritedClass", "Student|Person"], + ["Abstract", "InheritedClassPrivateSetters", "Student|Person"], + ["Abstract", "InheritedClassProtectedMembers", "Student|Person"], + ["Abstract", "InheritedClassProtectedSetters", "Student|Person"], + ["Abstract", "InheritedRecord", "Student|Person"], + ["Abstract", "InternalClass", "Student"], + ["Abstract", "KeywordClass", "Student"], + ["Abstract", "NonGenericCollectionMemberClass", "Student"], + ["Abstract", "NullablePredicateAndCollectionClass", "Student"], + ["Abstract", "OneMemberClass", "Student"], + ["Abstract", "OverloadedMethodClass", "Student"], + ["Abstract", "ParameterAnnotationsPrivateConstructorClass", "Student"], + ["Abstract", "ParameterAnnotationsPublicConstructorClass", "Student"], + ["Abstract", "PartialClass", "Student1|Student2"], + ["Abstract", "PredicateClass", "Student"], + ["Abstract", "PredicatePrivateFieldClass", "Student"], + ["Abstract", "PrivateConstructorClass", "Student"], + ["Abstract", "PrivateFieldClass", "Student"], + ["Abstract", "PrivateFluentMethodClass", "Student"], + ["Abstract", "PrivateFluentMethodNullableParameterClass", "Student"], + ["Abstract", "PrivateFluentMethodParameterModifiersClass", "Student"], + ["Abstract", "PrivateReadonlyFieldClass", "Student"], + ["Abstract", "PrivateUnderscoreFieldClass", "Student"], + ["Abstract", "PublicFieldClass", "Student"], + ["Abstract", "PublicReadonlyFieldClass", "Student"], + ["Abstract", "SameNameMemberClass", "Student"], + ["Abstract", "SkippableFirstMemberClass", "Student"], + ["Abstract", "SkippableFirstTwoMembersClass", "Student"], + ["Abstract", "SkippableForkMembersClass", "Student"], + ["Abstract", "SkippableLoopClass", "Student"], + ["Abstract", "SkippableMemberClass", "Student"], + ["Abstract", "SkippableSeveralMembersClass", "Student"], + ["Abstract", "SkippableTwoLoopsClass", "Student"], + ["Abstract", "ThreeMemberClass", "Student"], + ["Abstract", "ThreeMemberRecord", "Student"], + ["Abstract", "ThreeMemberRecordPrimaryConstructor", "Student"], + ["Abstract", "ThreeMemberStruct", "Student"], + ["Abstract", "ThreePrivateMembersClass", "Student"], + ["Abstract", "ThreeMemberRecordStruct", "Student"], + ["Abstract", "TryBreakFluentApiClass1", "Student"], + ["Abstract", "TryBreakFluentApiClass2", "Student"], + ["Abstract", "TryBreakFluentApiClass3", "Student|Address"], + ["Abstract", "TwoMemberClass", "Student"], + ["Abstract", "TwoParameterCompoundClass", "Student"], + ["Abstract", "TwoParameterCompoundClassReversedParameters", "Student"], + ["DocumentedStudentClass", "DocumentedStudent"], + ["PersonClass", "Person"], + ["StudentClass", "Student"] + ]).Select(l => new string[] { "..", "..", "..", "CodeGeneration", "TestClasses" } .Concat(l).Reverse().ToArray()).ToList(); // reversed for better readability in the unit test panel public IEnumerator GetEnumerator() => testClasses.GetEnumerator(); From 59bd0e159b9966776191d140319ab243c46b20bd Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 11:02:03 +0100 Subject: [PATCH 58/67] test: write expected --- .../CreateStudent.expected.txt | 126 +++++++++--------- .../CreateStudent.g.cs | 126 +++++++++--------- .../CreateStudent.expected.txt | 15 +-- .../CreateStudent.g.cs | 15 +-- .../CreateStudent.expected.txt | 73 +++------- .../CreateStudent.g.cs | 73 +++------- .../CreateStudent.expected.txt | 15 +-- .../GetInitPropertyClass/CreateStudent.g.cs | 15 +-- .../CreateStudent.expected.txt | 15 +-- .../CreateStudent.g.cs | 15 +-- .../CreatePerson.g.cs | 22 ++- .../CreateStudent.expected.txt | 29 ++-- .../CreateStudent.g.cs | 29 ++-- .../CreatePerson.g.cs | 22 ++- .../CreateStudent.expected.txt | 29 ++-- .../CreateStudent.g.cs | 29 ++-- .../CreateStudent.expected.txt | 17 +-- .../CreateStudent.g.cs | 17 +-- .../CreateStudent.expected.txt | 37 ++--- .../OverloadedMethodClass/CreateStudent.g.cs | 37 ++--- .../CreateStudent.expected.txt | 29 ++-- .../SameNameMemberClass/CreateStudent.g.cs | 29 ++-- .../PersonClass/CreatePerson.expected.txt | 121 ++++++----------- .../TestClasses/PersonClass/CreatePerson.g.cs | 121 ++++++----------- 24 files changed, 432 insertions(+), 624 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.expected.txt index 1d592ca..a396331 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.expected.txt @@ -6,7 +6,7 @@ #nullable enable using System.Collections.Generic; -using System.Reflection; +using System.Runtime.CompilerServices; using System; using System.Linq; @@ -18,26 +18,6 @@ public class CreateStudent : CreateStudent.IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo addressesAPropertyInfo; - private static readonly PropertyInfo addressesBPropertyInfo; - private static readonly PropertyInfo addressesCPropertyInfo; - private static readonly PropertyInfo addressesDPropertyInfo; - private static readonly PropertyInfo addressesEPropertyInfo; - private static readonly PropertyInfo addressesFPropertyInfo; - private static readonly PropertyInfo addressesGPropertyInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - addressesAPropertyInfo = typeof(Student).GetProperty("AddressesA", BindingFlags.Instance | BindingFlags.Public)!; - addressesBPropertyInfo = typeof(Student).GetProperty("AddressesB", BindingFlags.Instance | BindingFlags.Public)!; - addressesCPropertyInfo = typeof(Student).GetProperty("AddressesC", BindingFlags.Instance | BindingFlags.Public)!; - addressesDPropertyInfo = typeof(Student).GetProperty("AddressesD", BindingFlags.Instance | BindingFlags.Public)!; - addressesEPropertyInfo = typeof(Student).GetProperty("AddressesE", BindingFlags.Instance | BindingFlags.Public)!; - addressesFPropertyInfo = typeof(Student).GetProperty("AddressesF", BindingFlags.Instance | BindingFlags.Public)!; - addressesGPropertyInfo = typeof(Student).GetProperty("AddressesG", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -52,241 +32,241 @@ public class CreateStudent : public static IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(System.Collections.Generic.List addressesA) { - CreateStudent.addressesAPropertyInfo.SetValue(student, addressesA); + SetAddressesA(student, addressesA); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesA) { - CreateStudent.addressesAPropertyInfo.SetValue(student, new List(addressesA)); + SetAddressesA(student, new List(addressesA)); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params Func[] createAddressesA) { - CreateStudent.addressesAPropertyInfo.SetValue(student, new List(createAddressesA.Select(createAddressA => createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); + SetAddressesA(student, new List(createAddressesA.Select(createAddressA => createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressA) { - CreateStudent.addressesAPropertyInfo.SetValue(student, new List(1){ addressA }); + SetAddressesA(student, new List(1){ addressA }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(Func createAddressA) { - CreateStudent.addressesAPropertyInfo.SetValue(student, new List(1){ createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesA(student, new List(1){ createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesA() { - CreateStudent.addressesAPropertyInfo.SetValue(student, new List(0)); + SetAddressesA(student, new List(0)); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB) { - CreateStudent.addressesBPropertyInfo.SetValue(student, addressesB); + SetAddressesB(student, addressesB); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesB) { - CreateStudent.addressesBPropertyInfo.SetValue(student, addressesB); + SetAddressesB(student, addressesB); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params Func[] createAddressesB) { - CreateStudent.addressesBPropertyInfo.SetValue(student, createAddressesB.Select(createAddressB => createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesB(student, createAddressesB.Select(createAddressB => createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressB) { - CreateStudent.addressesBPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressB }); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressB }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(Func createAddressB) { - CreateStudent.addressesBPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesB() { - CreateStudent.addressesBPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesC) { - CreateStudent.addressesCPropertyInfo.SetValue(student, addressesC); + SetAddressesC(student, addressesC); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params Func[] createAddressesC) { - CreateStudent.addressesCPropertyInfo.SetValue(student, createAddressesC.Select(createAddressC => createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesC(student, createAddressesC.Select(createAddressC => createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressC) { - CreateStudent.addressesCPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressC }); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressC }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(Func createAddressC) { - CreateStudent.addressesCPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesC() { - CreateStudent.addressesCPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(System.Collections.Generic.HashSet addressesD) { - CreateStudent.addressesDPropertyInfo.SetValue(student, addressesD); + SetAddressesD(student, addressesD); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesD) { - CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(addressesD)); + SetAddressesD(student, new HashSet(addressesD)); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params Func[] createAddressesD) { - CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(createAddressesD.Select(createAddressD => createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); + SetAddressesD(student, new HashSet(createAddressesD.Select(createAddressD => createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressD) { - CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(1){ addressD }); + SetAddressesD(student, new HashSet(1){ addressD }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(Func createAddressD) { - CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(1){ createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesD(student, new HashSet(1){ createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesD() { - CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(0)); + SetAddressesD(student, new HashSet(0)); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[]? addressesE) { - CreateStudent.addressesEPropertyInfo.SetValue(student, addressesE); + SetAddressesE(student, addressesE); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params Func[]? createAddressesE) { - CreateStudent.addressesEPropertyInfo.SetValue(student, createAddressesE?.Select(createAddressE => createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesE(student, createAddressesE?.Select(createAddressE => createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressE) { - CreateStudent.addressesEPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressE }); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressE }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(Func createAddressE) { - CreateStudent.addressesEPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesE() { - CreateStudent.addressesEPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[] addressesF) { - CreateStudent.addressesFPropertyInfo.SetValue(student, addressesF); + SetAddressesF(student, addressesF); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params Func[] createAddressesF) { - CreateStudent.addressesFPropertyInfo.SetValue(student, createAddressesF.Select(createAddressF => createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesF(student, createAddressesF.Select(createAddressF => createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressF) { - CreateStudent.addressesFPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressF }); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressF }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(Func createAddressF) { - CreateStudent.addressesFPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesF() { - CreateStudent.addressesFPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[]? addressesG) { - CreateStudent.addressesGPropertyInfo.SetValue(student, addressesG); + SetAddressesG(student, addressesG); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params Func[]? createAddressesG) { - CreateStudent.addressesGPropertyInfo.SetValue(student, createAddressesG?.Select(createAddressG => createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesG(student, createAddressesG?.Select(createAddressG => createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressG) { - CreateStudent.addressesGPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressG }); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressG }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(Func createAddressG) { - CreateStudent.addressesGPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesG() { - CreateStudent.addressesGPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); return student; } @@ -377,4 +357,28 @@ public class CreateStudent : Student WithZeroAddressesG(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesA")] + private static extern void SetAddressesA(Student student, System.Collections.Generic.List value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesB")] + private static extern void SetAddressesB(Student student, System.Collections.Generic.IReadOnlyCollection value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesC")] + private static extern void SetAddressesC(Student student, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesD")] + private static extern void SetAddressesD(Student student, System.Collections.Generic.HashSet value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesE")] + private static extern void SetAddressesE(Student student, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[]? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesF")] + private static extern void SetAddressesF(Student student, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[] value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesG")] + private static extern void SetAddressesG(Student student, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[]? value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.g.cs index 1d592ca..a396331 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System.Collections.Generic; -using System.Reflection; +using System.Runtime.CompilerServices; using System; using System.Linq; @@ -18,26 +18,6 @@ public class CreateStudent : CreateStudent.IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo addressesAPropertyInfo; - private static readonly PropertyInfo addressesBPropertyInfo; - private static readonly PropertyInfo addressesCPropertyInfo; - private static readonly PropertyInfo addressesDPropertyInfo; - private static readonly PropertyInfo addressesEPropertyInfo; - private static readonly PropertyInfo addressesFPropertyInfo; - private static readonly PropertyInfo addressesGPropertyInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - addressesAPropertyInfo = typeof(Student).GetProperty("AddressesA", BindingFlags.Instance | BindingFlags.Public)!; - addressesBPropertyInfo = typeof(Student).GetProperty("AddressesB", BindingFlags.Instance | BindingFlags.Public)!; - addressesCPropertyInfo = typeof(Student).GetProperty("AddressesC", BindingFlags.Instance | BindingFlags.Public)!; - addressesDPropertyInfo = typeof(Student).GetProperty("AddressesD", BindingFlags.Instance | BindingFlags.Public)!; - addressesEPropertyInfo = typeof(Student).GetProperty("AddressesE", BindingFlags.Instance | BindingFlags.Public)!; - addressesFPropertyInfo = typeof(Student).GetProperty("AddressesF", BindingFlags.Instance | BindingFlags.Public)!; - addressesGPropertyInfo = typeof(Student).GetProperty("AddressesG", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -52,241 +32,241 @@ public static ICreateStudent InitialStep() public static IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(System.Collections.Generic.List addressesA) { - CreateStudent.addressesAPropertyInfo.SetValue(student, addressesA); + SetAddressesA(student, addressesA); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesA) { - CreateStudent.addressesAPropertyInfo.SetValue(student, new List(addressesA)); + SetAddressesA(student, new List(addressesA)); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params Func[] createAddressesA) { - CreateStudent.addressesAPropertyInfo.SetValue(student, new List(createAddressesA.Select(createAddressA => createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); + SetAddressesA(student, new List(createAddressesA.Select(createAddressA => createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressA) { - CreateStudent.addressesAPropertyInfo.SetValue(student, new List(1){ addressA }); + SetAddressesA(student, new List(1){ addressA }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(Func createAddressA) { - CreateStudent.addressesAPropertyInfo.SetValue(student, new List(1){ createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesA(student, new List(1){ createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesA() { - CreateStudent.addressesAPropertyInfo.SetValue(student, new List(0)); + SetAddressesA(student, new List(0)); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB) { - CreateStudent.addressesBPropertyInfo.SetValue(student, addressesB); + SetAddressesB(student, addressesB); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesB) { - CreateStudent.addressesBPropertyInfo.SetValue(student, addressesB); + SetAddressesB(student, addressesB); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params Func[] createAddressesB) { - CreateStudent.addressesBPropertyInfo.SetValue(student, createAddressesB.Select(createAddressB => createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesB(student, createAddressesB.Select(createAddressB => createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressB) { - CreateStudent.addressesBPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressB }); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressB }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(Func createAddressB) { - CreateStudent.addressesBPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesB() { - CreateStudent.addressesBPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesC) { - CreateStudent.addressesCPropertyInfo.SetValue(student, addressesC); + SetAddressesC(student, addressesC); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params Func[] createAddressesC) { - CreateStudent.addressesCPropertyInfo.SetValue(student, createAddressesC.Select(createAddressC => createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesC(student, createAddressesC.Select(createAddressC => createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressC) { - CreateStudent.addressesCPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressC }); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressC }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(Func createAddressC) { - CreateStudent.addressesCPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesC() { - CreateStudent.addressesCPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(System.Collections.Generic.HashSet addressesD) { - CreateStudent.addressesDPropertyInfo.SetValue(student, addressesD); + SetAddressesD(student, addressesD); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesD) { - CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(addressesD)); + SetAddressesD(student, new HashSet(addressesD)); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params Func[] createAddressesD) { - CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(createAddressesD.Select(createAddressD => createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); + SetAddressesD(student, new HashSet(createAddressesD.Select(createAddressD => createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressD) { - CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(1){ addressD }); + SetAddressesD(student, new HashSet(1){ addressD }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(Func createAddressD) { - CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(1){ createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesD(student, new HashSet(1){ createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesD() { - CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(0)); + SetAddressesD(student, new HashSet(0)); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[]? addressesE) { - CreateStudent.addressesEPropertyInfo.SetValue(student, addressesE); + SetAddressesE(student, addressesE); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params Func[]? createAddressesE) { - CreateStudent.addressesEPropertyInfo.SetValue(student, createAddressesE?.Select(createAddressE => createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesE(student, createAddressesE?.Select(createAddressE => createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressE) { - CreateStudent.addressesEPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressE }); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressE }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(Func createAddressE) { - CreateStudent.addressesEPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesE() { - CreateStudent.addressesEPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[] addressesF) { - CreateStudent.addressesFPropertyInfo.SetValue(student, addressesF); + SetAddressesF(student, addressesF); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params Func[] createAddressesF) { - CreateStudent.addressesFPropertyInfo.SetValue(student, createAddressesF.Select(createAddressF => createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesF(student, createAddressesF.Select(createAddressF => createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressF) { - CreateStudent.addressesFPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressF }); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressF }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(Func createAddressF) { - CreateStudent.addressesFPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesF() { - CreateStudent.addressesFPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[]? addressesG) { - CreateStudent.addressesGPropertyInfo.SetValue(student, addressesG); + SetAddressesG(student, addressesG); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params Func[]? createAddressesG) { - CreateStudent.addressesGPropertyInfo.SetValue(student, createAddressesG?.Select(createAddressG => createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesG(student, createAddressesG?.Select(createAddressG => createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressG) { - CreateStudent.addressesGPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressG }); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressG }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(Func createAddressG) { - CreateStudent.addressesGPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesG() { - CreateStudent.addressesGPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); return student; } @@ -377,4 +357,28 @@ public interface IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAd Student WithZeroAddressesG(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesA")] + private static extern void SetAddressesA(Student student, System.Collections.Generic.List value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesB")] + private static extern void SetAddressesB(Student student, System.Collections.Generic.IReadOnlyCollection value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesC")] + private static extern void SetAddressesC(Student student, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesD")] + private static extern void SetAddressesD(Student student, System.Collections.Generic.HashSet value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesE")] + private static extern void SetAddressesE(Student student, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[]? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesF")] + private static extern void SetAddressesF(Student student, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[] value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_AddressesG")] + private static extern void SetAddressesG(Student student, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[]? value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.expected.txt index c6bc5cb..3ab8d2b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.expected.txt @@ -6,7 +6,7 @@ #nullable enable using System.Collections.Generic; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentReturnMultiStepClass; @@ -16,12 +16,6 @@ public class CreateStudent : CreateStudent.IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -36,13 +30,13 @@ public class CreateStudent : public static IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } @@ -85,4 +79,7 @@ public class CreateStudent : int ReturnIntMethodWithRefParameter(ref string s); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.g.cs index c6bc5cb..3ab8d2b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System.Collections.Generic; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentReturnMultiStepClass; @@ -16,12 +16,6 @@ public class CreateStudent : CreateStudent.IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter { private readonly Student student; - private static readonly PropertyInfo namePropertyInfo; - - static CreateStudent() - { - namePropertyInfo = typeof(Student).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -36,13 +30,13 @@ public static ICreateStudent InitialStep() public static IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } @@ -85,4 +79,7 @@ public interface IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethod int ReturnIntMethodWithRefParameter(ref string s); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/CreateStudent.expected.txt index e3f1903..4912474 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/CreateStudent.expected.txt @@ -6,8 +6,7 @@ #nullable enable using System.Collections.Generic; -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass; @@ -16,42 +15,6 @@ public class CreateStudent : CreateStudent.IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter { private readonly Student student; - private static readonly MethodInfo returnVoidMethodMethodInfo; - private static readonly MethodInfo returnIntMethodMethodInfo; - private static readonly MethodInfo returnListMethodMethodInfo; - private static readonly MethodInfo returnIntMethodWithRefParameterMethodInfo; - - static CreateStudent() - { - returnVoidMethodMethodInfo = typeof(Student).GetMethod( - "ReturnVoidMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnIntMethodMethodInfo = typeof(Student).GetMethod( - "ReturnIntMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnListMethodMethodInfo = typeof(Student).GetMethod( - "ReturnListMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnIntMethodWithRefParameterMethodInfo = typeof(Student).GetMethod( - "ReturnIntMethodWithRefParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string).MakeByRefType() }, - null)!; - } private CreateStudent() { @@ -66,51 +29,45 @@ public class CreateStudent : public static void ReturnVoidMethod() { CreateStudent createStudent = new CreateStudent(); - CreateStudent.returnVoidMethodMethodInfo.Invoke(createStudent.student, new object?[] { }); + CallReturnVoidMethod(createStudent.student); } public static int ReturnIntMethod() { CreateStudent createStudent = new CreateStudent(); - return (int) CreateStudent.returnIntMethodMethodInfo.Invoke(createStudent.student, new object?[] { })!; + return CallReturnIntMethod(createStudent.student); } public static System.Collections.Generic.List ReturnListMethod() { CreateStudent createStudent = new CreateStudent(); - return (System.Collections.Generic.List) CreateStudent.returnListMethodMethodInfo.Invoke(createStudent.student, new object?[] { })!; + return CallReturnListMethod(createStudent.student); } public static int ReturnIntMethodWithRefParameter(ref string s) { CreateStudent createStudent = new CreateStudent(); - object?[] args = new object?[] { s }; - int result = (int) CreateStudent.returnIntMethodWithRefParameterMethodInfo.Invoke(createStudent.student, args)!; - s = (string) args[0]!; - return result; + return CallReturnIntMethodWithRefParameter(createStudent.student, ref s); } void IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnVoidMethod() { - CreateStudent.returnVoidMethodMethodInfo.Invoke(student, new object?[] { }); + CallReturnVoidMethod(student); } int IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnIntMethod() { - return (int) CreateStudent.returnIntMethodMethodInfo.Invoke(student, new object?[] { })!; + return CallReturnIntMethod(student); } System.Collections.Generic.List IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnListMethod() { - return (System.Collections.Generic.List) CreateStudent.returnListMethodMethodInfo.Invoke(student, new object?[] { })!; + return CallReturnListMethod(student); } int IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnIntMethodWithRefParameter(ref string s) { - object?[] args = new object?[] { s }; - int result = (int) CreateStudent.returnIntMethodWithRefParameterMethodInfo.Invoke(student, args)!; - s = (string) args[0]!; - return result; + return CallReturnIntMethodWithRefParameter(student, ref s); } public interface ICreateStudent : IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter @@ -127,4 +84,16 @@ public class CreateStudent : int ReturnIntMethodWithRefParameter(ref string s); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnVoidMethod")] + private static extern void CallReturnVoidMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnIntMethod")] + private static extern int CallReturnIntMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnListMethod")] + private static extern System.Collections.Generic.List CallReturnListMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnIntMethodWithRefParameter")] + private static extern int CallReturnIntMethodWithRefParameter(Student student, ref string s); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/CreateStudent.g.cs index e3f1903..4912474 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnSingleStepPrivateMethodsClass/CreateStudent.g.cs @@ -6,8 +6,7 @@ #nullable enable using System.Collections.Generic; -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass; @@ -16,42 +15,6 @@ public class CreateStudent : CreateStudent.IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter { private readonly Student student; - private static readonly MethodInfo returnVoidMethodMethodInfo; - private static readonly MethodInfo returnIntMethodMethodInfo; - private static readonly MethodInfo returnListMethodMethodInfo; - private static readonly MethodInfo returnIntMethodWithRefParameterMethodInfo; - - static CreateStudent() - { - returnVoidMethodMethodInfo = typeof(Student).GetMethod( - "ReturnVoidMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnIntMethodMethodInfo = typeof(Student).GetMethod( - "ReturnIntMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnListMethodMethodInfo = typeof(Student).GetMethod( - "ReturnListMethod", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - returnIntMethodWithRefParameterMethodInfo = typeof(Student).GetMethod( - "ReturnIntMethodWithRefParameter", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string).MakeByRefType() }, - null)!; - } private CreateStudent() { @@ -66,51 +29,45 @@ public static ICreateStudent InitialStep() public static void ReturnVoidMethod() { CreateStudent createStudent = new CreateStudent(); - CreateStudent.returnVoidMethodMethodInfo.Invoke(createStudent.student, new object?[] { }); + CallReturnVoidMethod(createStudent.student); } public static int ReturnIntMethod() { CreateStudent createStudent = new CreateStudent(); - return (int) CreateStudent.returnIntMethodMethodInfo.Invoke(createStudent.student, new object?[] { })!; + return CallReturnIntMethod(createStudent.student); } public static System.Collections.Generic.List ReturnListMethod() { CreateStudent createStudent = new CreateStudent(); - return (System.Collections.Generic.List) CreateStudent.returnListMethodMethodInfo.Invoke(createStudent.student, new object?[] { })!; + return CallReturnListMethod(createStudent.student); } public static int ReturnIntMethodWithRefParameter(ref string s) { CreateStudent createStudent = new CreateStudent(); - object?[] args = new object?[] { s }; - int result = (int) CreateStudent.returnIntMethodWithRefParameterMethodInfo.Invoke(createStudent.student, args)!; - s = (string) args[0]!; - return result; + return CallReturnIntMethodWithRefParameter(createStudent.student, ref s); } void IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnVoidMethod() { - CreateStudent.returnVoidMethodMethodInfo.Invoke(student, new object?[] { }); + CallReturnVoidMethod(student); } int IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnIntMethod() { - return (int) CreateStudent.returnIntMethodMethodInfo.Invoke(student, new object?[] { })!; + return CallReturnIntMethod(student); } System.Collections.Generic.List IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnListMethod() { - return (System.Collections.Generic.List) CreateStudent.returnListMethodMethodInfo.Invoke(student, new object?[] { })!; + return CallReturnListMethod(student); } int IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter.ReturnIntMethodWithRefParameter(ref string s) { - object?[] args = new object?[] { s }; - int result = (int) CreateStudent.returnIntMethodWithRefParameterMethodInfo.Invoke(student, args)!; - s = (string) args[0]!; - return result; + return CallReturnIntMethodWithRefParameter(student, ref s); } public interface ICreateStudent : IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter @@ -127,4 +84,16 @@ public interface IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethod int ReturnIntMethodWithRefParameter(ref string s); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnVoidMethod")] + private static extern void CallReturnVoidMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnIntMethod")] + private static extern int CallReturnIntMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnListMethod")] + private static extern System.Collections.Generic.List CallReturnListMethod(Student student); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "ReturnIntMethodWithRefParameter")] + private static extern int CallReturnIntMethodWithRefParameter(Student student, ref string s); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.expected.txt index 1344659..830e205 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GetInitPropertyClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterPropertyInfo.SetValue(createStudent.student, semester); + SetSemester(createStudent.student, semester); return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -52,4 +46,7 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.g.cs index 1344659..830e205 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GetInitPropertyClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterPropertyInfo.SetValue(createStudent.student, semester); + SetSemester(createStudent.student, semester); return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -52,4 +46,7 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.expected.txt index 277ef96..ff0e8ee 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GetPrivateSetPropertyClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterPropertyInfo.SetValue(createStudent.student, semester); + SetSemester(createStudent.student, semester); return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -52,4 +46,7 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.g.cs index 277ef96..ff0e8ee 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GetPrivateSetPropertyClass; @@ -14,12 +14,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -34,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterPropertyInfo.SetValue(createStudent.student, semester); + SetSemester(createStudent.student, semester); return createStudent.student; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -52,4 +46,7 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreatePerson.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreatePerson.g.cs index 497753b..f4bd18d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreatePerson.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreatePerson.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassProtectedMembers; @@ -16,14 +16,6 @@ public class CreatePerson : CreatePerson.IBornOn { private readonly Person person; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - - static CreatePerson() - { - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.NonPublic)!; - dateOfBirthPropertyInfo = typeof(Person).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreatePerson() { @@ -38,19 +30,19 @@ public static ICreatePerson InitialStep() public static IBornOn WithName(string name) { CreatePerson createPerson = new CreatePerson(); - CreatePerson.namePropertyInfo.SetValue(createPerson.person, name); + SetName(createPerson.person, name); return createPerson; } IBornOn IWithName.WithName(string name) { - CreatePerson.namePropertyInfo.SetValue(person, name); + SetName(person, name); return this; } Person IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreatePerson.dateOfBirthPropertyInfo.SetValue(person, dateOfBirth); + SetDateOfBirth(person, dateOfBirth); return person; } @@ -67,4 +59,10 @@ public interface IBornOn { Person BornOn(System.DateOnly dateOfBirth); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Person person, System.DateOnly value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.expected.txt index 8c0fe13..48a3404 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.expected.txt @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassProtectedMembers; @@ -17,16 +17,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.NonPublic)!; - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.NonPublic)!; - dateOfBirthPropertyInfo = typeof(Person).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreateStudent() { @@ -41,25 +31,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.dateOfBirthPropertyInfo.SetValue(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -81,4 +71,13 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Person person, System.DateOnly value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.g.cs index 8c0fe13..48a3404 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassProtectedMembers; @@ -17,16 +17,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.NonPublic)!; - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.NonPublic)!; - dateOfBirthPropertyInfo = typeof(Person).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.NonPublic)!; - } private CreateStudent() { @@ -41,25 +31,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.dateOfBirthPropertyInfo.SetValue(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -81,4 +71,13 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Person person, System.DateOnly value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreatePerson.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreatePerson.g.cs index 6007df7..b9d0936 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreatePerson.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreatePerson.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassProtectedSetters; @@ -16,14 +16,6 @@ public class CreatePerson : CreatePerson.IBornOn { private readonly Person person; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - - static CreatePerson() - { - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - dateOfBirthPropertyInfo = typeof(Person).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.Public)!; - } private CreatePerson() { @@ -38,19 +30,19 @@ public static ICreatePerson InitialStep() public static IBornOn WithName(string name) { CreatePerson createPerson = new CreatePerson(); - CreatePerson.namePropertyInfo.SetValue(createPerson.person, name); + SetName(createPerson.person, name); return createPerson; } IBornOn IWithName.WithName(string name) { - CreatePerson.namePropertyInfo.SetValue(person, name); + SetName(person, name); return this; } Person IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreatePerson.dateOfBirthPropertyInfo.SetValue(person, dateOfBirth); + SetDateOfBirth(person, dateOfBirth); return person; } @@ -67,4 +59,10 @@ public interface IBornOn { Person BornOn(System.DateOnly dateOfBirth); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Person person, System.DateOnly value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.expected.txt index b938be3..ca8a93b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.expected.txt @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassProtectedSetters; @@ -17,16 +17,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - dateOfBirthPropertyInfo = typeof(Person).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -41,25 +31,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.dateOfBirthPropertyInfo.SetValue(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -81,4 +71,13 @@ public class CreateStudent : { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Person person, System.DateOnly value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.g.cs index b938be3..ca8a93b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.InheritedClassProtectedSetters; @@ -17,16 +17,6 @@ public class CreateStudent : CreateStudent.IInSemester { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo namePropertyInfo; - private static readonly PropertyInfo dateOfBirthPropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - namePropertyInfo = typeof(Person).GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)!; - dateOfBirthPropertyInfo = typeof(Person).GetProperty("DateOfBirth", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -41,25 +31,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + SetName(createStudent.student, name); return createStudent; } IBornOn IWithName.WithName(string name) { - CreateStudent.namePropertyInfo.SetValue(student, name); + SetName(student, name); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - CreateStudent.dateOfBirthPropertyInfo.SetValue(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth); return this; } Student IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return student; } @@ -81,4 +71,13 @@ public interface IInSemester { Student InSemester(int semester); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Name")] + private static extern void SetName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DateOfBirth")] + private static extern void SetDateOfBirth(Person person, System.DateOnly value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.expected.txt index afb62d7..f7cadf5 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.expected.txt @@ -6,7 +6,7 @@ #nullable enable using System.Collections.Generic; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.NullablePredicateAndCollectionClass; @@ -16,12 +16,6 @@ public class CreateStudent : CreateStudent.IWhoIsHappy { private readonly Student student; - private static readonly PropertyInfo isHappyPropertyInfo; - - static CreateStudent() - { - isHappyPropertyInfo = typeof(Student).GetProperty("IsHappy", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -100,19 +94,19 @@ public class CreateStudent : Student IWhoIsHappy.WhoIsHappy(bool? isHappy) { - CreateStudent.isHappyPropertyInfo.SetValue(student, isHappy); + SetIsHappy(student, isHappy); return student; } Student IWhoIsHappy.WhoIsSad() { - CreateStudent.isHappyPropertyInfo.SetValue(student, false); + SetIsHappy(student, false); return student; } Student IWhoIsHappy.WithUnknownMood() { - CreateStudent.isHappyPropertyInfo.SetValue(student, null); + SetIsHappy(student, null); return student; } @@ -141,4 +135,7 @@ public class CreateStudent : Student WithUnknownMood(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_IsHappy")] + private static extern void SetIsHappy(Student student, bool? value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.g.cs index afb62d7..f7cadf5 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.g.cs @@ -6,7 +6,7 @@ #nullable enable using System.Collections.Generic; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.NullablePredicateAndCollectionClass; @@ -16,12 +16,6 @@ public class CreateStudent : CreateStudent.IWhoIsHappy { private readonly Student student; - private static readonly PropertyInfo isHappyPropertyInfo; - - static CreateStudent() - { - isHappyPropertyInfo = typeof(Student).GetProperty("IsHappy", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -100,19 +94,19 @@ IWhoIsHappy IWhoseFriendsAre.WhoseFriendsAreUnknown() Student IWhoIsHappy.WhoIsHappy(bool? isHappy) { - CreateStudent.isHappyPropertyInfo.SetValue(student, isHappy); + SetIsHappy(student, isHappy); return student; } Student IWhoIsHappy.WhoIsSad() { - CreateStudent.isHappyPropertyInfo.SetValue(student, false); + SetIsHappy(student, false); return student; } Student IWhoIsHappy.WithUnknownMood() { - CreateStudent.isHappyPropertyInfo.SetValue(student, null); + SetIsHappy(student, null); return student; } @@ -141,4 +135,7 @@ public interface IWhoIsHappy Student WithUnknownMood(); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_IsHappy")] + private static extern void SetIsHappy(Student student, bool? value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/OverloadedMethodClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/OverloadedMethodClass/CreateStudent.expected.txt index 20f2429..dc271c9 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/OverloadedMethodClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/OverloadedMethodClass/CreateStudent.expected.txt @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.OverloadedMethodClass; @@ -15,26 +14,6 @@ public class CreateStudent : CreateStudent.INamedNamed { private readonly Student student; - private static readonly MethodInfo namedMethodInfo; - private static readonly MethodInfo namedMethodInfo2; - - static CreateStudent() - { - namedMethodInfo = typeof(Student).GetMethod( - "Named", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string), typeof(string) }, - null)!; - namedMethodInfo2 = typeof(Student).GetMethod( - "Named", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - } private CreateStudent() { @@ -49,26 +28,26 @@ public class CreateStudent : public static Student Named(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namedMethodInfo.Invoke(createStudent.student, new object?[] { firstName, lastName }); + CallNamed(createStudent.student, firstName, lastName); return createStudent.student; } public static Student Named(string lastName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namedMethodInfo2.Invoke(createStudent.student, new object?[] { lastName }); + CallNamed(createStudent.student, lastName); return createStudent.student; } Student INamedNamed.Named(string firstName, string lastName) { - CreateStudent.namedMethodInfo.Invoke(student, new object?[] { firstName, lastName }); + CallNamed(student, firstName, lastName); return student; } Student INamedNamed.Named(string lastName) { - CreateStudent.namedMethodInfo2.Invoke(student, new object?[] { lastName }); + CallNamed(student, lastName); return student; } @@ -82,4 +61,10 @@ public class CreateStudent : Student Named(string lastName); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Named")] + private static extern void CallNamed(Student student, string firstName, string lastName); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Named")] + private static extern void CallNamed(Student student, string lastName); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/OverloadedMethodClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/OverloadedMethodClass/CreateStudent.g.cs index 20f2429..dc271c9 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/OverloadedMethodClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/OverloadedMethodClass/CreateStudent.g.cs @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.OverloadedMethodClass; @@ -15,26 +14,6 @@ public class CreateStudent : CreateStudent.INamedNamed { private readonly Student student; - private static readonly MethodInfo namedMethodInfo; - private static readonly MethodInfo namedMethodInfo2; - - static CreateStudent() - { - namedMethodInfo = typeof(Student).GetMethod( - "Named", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string), typeof(string) }, - null)!; - namedMethodInfo2 = typeof(Student).GetMethod( - "Named", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - } private CreateStudent() { @@ -49,26 +28,26 @@ public static ICreateStudent InitialStep() public static Student Named(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namedMethodInfo.Invoke(createStudent.student, new object?[] { firstName, lastName }); + CallNamed(createStudent.student, firstName, lastName); return createStudent.student; } public static Student Named(string lastName) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.namedMethodInfo2.Invoke(createStudent.student, new object?[] { lastName }); + CallNamed(createStudent.student, lastName); return createStudent.student; } Student INamedNamed.Named(string firstName, string lastName) { - CreateStudent.namedMethodInfo.Invoke(student, new object?[] { firstName, lastName }); + CallNamed(student, firstName, lastName); return student; } Student INamedNamed.Named(string lastName) { - CreateStudent.namedMethodInfo2.Invoke(student, new object?[] { lastName }); + CallNamed(student, lastName); return student; } @@ -82,4 +61,10 @@ public interface INamedNamed Student Named(string lastName); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Named")] + private static extern void CallNamed(Student student, string firstName, string lastName); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Named")] + private static extern void CallNamed(Student student, string lastName); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.expected.txt index 80fadc2..546fc98 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.expected.txt @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.SameNameMemberClass; @@ -16,16 +16,6 @@ public class CreateStudent : CreateStudent.IWithName2 { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo initialPropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - initialPropertyInfo = typeof(Student).GetProperty("Initial", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Student).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -40,25 +30,25 @@ public class CreateStudent : public static IWithName InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterPropertyInfo.SetValue(createStudent.student, semester); + SetSemester(createStudent.student, semester); return createStudent; } IWithName IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return this; } IWithName2 IWithName.WithName(char initial) { - CreateStudent.initialPropertyInfo.SetValue(student, initial); + SetInitial(student, initial); return this; } Student IWithName2.WithName(string lastName) { - CreateStudent.lastNamePropertyInfo.SetValue(student, lastName); + SetLastName(student, lastName); return student; } @@ -80,4 +70,13 @@ public class CreateStudent : { Student WithName(string lastName); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Initial")] + private static extern void SetInitial(Student student, char value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.g.cs index 80fadc2..546fc98 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.g.cs @@ -5,7 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.SameNameMemberClass; @@ -16,16 +16,6 @@ public class CreateStudent : CreateStudent.IWithName2 { private readonly Student student; - private static readonly PropertyInfo semesterPropertyInfo; - private static readonly PropertyInfo initialPropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - - static CreateStudent() - { - semesterPropertyInfo = typeof(Student).GetProperty("Semester", BindingFlags.Instance | BindingFlags.Public)!; - initialPropertyInfo = typeof(Student).GetProperty("Initial", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Student).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - } private CreateStudent() { @@ -40,25 +30,25 @@ public static ICreateStudent InitialStep() public static IWithName InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - CreateStudent.semesterPropertyInfo.SetValue(createStudent.student, semester); + SetSemester(createStudent.student, semester); return createStudent; } IWithName IInSemester.InSemester(int semester) { - CreateStudent.semesterPropertyInfo.SetValue(student, semester); + SetSemester(student, semester); return this; } IWithName2 IWithName.WithName(char initial) { - CreateStudent.initialPropertyInfo.SetValue(student, initial); + SetInitial(student, initial); return this; } Student IWithName2.WithName(string lastName) { - CreateStudent.lastNamePropertyInfo.SetValue(student, lastName); + SetLastName(student, lastName); return student; } @@ -80,4 +70,13 @@ public interface IWithName2 { Student WithName(string lastName); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Semester")] + private static extern void SetSemester(Student student, int value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Initial")] + private static extern void SetInitial(Student student, char value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Student student, string value); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.expected.txt index f77cf4b..a53d530 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.expected.txt @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.PersonClass; @@ -22,72 +21,6 @@ public class CreatePerson : CreatePerson.ILivingInCity { private readonly Person person; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo middleNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - private static readonly MethodInfo whoseAddressIsUnknownMethodInfo; - private static readonly MethodInfo whoLivesAtAddressMethodInfo; - private static readonly MethodInfo withHouseNumberMethodInfo; - private static readonly MethodInfo withStreetMethodInfo; - private static readonly MethodInfo inCityMethodInfo; - private static readonly MethodInfo whoIsADigitalNomadMethodInfo; - private static readonly MethodInfo livingInCityMethodInfo; - - static CreatePerson() - { - firstNamePropertyInfo = typeof(Person).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - middleNamePropertyInfo = typeof(Person).GetProperty("MiddleName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Person).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - whoseAddressIsUnknownMethodInfo = typeof(Person).GetMethod( - "WhoseAddressIsUnknown", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - whoLivesAtAddressMethodInfo = typeof(Person).GetMethod( - "WhoLivesAtAddress", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - withHouseNumberMethodInfo = typeof(Person).GetMethod( - "WithHouseNumber", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - withStreetMethodInfo = typeof(Person).GetMethod( - "WithStreet", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - inCityMethodInfo = typeof(Person).GetMethod( - "InCity", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - whoIsADigitalNomadMethodInfo = typeof(Person).GetMethod( - "WhoIsADigitalNomad", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - livingInCityMethodInfo = typeof(Person).GetMethod( - "LivingInCity", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - } private CreatePerson() { @@ -102,67 +35,67 @@ public class CreatePerson : public static IWithMiddleName WithFirstName(string firstName) { CreatePerson createPerson = new CreatePerson(); - CreatePerson.firstNamePropertyInfo.SetValue(createPerson.person, firstName); + SetFirstName(createPerson.person, firstName); return createPerson; } IWithMiddleName IWithFirstName.WithFirstName(string firstName) { - CreatePerson.firstNamePropertyInfo.SetValue(person, firstName); + SetFirstName(person, firstName); return this; } IWithLastName IWithMiddleName.WithMiddleName(string? middleName) { - CreatePerson.middleNamePropertyInfo.SetValue(person, middleName); + SetMiddleName(person, middleName); return this; } IWhoseAddressIsUnknownWhoLivesAtAddressWhoIsADigitalNomad IWithLastName.WithLastName(string lastName) { - CreatePerson.lastNamePropertyInfo.SetValue(person, lastName); + SetLastName(person, lastName); return this; } Person IWhoseAddressIsUnknownWhoLivesAtAddressWhoIsADigitalNomad.WhoseAddressIsUnknown() { - CreatePerson.whoseAddressIsUnknownMethodInfo.Invoke(person, new object?[] { }); + CallWhoseAddressIsUnknown(person); return person; } IWithHouseNumber IWhoseAddressIsUnknownWhoLivesAtAddressWhoIsADigitalNomad.WhoLivesAtAddress() { - CreatePerson.whoLivesAtAddressMethodInfo.Invoke(person, new object?[] { }); + CallWhoLivesAtAddress(person); return this; } ILivingInCity IWhoseAddressIsUnknownWhoLivesAtAddressWhoIsADigitalNomad.WhoIsADigitalNomad() { - CreatePerson.whoIsADigitalNomadMethodInfo.Invoke(person, new object?[] { }); + CallWhoIsADigitalNomad(person); return this; } IWithStreet IWithHouseNumber.WithHouseNumber(string houseNumber) { - CreatePerson.withHouseNumberMethodInfo.Invoke(person, new object?[] { houseNumber }); + CallWithHouseNumber(person, houseNumber); return this; } IInCity IWithStreet.WithStreet(string street) { - CreatePerson.withStreetMethodInfo.Invoke(person, new object?[] { street }); + CallWithStreet(person, street); return this; } Person IInCity.InCity(string city) { - CreatePerson.inCityMethodInfo.Invoke(person, new object?[] { city }); + CallInCity(person, city); return person; } Person ILivingInCity.LivingInCity(string city) { - CreatePerson.livingInCityMethodInfo.Invoke(person, new object?[] { city }); + CallLivingInCity(person, city); return person; } @@ -213,4 +146,34 @@ public class CreatePerson : { Person LivingInCity(string city); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_MiddleName")] + private static extern void SetMiddleName(Person person, string? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WhoseAddressIsUnknown")] + private static extern void CallWhoseAddressIsUnknown(Person person); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WhoLivesAtAddress")] + private static extern void CallWhoLivesAtAddress(Person person); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithHouseNumber")] + private static extern void CallWithHouseNumber(Person person, string houseNumber); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithStreet")] + private static extern void CallWithStreet(Person person, string street); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "InCity")] + private static extern void CallInCity(Person person, string city); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WhoIsADigitalNomad")] + private static extern void CallWhoIsADigitalNomad(Person person); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "LivingInCity")] + private static extern void CallLivingInCity(Person person, string city); } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.g.cs index f77cf4b..a53d530 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.g.cs @@ -5,8 +5,7 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #nullable enable -using System; -using System.Reflection; +using System.Runtime.CompilerServices; namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.PersonClass; @@ -22,72 +21,6 @@ public class CreatePerson : CreatePerson.ILivingInCity { private readonly Person person; - private static readonly PropertyInfo firstNamePropertyInfo; - private static readonly PropertyInfo middleNamePropertyInfo; - private static readonly PropertyInfo lastNamePropertyInfo; - private static readonly MethodInfo whoseAddressIsUnknownMethodInfo; - private static readonly MethodInfo whoLivesAtAddressMethodInfo; - private static readonly MethodInfo withHouseNumberMethodInfo; - private static readonly MethodInfo withStreetMethodInfo; - private static readonly MethodInfo inCityMethodInfo; - private static readonly MethodInfo whoIsADigitalNomadMethodInfo; - private static readonly MethodInfo livingInCityMethodInfo; - - static CreatePerson() - { - firstNamePropertyInfo = typeof(Person).GetProperty("FirstName", BindingFlags.Instance | BindingFlags.Public)!; - middleNamePropertyInfo = typeof(Person).GetProperty("MiddleName", BindingFlags.Instance | BindingFlags.Public)!; - lastNamePropertyInfo = typeof(Person).GetProperty("LastName", BindingFlags.Instance | BindingFlags.Public)!; - whoseAddressIsUnknownMethodInfo = typeof(Person).GetMethod( - "WhoseAddressIsUnknown", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - whoLivesAtAddressMethodInfo = typeof(Person).GetMethod( - "WhoLivesAtAddress", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - withHouseNumberMethodInfo = typeof(Person).GetMethod( - "WithHouseNumber", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - withStreetMethodInfo = typeof(Person).GetMethod( - "WithStreet", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - inCityMethodInfo = typeof(Person).GetMethod( - "InCity", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - whoIsADigitalNomadMethodInfo = typeof(Person).GetMethod( - "WhoIsADigitalNomad", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { }, - null)!; - livingInCityMethodInfo = typeof(Person).GetMethod( - "LivingInCity", - 0, - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[] { typeof(string) }, - null)!; - } private CreatePerson() { @@ -102,67 +35,67 @@ public static ICreatePerson InitialStep() public static IWithMiddleName WithFirstName(string firstName) { CreatePerson createPerson = new CreatePerson(); - CreatePerson.firstNamePropertyInfo.SetValue(createPerson.person, firstName); + SetFirstName(createPerson.person, firstName); return createPerson; } IWithMiddleName IWithFirstName.WithFirstName(string firstName) { - CreatePerson.firstNamePropertyInfo.SetValue(person, firstName); + SetFirstName(person, firstName); return this; } IWithLastName IWithMiddleName.WithMiddleName(string? middleName) { - CreatePerson.middleNamePropertyInfo.SetValue(person, middleName); + SetMiddleName(person, middleName); return this; } IWhoseAddressIsUnknownWhoLivesAtAddressWhoIsADigitalNomad IWithLastName.WithLastName(string lastName) { - CreatePerson.lastNamePropertyInfo.SetValue(person, lastName); + SetLastName(person, lastName); return this; } Person IWhoseAddressIsUnknownWhoLivesAtAddressWhoIsADigitalNomad.WhoseAddressIsUnknown() { - CreatePerson.whoseAddressIsUnknownMethodInfo.Invoke(person, new object?[] { }); + CallWhoseAddressIsUnknown(person); return person; } IWithHouseNumber IWhoseAddressIsUnknownWhoLivesAtAddressWhoIsADigitalNomad.WhoLivesAtAddress() { - CreatePerson.whoLivesAtAddressMethodInfo.Invoke(person, new object?[] { }); + CallWhoLivesAtAddress(person); return this; } ILivingInCity IWhoseAddressIsUnknownWhoLivesAtAddressWhoIsADigitalNomad.WhoIsADigitalNomad() { - CreatePerson.whoIsADigitalNomadMethodInfo.Invoke(person, new object?[] { }); + CallWhoIsADigitalNomad(person); return this; } IWithStreet IWithHouseNumber.WithHouseNumber(string houseNumber) { - CreatePerson.withHouseNumberMethodInfo.Invoke(person, new object?[] { houseNumber }); + CallWithHouseNumber(person, houseNumber); return this; } IInCity IWithStreet.WithStreet(string street) { - CreatePerson.withStreetMethodInfo.Invoke(person, new object?[] { street }); + CallWithStreet(person, street); return this; } Person IInCity.InCity(string city) { - CreatePerson.inCityMethodInfo.Invoke(person, new object?[] { city }); + CallInCity(person, city); return person; } Person ILivingInCity.LivingInCity(string city) { - CreatePerson.livingInCityMethodInfo.Invoke(person, new object?[] { city }); + CallLivingInCity(person, city); return person; } @@ -213,4 +146,34 @@ public interface ILivingInCity { Person LivingInCity(string city); } + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_FirstName")] + private static extern void SetFirstName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_MiddleName")] + private static extern void SetMiddleName(Person person, string? value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_LastName")] + private static extern void SetLastName(Person person, string value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WhoseAddressIsUnknown")] + private static extern void CallWhoseAddressIsUnknown(Person person); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WhoLivesAtAddress")] + private static extern void CallWhoLivesAtAddress(Person person); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithHouseNumber")] + private static extern void CallWithHouseNumber(Person person, string houseNumber); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WithStreet")] + private static extern void CallWithStreet(Person person, string street); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "InCity")] + private static extern void CallInCity(Person person, string city); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "WhoIsADigitalNomad")] + private static extern void CallWhoIsADigitalNomad(Person person); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "LivingInCity")] + private static extern void CallLivingInCity(Person person, string city); } \ No newline at end of file From f8db8602a6959db118d23a9c5f4366fe941eba8e Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 11:12:55 +0100 Subject: [PATCH 59/67] test: GenericClassWithGenericMethods --- .../CreateStudent.expected.txt | 19 ++++++++++++++----- .../CreateStudent.g.cs | 19 ++++++++++++++----- .../GenericClassWithGenericMethods/Student.cs | 10 ++++++++++ .../UsageTests.cs | 19 ++++++++++++++++++- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/CreateStudent.expected.txt index adaf370..e99d10d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/CreateStudent.expected.txt @@ -18,7 +18,7 @@ public class CreateStudent : CreateStudent.IWithProperty5, CreateStudent.IMethod1, CreateStudent.IMethod2, - CreateStudent.IMethod3 + CreateStudent.IMethod3Method4 where T1 : class where T2 : class? where T3 : struct @@ -80,18 +80,23 @@ public class CreateStudent : return this; } - IMethod3 IMethod2.Method2(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) + IMethod3Method4 IMethod2.Method2(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) { student.Method2(p1, p2, p3, p4, p5, p6, p7, p8, p9); return this; } - Student IMethod3.Method3(T1 p1) + Student IMethod3Method4.Method3(T1 p1) { student.Method3(p1); return student; } + T6 IMethod3Method4.Method4(T6 p1, T7 p2) + { + return student.Method4(p1, p2); + } + public interface ICreateStudent : IWithProperty1 { } @@ -132,19 +137,23 @@ public class CreateStudent : public interface IMethod2 { - IMethod3 Method2(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) + IMethod3Method4 Method2(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) where T6 : unmanaged where T7 : System.Collections.Generic.List, System.Collections.Generic.IDictionary where T8 : class, System.Collections.Generic.IDictionary where T9 : System.Collections.Generic.List, new(); } - public interface IMethod3 + public interface IMethod3Method4 { Student Method3(T1 p1) where T6 : unmanaged where T7 : System.Collections.Generic.List, System.Collections.Generic.IDictionary where T8 : class, System.Collections.Generic.IDictionary where T9 : System.Collections.Generic.List, new(); + + T6 Method4(T6 p1, T7 p2) + where T6 : System.Collections.Generic.List + where T7 : System.Collections.Generic.List; } } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/CreateStudent.g.cs index adaf370..e99d10d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/CreateStudent.g.cs @@ -18,7 +18,7 @@ public class CreateStudent : CreateStudent.IWithProperty5, CreateStudent.IMethod1, CreateStudent.IMethod2, - CreateStudent.IMethod3 + CreateStudent.IMethod3Method4 where T1 : class where T2 : class? where T3 : struct @@ -80,18 +80,23 @@ IMethod2 IMethod1.Method1(T6 p1, T7 p2, T8 p3, T9 p4) return this; } - IMethod3 IMethod2.Method2(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) + IMethod3Method4 IMethod2.Method2(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) { student.Method2(p1, p2, p3, p4, p5, p6, p7, p8, p9); return this; } - Student IMethod3.Method3(T1 p1) + Student IMethod3Method4.Method3(T1 p1) { student.Method3(p1); return student; } + T6 IMethod3Method4.Method4(T6 p1, T7 p2) + { + return student.Method4(p1, p2); + } + public interface ICreateStudent : IWithProperty1 { } @@ -132,19 +137,23 @@ IMethod2 Method1(T6 p1, T7 p2, T8 p3, T9 p4) public interface IMethod2 { - IMethod3 Method2(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) + IMethod3Method4 Method2(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) where T6 : unmanaged where T7 : System.Collections.Generic.List, System.Collections.Generic.IDictionary where T8 : class, System.Collections.Generic.IDictionary where T9 : System.Collections.Generic.List, new(); } - public interface IMethod3 + public interface IMethod3Method4 { Student Method3(T1 p1) where T6 : unmanaged where T7 : System.Collections.Generic.List, System.Collections.Generic.IDictionary where T8 : class, System.Collections.Generic.IDictionary where T9 : System.Collections.Generic.List, new(); + + T6 Method4(T6 p1, T7 p2) + where T6 : System.Collections.Generic.List + where T7 : System.Collections.Generic.List; } } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/Student.cs index 271d9db..8c0d292 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/Student.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/Student.cs @@ -61,4 +61,14 @@ public void Method3(T1 p1) { Logs.Add("Called Method3"); } + + [FluentMethod(8)] + [FluentReturn] + public T6 Method4(T6 p1, T7 p2) + where T6: List + where T7 : List + { + Logs.Add("CalledMethod4"); + return p1; + } } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/UsageTests.cs index 01944f8..091d37c 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithGenericMethods/UsageTests.cs @@ -12,7 +12,7 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassWi public class UsageTests { [Fact, Priority(1)] - public void CanExecuteGenericClassWithGenericMethods() + public void CanExecuteGenericClassWithGenericMethodsTest1() { var student = CreateStudent .WithProperty1("property1") @@ -28,6 +28,23 @@ public void CanExecuteGenericClassWithGenericMethods() string[] expectedLogs = { "Called Method1", "Called Method2", "Called Method3" }; Assert.Equal(expectedLogs, student.Logs); } + + [Fact, Priority(1)] + public void CanExecuteGenericClassWithGenericMethodsTest2() + { + var result = CreateStudent + .WithProperty1("property1") + .WithProperty2(null) + .WithProperty3(0) + .WithProperty4(0) + .WithProperty5(0) + .Method1(0, new ListAndDictionary(), new Dictionary(), new List()) + .Method2("string1", null, 0, 0, 0, 0, new ListAndDictionary(), new Dictionary(), + new List()) + .Method4(new List { 1, 2, 3 }, new List() { 4, 5, 6 }); + + Assert.Equal([1, 2, 3], result); + } } #endif \ No newline at end of file From 7c5da66eb6c4f1eb6677f38a465055828a451462 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 11:17:33 +0100 Subject: [PATCH 60/67] fix: test method names --- .../InnerBodyGeneration/InnerBodyForMethodGenerator.cs | 1 - .../Abstract/CollectionNullableArrayClass/UsageTests.cs | 2 +- .../Abstract/ContinueWithAfterCompoundClass/UsageTests.cs | 2 +- .../ContinueWithOfOverloadedMethodClass/UsageTests.cs | 2 +- .../TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs | 4 +--- .../GenericClassWithPrivateGenericMethods/UsageTests.cs | 2 +- .../Abstract/GetPrivateInitPropertyClass/UsageTests.cs | 2 +- .../Abstract/PredicatePrivateFieldClass/UsageTests.cs | 2 +- .../Abstract/PrivateUnderscoreFieldClass/UsageTests.cs | 2 +- 9 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs index 780748f..8d0f947 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMethodGenerator.cs @@ -48,7 +48,6 @@ protected override void GenerateInnerBodyForPrivateSymbol(MethodSymbolInfo symbo // private static extern void CallWithName(Student student, string name); MethodSignature unsafeAccessorSignature = MethodSignature.Create(symbolInfo.ReturnType, callMethodName, null, true); - // todo: generic constraints handled correctly for generic return type? unsafeAccessorSignature.AddModifiers("private", "static", "extern"); // Student student diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/UsageTests.cs index a922ae3..4ea2e02 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/UsageTests.cs @@ -10,7 +10,7 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.CollectionNull public class UsageTests { [Fact, Priority(1)] - public void CanExecutePrivateReadonlyFieldClass() + public void CanExecuteCollectionNullableArrayClass() { var student = CreateStudent .WhoseFriendsAre("Alice", "Bob"); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/UsageTests.cs index b48a33f..05282c8 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/UsageTests.cs @@ -10,7 +10,7 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithAf public class UsageTests { [Fact, Priority(1)] - public void CanExecutePrivateReadonlyFieldClass() + public void CanExecuteContinueWithAfterCompoundClass() { var student = CreateStudent .WithName("Alice", "King") diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/UsageTests.cs index d28a232..c4a0431 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/UsageTests.cs @@ -10,7 +10,7 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.ContinueWithOf public class UsageTests { [Fact, Priority(1)] - public void CanExecutePrivateReadonlyFieldClass() + public void CanExecuteContinueWithOfOverloadedMethodClass() { var student = CreateStudent .Method1() diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs index 492f0aa..b83c692 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/UsageTests.cs @@ -23,6 +23,4 @@ public void CanExecuteContinueWithSelfClass() } } -#endif -// todo: check all usage tests. Some have the wrong method names. -// todo: all tests with UnsafeAccessor should have a usage test. \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/UsageTests.cs index 23f5fbc..dbec380 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GenericClassWithPrivateGenericMethods/UsageTests.cs @@ -12,7 +12,7 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GenericClassWi public class UsageTests { [Fact, Priority(1)] - public void CanExecuteGenericClassWithGenericMethods() + public void CanExecuteGenericClassWithPrivateGenericMethods() { var student = CreateStudent .WithProperty1("property1") diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/UsageTests.cs index 5a1da40..86ae672 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/UsageTests.cs @@ -10,7 +10,7 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.GetPrivateInit public class UsageTests { [Fact, Priority(1)] - public void CanExecutePrivateReadonlyFieldClass() + public void CanExecuteGetPrivateInitPropertyClass() { var student = CreateStudent .InSemester(4); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/UsageTests.cs index e3853db..7275539 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/UsageTests.cs @@ -11,7 +11,7 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PredicatePriva public class UsageTests { [Fact, Priority(1)] - public void CanExecutePrivateReadonlyFieldClass() + public void CanExecutePredicatePrivateFieldClass() { var student = CreateStudent .WhoIsHappy(); diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/UsageTests.cs index 9ac3c98..2cb51b1 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/UsageTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/UsageTests.cs @@ -11,7 +11,7 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateUndersc public class UsageTests { [Fact, Priority(1)] - public void CanExecutePrivateReadonlyFieldClass() + public void CanExecutePrivateUnderscoreFieldClass() { var student = CreateStudent .InSemester(4); From f179f884b7267a29dcc9c6d3b07e88a31af527aa Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 11:22:52 +0100 Subject: [PATCH 61/67] test: PrivateConstructorClassWithParams --- .../CreateStudent.expected.txt | 52 +++++++++++++++++++ .../CreateStudent.g.cs | 52 +++++++++++++++++++ .../Student.cs | 19 +++++++ .../UsageTests.cs | 23 ++++++++ .../CodeGeneration/TestDataProvider.cs | 1 + 5 files changed, 147 insertions(+) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/CreateStudent.expected.txt create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/CreateStudent.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/Student.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/UsageTests.cs diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/CreateStudent.expected.txt new file mode 100644 index 0000000..b7fe4ee --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/CreateStudent.expected.txt @@ -0,0 +1,52 @@ +// +// This code was generated by the library M31.FluentAPI. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#nullable enable + +using System.Runtime.CompilerServices; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateConstructorClassWithParams; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IInSemester +{ + private readonly Student student; + + private CreateStudent() + { + student = CreateStudentInstance(default!); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static Student InSemester(int semester) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Semester = semester; + return createStudent.student; + } + + Student IInSemester.InSemester(int semester) + { + student.Semester = semester; + return student; + } + + public interface ICreateStudent : IInSemester + { + } + + public interface IInSemester + { + Student InSemester(int semester); + } + + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] + private static extern Student CreateStudentInstance(params string[] hobbies); +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/CreateStudent.g.cs new file mode 100644 index 0000000..b7fe4ee --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/CreateStudent.g.cs @@ -0,0 +1,52 @@ +// +// This code was generated by the library M31.FluentAPI. +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#nullable enable + +using System.Runtime.CompilerServices; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateConstructorClassWithParams; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IInSemester +{ + private readonly Student student; + + private CreateStudent() + { + student = CreateStudentInstance(default!); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static Student InSemester(int semester) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Semester = semester; + return createStudent.student; + } + + Student IInSemester.InSemester(int semester) + { + student.Semester = semester; + return student; + } + + public interface ICreateStudent : IInSemester + { + } + + public interface IInSemester + { + Student InSemester(int semester); + } + + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] + private static extern Student CreateStudentInstance(params string[] hobbies); +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/Student.cs new file mode 100644 index 0000000..ff7e675 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/Student.cs @@ -0,0 +1,19 @@ +// ReSharper disable All + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateConstructorClassWithParams; + +[FluentApi] +public class Student +{ + private Student(params string[] hobbies) + { + Hobbies = hobbies; + } + + [FluentMember(0, "InSemester")] + public int Semester { get; set; } + + public string[] Hobbies { get; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/UsageTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/UsageTests.cs new file mode 100644 index 0000000..c8ea980 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateConstructorClassWithParams/UsageTests.cs @@ -0,0 +1,23 @@ +#if TEST_GENERATED_CODE + +// ReSharper disable NotAccessedVariable + +using Xunit; +using Xunit.Priority; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.PrivateConstructorClassWithParams; + +public class UsageTests +{ + [Fact, Priority(1)] + public void CanExecutePrivateConstructorClass() + { + Student student = CreateStudent + .InSemester(2); + + Assert.Equal(2, student.Semester); + Assert.Null(student.Hobbies); + } +} + +#endif \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs index 26ccb97..300775c 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -83,6 +83,7 @@ internal class TestDataProvider : IEnumerable ["Abstract", "PredicateClass", "Student"], ["Abstract", "PredicatePrivateFieldClass", "Student"], ["Abstract", "PrivateConstructorClass", "Student"], + ["Abstract", "PrivateConstructorClassWithParams", "Student"], ["Abstract", "PrivateFieldClass", "Student"], ["Abstract", "PrivateFluentMethodClass", "Student"], ["Abstract", "PrivateFluentMethodNullableParameterClass", "Student"], From e1b3116483c26c49b8a4ca05af234b660f6cbd0a Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 11:23:05 +0100 Subject: [PATCH 62/67] fix: remove todo --- .../CodeGeneration/CodeBoardActors/ConstructorGenerator.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs index 4fc5c16..d4979a2 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/ConstructorGenerator.cs @@ -109,8 +109,6 @@ private static string CreateArgument( return $"in {variableName}"; } - // todo: test params. - return "default!"; } From c304af9cde5c3196496a125f3ce669e9351acd80 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 11:29:00 +0100 Subject: [PATCH 63/67] fix: exlamation mark in set methods --- .../InnerBodyForMemberGenerator.cs | 4 +- .../CreateStudent.expected.txt | 12 +-- .../CreateStudent.g.cs | 12 +-- .../CreateStudent.expected.txt | 12 +-- .../CreateStudent.g.cs | 12 +-- .../CreateStudent.expected.txt | 4 +- .../CreateStudent.g.cs | 4 +- .../CreateStudent.expected.txt | 8 +- .../ContinueWithSelfClass/CreateStudent.g.cs | 8 +- .../CreateStudent.expected.txt | 2 +- .../CommentedMethodsClass/CreateStudent.g.cs | 2 +- .../CreateStudent.expected.txt | 6 +- .../CreateStudent.g.cs | 6 +- .../CreateStudent.expected.txt | 80 +++++++++---------- .../CreateStudent.g.cs | 80 +++++++++---------- .../CreateStudent.expected.txt | 8 +- .../CreateStudent.g.cs | 8 +- .../CreateStudent.expected.txt | 4 +- .../CreateStudent.g.cs | 4 +- .../CreateStudent.expected.txt | 4 +- .../CreateStudent.g.cs | 4 +- .../CreateStudent.expected.txt | 4 +- .../GetInitPropertyClass/CreateStudent.g.cs | 4 +- .../CreateStudent.expected.txt | 4 +- .../CreateStudent.g.cs | 4 +- .../CreateStudent.expected.txt | 4 +- .../CreateStudent.g.cs | 4 +- .../CreatePerson.g.cs | 6 +- .../CreateStudent.expected.txt | 8 +- .../CreateStudent.g.cs | 8 +- .../CreatePerson.g.cs | 6 +- .../CreateStudent.expected.txt | 8 +- .../CreateStudent.g.cs | 8 +- .../CreatePerson.g.cs | 6 +- .../CreateStudent.expected.txt | 8 +- .../CreateStudent.g.cs | 8 +- .../InheritedRecord/CreatePerson.g.cs | 6 +- .../CreateStudent.expected.txt | 8 +- .../InheritedRecord/CreateStudent.g.cs | 8 +- .../CreateStudent.expected.txt | 6 +- .../CreateStudent.g.cs | 6 +- .../PartialClass/CreateStudent.expected.txt | 6 +- .../Abstract/PartialClass/CreateStudent.g.cs | 6 +- .../CreateStudent.expected.txt | 8 +- .../CreateStudent.g.cs | 8 +- .../CreateStudent.expected.txt | 4 +- .../PrivateFieldClass/CreateStudent.g.cs | 4 +- .../CreateStudent.expected.txt | 4 +- .../CreateStudent.g.cs | 4 +- .../CreateStudent.expected.txt | 4 +- .../CreateStudent.g.cs | 4 +- .../CreateStudent.expected.txt | 4 +- .../CreateStudent.g.cs | 4 +- .../CreateStudent.expected.txt | 8 +- .../SameNameMemberClass/CreateStudent.g.cs | 8 +- .../CreateStudent.expected.txt | 8 +- .../CreateStudent.g.cs | 8 +- .../CreateStudent.expected.txt | 8 +- .../CreateStudent.g.cs | 8 +- .../CreateDocumentedStudent.expected.txt | 30 +++---- .../CreateDocumentedStudent.g.cs | 30 +++---- .../PersonClass/CreatePerson.expected.txt | 8 +- .../TestClasses/PersonClass/CreatePerson.g.cs | 8 +- .../StudentClass/CreateStudent.expected.txt | 30 +++---- .../StudentClass/CreateStudent.g.cs | 30 +++---- 65 files changed, 326 insertions(+), 326 deletions(-) diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs index bfb9c35..26df7c7 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/InnerBodyGeneration/InnerBodyForMemberGenerator.cs @@ -59,7 +59,7 @@ private void GenerateInnerBodyForPrivateProperty(MemberSymbolInfo symbolInfo) // SetName(createStudent.student, name); SetMemberCode setMemberCode = new SetMemberCode((instancePrefix, value) => - $"{setMethodName}({instancePrefix}{CodeBoard.Info.ClassInstanceName}, {value});"); + $"{setMethodName}({instancePrefix}{CodeBoard.Info.ClassInstanceName}, {value}!);"); CodeBoard.InnerBodyCreationDelegates.AssignSetMemberCode(symbolInfo.Name, setMemberCode); } @@ -84,7 +84,7 @@ private void GenerateInnerBodyForPrivateField(MemberSymbolInfo symbolInfo) // SemesterField(createStudent.student) = semester; SetMemberCode setMemberCode = new SetMemberCode((instancePrefix, value) => - $"{getFieldName}({instancePrefix}{CodeBoard.Info.ClassInstanceName}) = {value};"); + $"{getFieldName}({instancePrefix}{CodeBoard.Info.ClassInstanceName}) = {value}!;"); CodeBoard.InnerBodyCreationDelegates.AssignSetMemberCode(symbolInfo.Name, setMemberCode); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.expected.txt index 3767ae1..e57ff99 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.expected.txt @@ -28,39 +28,39 @@ public class CreateStudent : public static Student WhoseFriendsAre(params string[]? friends) { CreateStudent createStudent = new CreateStudent(); - SetFriends(createStudent.student, friends); + SetFriends(createStudent.student, friends!); return createStudent.student; } public static Student WhoseFriendIs(string friend) { CreateStudent createStudent = new CreateStudent(); - SetFriends(createStudent.student, new string[1]{ friend }); + SetFriends(createStudent.student, new string[1]{ friend }!); return createStudent.student; } public static Student WhoHasNoFriends() { CreateStudent createStudent = new CreateStudent(); - SetFriends(createStudent.student, new string[0]); + SetFriends(createStudent.student, new string[0]!); return createStudent.student; } Student IWhoseFriendsAre.WhoseFriendsAre(params string[]? friends) { - SetFriends(student, friends); + SetFriends(student, friends!); return student; } Student IWhoseFriendsAre.WhoseFriendIs(string friend) { - SetFriends(student, new string[1]{ friend }); + SetFriends(student, new string[1]{ friend }!); return student; } Student IWhoseFriendsAre.WhoHasNoFriends() { - SetFriends(student, new string[0]); + SetFriends(student, new string[0]!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.g.cs index 3767ae1..e57ff99 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/CollectionNullableArrayClass/CreateStudent.g.cs @@ -28,39 +28,39 @@ public static ICreateStudent InitialStep() public static Student WhoseFriendsAre(params string[]? friends) { CreateStudent createStudent = new CreateStudent(); - SetFriends(createStudent.student, friends); + SetFriends(createStudent.student, friends!); return createStudent.student; } public static Student WhoseFriendIs(string friend) { CreateStudent createStudent = new CreateStudent(); - SetFriends(createStudent.student, new string[1]{ friend }); + SetFriends(createStudent.student, new string[1]{ friend }!); return createStudent.student; } public static Student WhoHasNoFriends() { CreateStudent createStudent = new CreateStudent(); - SetFriends(createStudent.student, new string[0]); + SetFriends(createStudent.student, new string[0]!); return createStudent.student; } Student IWhoseFriendsAre.WhoseFriendsAre(params string[]? friends) { - SetFriends(student, friends); + SetFriends(student, friends!); return student; } Student IWhoseFriendsAre.WhoseFriendIs(string friend) { - SetFriends(student, new string[1]{ friend }); + SetFriends(student, new string[1]{ friend }!); return student; } Student IWhoseFriendsAre.WhoHasNoFriends() { - SetFriends(student, new string[0]); + SetFriends(student, new string[0]!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.expected.txt index 9b4a920..5712ee7 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.expected.txt @@ -30,27 +30,27 @@ public class CreateStudent : public static IWithProperty2 WithName(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - SetFirstName(createStudent.student, firstName); - SetLastName(createStudent.student, lastName); + SetFirstName(createStudent.student, firstName!); + SetLastName(createStudent.student, lastName!); return createStudent; } IWithProperty2 IWithName.WithName(string firstName, string lastName) { - SetFirstName(student, firstName); - SetLastName(student, lastName); + SetFirstName(student, firstName!); + SetLastName(student, lastName!); return this; } IWithProperty2 IWithProperty1.WithProperty1(string property1) { - SetProperty1(student, property1); + SetProperty1(student, property1!); return this; } Student IWithProperty2.WithProperty2(string property2) { - SetProperty2(student, property2); + SetProperty2(student, property2!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.g.cs index 9b4a920..5712ee7 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithAfterCompoundClass/CreateStudent.g.cs @@ -30,27 +30,27 @@ public static ICreateStudent InitialStep() public static IWithProperty2 WithName(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - SetFirstName(createStudent.student, firstName); - SetLastName(createStudent.student, lastName); + SetFirstName(createStudent.student, firstName!); + SetLastName(createStudent.student, lastName!); return createStudent; } IWithProperty2 IWithName.WithName(string firstName, string lastName) { - SetFirstName(student, firstName); - SetLastName(student, lastName); + SetFirstName(student, firstName!); + SetLastName(student, lastName!); return this; } IWithProperty2 IWithProperty1.WithProperty1(string property1) { - SetProperty1(student, property1); + SetProperty1(student, property1!); return this; } Student IWithProperty2.WithProperty2(string property2) { - SetProperty2(student, property2); + SetProperty2(student, property2!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.expected.txt index 7f74f1d..ea2b90d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.expected.txt @@ -55,13 +55,13 @@ public class CreateStudent : IWithProperty2 IWithProperty1.WithProperty1(string property1) { - SetProperty1(student, property1); + SetProperty1(student, property1!); return this; } Student IWithProperty2.WithProperty2(string property2) { - SetProperty2(student, property2); + SetProperty2(student, property2!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.g.cs index 7f74f1d..ea2b90d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithOfOverloadedMethodClass/CreateStudent.g.cs @@ -55,13 +55,13 @@ IWithProperty2 IMethod1Method1.Method1(int p1) IWithProperty2 IWithProperty1.WithProperty1(string property1) { - SetProperty1(student, property1); + SetProperty1(student, property1!); return this; } Student IWithProperty2.WithProperty2(string property2) { - SetProperty2(student, property2); + SetProperty2(student, property2!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.expected.txt index fb2be7e..83119a9 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.expected.txt @@ -29,25 +29,25 @@ public class CreateStudent : public static IWithMiddleNameWithLastName WithFirstName(string firstName) { CreateStudent createStudent = new CreateStudent(); - SetFirstName(createStudent.student, firstName); + SetFirstName(createStudent.student, firstName!); return createStudent; } IWithMiddleNameWithLastName IWithFirstName.WithFirstName(string firstName) { - SetFirstName(student, firstName); + SetFirstName(student, firstName!); return this; } IWithMiddleNameWithLastName IWithMiddleNameWithLastName.WithMiddleName(string? middleName) { - SetMiddleName(student, middleName); + SetMiddleName(student, middleName!); return this; } Student IWithMiddleNameWithLastName.WithLastName(string lastName) { - SetLastName(student, lastName); + SetLastName(student, lastName!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.g.cs index fb2be7e..83119a9 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ContinueWithSelfClass/CreateStudent.g.cs @@ -29,25 +29,25 @@ public static ICreateStudent InitialStep() public static IWithMiddleNameWithLastName WithFirstName(string firstName) { CreateStudent createStudent = new CreateStudent(); - SetFirstName(createStudent.student, firstName); + SetFirstName(createStudent.student, firstName!); return createStudent; } IWithMiddleNameWithLastName IWithFirstName.WithFirstName(string firstName) { - SetFirstName(student, firstName); + SetFirstName(student, firstName!); return this; } IWithMiddleNameWithLastName IWithMiddleNameWithLastName.WithMiddleName(string? middleName) { - SetMiddleName(student, middleName); + SetMiddleName(student, middleName!); return this; } Student IWithMiddleNameWithLastName.WithLastName(string lastName) { - SetLastName(student, lastName); + SetLastName(student, lastName!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.expected.txt index 9d94507..5b9e9e9 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.expected.txt @@ -46,7 +46,7 @@ public class CreateStudent : Student IOfAgeBornOn.OfAge(int age) { - SetAge(student, age); + SetAge(student, age!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.g.cs index 9d94507..5b9e9e9 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedMethodsClass/CreateStudent.g.cs @@ -46,7 +46,7 @@ IOfAgeBornOn IWithName.WithName(string firstName, string lastName) Student IOfAgeBornOn.OfAge(int age) { - SetAge(student, age); + SetAge(student, age!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.expected.txt index 7adb809..d1c54f6 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.expected.txt @@ -70,19 +70,19 @@ public class CreateStudent : Student IWhoIsHappy.WhoIsHappy(bool? isHappy) { - SetIsHappy(student, isHappy); + SetIsHappy(student, isHappy!); return student; } Student IWhoIsHappy.WhoIsSad() { - SetIsHappy(student, false); + SetIsHappy(student, false!); return student; } Student IWhoIsHappy.WithUnknownMood() { - SetIsHappy(student, null); + SetIsHappy(student, null!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.g.cs index 7adb809..d1c54f6 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentApiComments/CommentedPropertiesClassAdvanced/CreateStudent.g.cs @@ -70,19 +70,19 @@ IWhoIsHappy ILivingIn.InUnknownCity() Student IWhoIsHappy.WhoIsHappy(bool? isHappy) { - SetIsHappy(student, isHappy); + SetIsHappy(student, isHappy!); return student; } Student IWhoIsHappy.WhoIsSad() { - SetIsHappy(student, false); + SetIsHappy(student, false!); return student; } Student IWhoIsHappy.WithUnknownMood() { - SetIsHappy(student, null); + SetIsHappy(student, null!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.expected.txt index a396331..dab796b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.expected.txt @@ -32,241 +32,241 @@ public class CreateStudent : public static IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(System.Collections.Generic.List addressesA) { - SetAddressesA(student, addressesA); + SetAddressesA(student, addressesA!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesA) { - SetAddressesA(student, new List(addressesA)); + SetAddressesA(student, new List(addressesA)!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params Func[] createAddressesA) { - SetAddressesA(student, new List(createAddressesA.Select(createAddressA => createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); + SetAddressesA(student, new List(createAddressesA.Select(createAddressA => createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressA) { - SetAddressesA(student, new List(1){ addressA }); + SetAddressesA(student, new List(1){ addressA }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(Func createAddressA) { - SetAddressesA(student, new List(1){ createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesA(student, new List(1){ createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesA() { - SetAddressesA(student, new List(0)); + SetAddressesA(student, new List(0)!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB) { - SetAddressesB(student, addressesB); + SetAddressesB(student, addressesB!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesB) { - SetAddressesB(student, addressesB); + SetAddressesB(student, addressesB!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params Func[] createAddressesB) { - SetAddressesB(student, createAddressesB.Select(createAddressB => createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesB(student, createAddressesB.Select(createAddressB => createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressB) { - SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressB }); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressB }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(Func createAddressB) { - SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesB() { - SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesC) { - SetAddressesC(student, addressesC); + SetAddressesC(student, addressesC!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params Func[] createAddressesC) { - SetAddressesC(student, createAddressesC.Select(createAddressC => createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesC(student, createAddressesC.Select(createAddressC => createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressC) { - SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressC }); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressC }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(Func createAddressC) { - SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesC() { - SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(System.Collections.Generic.HashSet addressesD) { - SetAddressesD(student, addressesD); + SetAddressesD(student, addressesD!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesD) { - SetAddressesD(student, new HashSet(addressesD)); + SetAddressesD(student, new HashSet(addressesD)!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params Func[] createAddressesD) { - SetAddressesD(student, new HashSet(createAddressesD.Select(createAddressD => createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); + SetAddressesD(student, new HashSet(createAddressesD.Select(createAddressD => createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressD) { - SetAddressesD(student, new HashSet(1){ addressD }); + SetAddressesD(student, new HashSet(1){ addressD }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(Func createAddressD) { - SetAddressesD(student, new HashSet(1){ createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesD(student, new HashSet(1){ createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesD() { - SetAddressesD(student, new HashSet(0)); + SetAddressesD(student, new HashSet(0)!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[]? addressesE) { - SetAddressesE(student, addressesE); + SetAddressesE(student, addressesE!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params Func[]? createAddressesE) { - SetAddressesE(student, createAddressesE?.Select(createAddressE => createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesE(student, createAddressesE?.Select(createAddressE => createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressE) { - SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressE }); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressE }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(Func createAddressE) { - SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesE() { - SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[] addressesF) { - SetAddressesF(student, addressesF); + SetAddressesF(student, addressesF!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params Func[] createAddressesF) { - SetAddressesF(student, createAddressesF.Select(createAddressF => createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesF(student, createAddressesF.Select(createAddressF => createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressF) { - SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressF }); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressF }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(Func createAddressF) { - SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesF() { - SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[]? addressesG) { - SetAddressesG(student, addressesG); + SetAddressesG(student, addressesG!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params Func[]? createAddressesG) { - SetAddressesG(student, createAddressesG?.Select(createAddressG => createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesG(student, createAddressesG?.Select(createAddressG => createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressG) { - SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressG }); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressG }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(Func createAddressG) { - SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesG() { - SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.g.cs index a396331..dab796b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.g.cs @@ -32,241 +32,241 @@ public static ICreateStudent InitialStep() public static IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(System.Collections.Generic.List addressesA) { - SetAddressesA(student, addressesA); + SetAddressesA(student, addressesA!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesA) { - SetAddressesA(student, new List(addressesA)); + SetAddressesA(student, new List(addressesA)!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params Func[] createAddressesA) { - SetAddressesA(student, new List(createAddressesA.Select(createAddressA => createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); + SetAddressesA(student, new List(createAddressesA.Select(createAddressA => createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressA) { - SetAddressesA(student, new List(1){ addressA }); + SetAddressesA(student, new List(1){ addressA }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(Func createAddressA) { - SetAddressesA(student, new List(1){ createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesA(student, new List(1){ createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesA() { - SetAddressesA(student, new List(0)); + SetAddressesA(student, new List(0)!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB) { - SetAddressesB(student, addressesB); + SetAddressesB(student, addressesB!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesB) { - SetAddressesB(student, addressesB); + SetAddressesB(student, addressesB!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params Func[] createAddressesB) { - SetAddressesB(student, createAddressesB.Select(createAddressB => createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesB(student, createAddressesB.Select(createAddressB => createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressB) { - SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressB }); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressB }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(Func createAddressB) { - SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesB() { - SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesB(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesC) { - SetAddressesC(student, addressesC); + SetAddressesC(student, addressesC!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params Func[] createAddressesC) { - SetAddressesC(student, createAddressesC.Select(createAddressC => createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesC(student, createAddressesC.Select(createAddressC => createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressC) { - SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressC }); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressC }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(Func createAddressC) { - SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesC() { - SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesC(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(System.Collections.Generic.HashSet addressesD) { - SetAddressesD(student, addressesD); + SetAddressesD(student, addressesD!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesD) { - SetAddressesD(student, new HashSet(addressesD)); + SetAddressesD(student, new HashSet(addressesD)!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params Func[] createAddressesD) { - SetAddressesD(student, new HashSet(createAddressesD.Select(createAddressD => createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))); + SetAddressesD(student, new HashSet(createAddressesD.Select(createAddressD => createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())))!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressD) { - SetAddressesD(student, new HashSet(1){ addressD }); + SetAddressesD(student, new HashSet(1){ addressD }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(Func createAddressD) { - SetAddressesD(student, new HashSet(1){ createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesD(student, new HashSet(1){ createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesD() { - SetAddressesD(student, new HashSet(0)); + SetAddressesD(student, new HashSet(0)!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[]? addressesE) { - SetAddressesE(student, addressesE); + SetAddressesE(student, addressesE!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params Func[]? createAddressesE) { - SetAddressesE(student, createAddressesE?.Select(createAddressE => createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesE(student, createAddressesE?.Select(createAddressE => createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressE) { - SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressE }); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ addressE }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(Func createAddressE) { - SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[1]{ createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesE() { - SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]); + SetAddressesE(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[0]!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[] addressesF) { - SetAddressesF(student, addressesF); + SetAddressesF(student, addressesF!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params Func[] createAddressesF) { - SetAddressesF(student, createAddressesF.Select(createAddressF => createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesF(student, createAddressesF.Select(createAddressF => createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressF) { - SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressF }); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressF }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(Func createAddressF) { - SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesF() { - SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); + SetAddressesF(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[]? addressesG) { - SetAddressesG(student, addressesG); + SetAddressesG(student, addressesG!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params Func[]? createAddressesG) { - SetAddressesG(student, createAddressesG?.Select(createAddressG => createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()); + SetAddressesG(student, createAddressesG?.Select(createAddressG => createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep())).ToArray()!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressG) { - SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressG }); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ addressG }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(Func createAddressG) { - SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[1]{ createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.CreateAddress.InitialStep()) }!); return student; } Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesG() { - SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); + SetAddressesG(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.expected.txt index b8da3a6..c576631 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.expected.txt @@ -28,26 +28,26 @@ public class CreateStudent : public static Student WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent.student; } public static Student WhoseNameIsUnknown() { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, null); + SetName(createStudent.student, null!); return createStudent.student; } Student IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return student; } Student IWithName.WhoseNameIsUnknown() { - SetName(student, null); + SetName(student, null!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.g.cs index b8da3a6..c576631 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentNullableNoNullableAnnotationPrivateSetClass/CreateStudent.g.cs @@ -28,26 +28,26 @@ public static ICreateStudent InitialStep() public static Student WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent.student; } public static Student WhoseNameIsUnknown() { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, null); + SetName(createStudent.student, null!); return createStudent.student; } Student IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return student; } Student IWithName.WhoseNameIsUnknown() { - SetName(student, null); + SetName(student, null!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.expected.txt index 3ab8d2b..1fd7cb2 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.expected.txt @@ -30,13 +30,13 @@ public class CreateStudent : public static IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.g.cs index 3ab8d2b..1fd7cb2 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepClass/CreateStudent.g.cs @@ -30,13 +30,13 @@ public static ICreateStudent InitialStep() public static IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.expected.txt index cdc9552..4052d76 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.expected.txt @@ -30,13 +30,13 @@ public class CreateStudent : public static IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.g.cs index cdc9552..4052d76 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentReturnMultiStepPrivateMethodsClass/CreateStudent.g.cs @@ -30,13 +30,13 @@ public static ICreateStudent InitialStep() public static IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IReturnVoidMethodReturnIntMethodReturnListMethodReturnIntMethodWithRefParameter IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.expected.txt index 830e205..c7f94ba 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.expected.txt @@ -28,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SetSemester(createStudent.student, semester); + SetSemester(createStudent.student, semester!); return createStudent.student; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.g.cs index 830e205..c7f94ba 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetInitPropertyClass/CreateStudent.g.cs @@ -28,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SetSemester(createStudent.student, semester); + SetSemester(createStudent.student, semester!); return createStudent.student; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.expected.txt index c91ee68..7d7820a 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.expected.txt @@ -28,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SetSemester(createStudent.student, semester); + SetSemester(createStudent.student, semester!); return createStudent.student; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.g.cs index c91ee68..7d7820a 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateInitPropertyClass/CreateStudent.g.cs @@ -28,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SetSemester(createStudent.student, semester); + SetSemester(createStudent.student, semester!); return createStudent.student; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.expected.txt index ff0e8ee..5974eb5 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.expected.txt @@ -28,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SetSemester(createStudent.student, semester); + SetSemester(createStudent.student, semester!); return createStudent.student; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.g.cs index ff0e8ee..5974eb5 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/GetPrivateSetPropertyClass/CreateStudent.g.cs @@ -28,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SetSemester(createStudent.student, semester); + SetSemester(createStudent.student, semester!); return createStudent.student; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreatePerson.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreatePerson.g.cs index 2b24c56..3e4d042 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreatePerson.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreatePerson.g.cs @@ -30,19 +30,19 @@ public static ICreatePerson InitialStep() public static IOfAgeBornOn WithName(string name) { CreatePerson createPerson = new CreatePerson(); - SetName(createPerson.person, name); + SetName(createPerson.person, name!); return createPerson; } IOfAgeBornOn IWithName.WithName(string name) { - SetName(person, name); + SetName(person, name!); return this; } Person IOfAgeBornOn.OfAge(int age) { - SetAge(person, age); + SetAge(person, age!); return person; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.expected.txt index 4224acc..119b64a 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.expected.txt @@ -31,19 +31,19 @@ public class CreateStudent : public static IOfAgeBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IOfAgeBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IOfAgeBornOn.OfAge(int age) { - SetAge(student, age); + SetAge(student, age!); return this; } @@ -55,7 +55,7 @@ public class CreateStudent : Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.g.cs index 4224acc..119b64a 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassPrivateSetters/CreateStudent.g.cs @@ -31,19 +31,19 @@ public static ICreateStudent InitialStep() public static IOfAgeBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IOfAgeBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IOfAgeBornOn.OfAge(int age) { - SetAge(student, age); + SetAge(student, age!); return this; } @@ -55,7 +55,7 @@ IInSemester IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreatePerson.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreatePerson.g.cs index f4bd18d..01716ab 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreatePerson.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreatePerson.g.cs @@ -30,19 +30,19 @@ public static ICreatePerson InitialStep() public static IBornOn WithName(string name) { CreatePerson createPerson = new CreatePerson(); - SetName(createPerson.person, name); + SetName(createPerson.person, name!); return createPerson; } IBornOn IWithName.WithName(string name) { - SetName(person, name); + SetName(person, name!); return this; } Person IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(person, dateOfBirth); + SetDateOfBirth(person, dateOfBirth!); return person; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.expected.txt index 48a3404..1054b46 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.expected.txt @@ -31,25 +31,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth!); return this; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.g.cs index 48a3404..1054b46 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedMembers/CreateStudent.g.cs @@ -31,25 +31,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth!); return this; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreatePerson.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreatePerson.g.cs index b9d0936..365059a 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreatePerson.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreatePerson.g.cs @@ -30,19 +30,19 @@ public static ICreatePerson InitialStep() public static IBornOn WithName(string name) { CreatePerson createPerson = new CreatePerson(); - SetName(createPerson.person, name); + SetName(createPerson.person, name!); return createPerson; } IBornOn IWithName.WithName(string name) { - SetName(person, name); + SetName(person, name!); return this; } Person IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(person, dateOfBirth); + SetDateOfBirth(person, dateOfBirth!); return person; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.expected.txt index ca8a93b..5f84e0f 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.expected.txt @@ -31,25 +31,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth!); return this; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.g.cs index ca8a93b..5f84e0f 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedClassProtectedSetters/CreateStudent.g.cs @@ -31,25 +31,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth!); return this; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreatePerson.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreatePerson.g.cs index dee9103..2f70e75 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreatePerson.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreatePerson.g.cs @@ -30,19 +30,19 @@ public static ICreatePerson InitialStep() public static IBornOn WithName(string name) { CreatePerson createPerson = new CreatePerson(); - SetName(createPerson.person, name); + SetName(createPerson.person, name!); return createPerson; } IBornOn IWithName.WithName(string name) { - SetName(person, name); + SetName(person, name!); return this; } Person IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(person, dateOfBirth); + SetDateOfBirth(person, dateOfBirth!); return person; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.expected.txt index 0e9e003..26df6f0 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.expected.txt @@ -31,25 +31,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth!); return this; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs index 0e9e003..26df6f0 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/InheritedRecord/CreateStudent.g.cs @@ -31,25 +31,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth!); return this; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.expected.txt index f7cadf5..fc3568a 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.expected.txt @@ -94,19 +94,19 @@ public class CreateStudent : Student IWhoIsHappy.WhoIsHappy(bool? isHappy) { - SetIsHappy(student, isHappy); + SetIsHappy(student, isHappy!); return student; } Student IWhoIsHappy.WhoIsSad() { - SetIsHappy(student, false); + SetIsHappy(student, false!); return student; } Student IWhoIsHappy.WithUnknownMood() { - SetIsHappy(student, null); + SetIsHappy(student, null!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.g.cs index f7cadf5..fc3568a 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/NullablePredicateAndCollectionClass/CreateStudent.g.cs @@ -94,19 +94,19 @@ IWhoIsHappy IWhoseFriendsAre.WhoseFriendsAreUnknown() Student IWhoIsHappy.WhoIsHappy(bool? isHappy) { - SetIsHappy(student, isHappy); + SetIsHappy(student, isHappy!); return student; } Student IWhoIsHappy.WhoIsSad() { - SetIsHappy(student, false); + SetIsHappy(student, false!); return student; } Student IWhoIsHappy.WithUnknownMood() { - SetIsHappy(student, null); + SetIsHappy(student, null!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.expected.txt index b28a572..4b6bcd0 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.expected.txt @@ -29,19 +29,19 @@ public class CreateStudent : public static IWithLastName WithFirstName(string firstName) { CreateStudent createStudent = new CreateStudent(); - SetFirstName(createStudent.student, firstName); + SetFirstName(createStudent.student, firstName!); return createStudent; } IWithLastName IWithFirstName.WithFirstName(string firstName) { - SetFirstName(student, firstName); + SetFirstName(student, firstName!); return this; } Student IWithLastName.WithLastName(string lastName) { - SetLastName(student, lastName); + SetLastName(student, lastName!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.g.cs index b28a572..4b6bcd0 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PartialClass/CreateStudent.g.cs @@ -29,19 +29,19 @@ public static ICreateStudent InitialStep() public static IWithLastName WithFirstName(string firstName) { CreateStudent createStudent = new CreateStudent(); - SetFirstName(createStudent.student, firstName); + SetFirstName(createStudent.student, firstName!); return createStudent; } IWithLastName IWithFirstName.WithFirstName(string firstName) { - SetFirstName(student, firstName); + SetFirstName(student, firstName!); return this; } Student IWithLastName.WithLastName(string lastName) { - SetLastName(student, lastName); + SetLastName(student, lastName!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.expected.txt index deb6426..d3ec4f9 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.expected.txt @@ -28,26 +28,26 @@ public class CreateStudent : public static Student WhoIsHappy(bool isHappy = true) { CreateStudent createStudent = new CreateStudent(); - IsHappyField(createStudent.student) = isHappy; + IsHappyField(createStudent.student) = isHappy!; return createStudent.student; } public static Student WhoIsSad() { CreateStudent createStudent = new CreateStudent(); - IsHappyField(createStudent.student) = false; + IsHappyField(createStudent.student) = false!; return createStudent.student; } Student IWhoIsHappy.WhoIsHappy(bool isHappy) { - IsHappyField(student) = isHappy; + IsHappyField(student) = isHappy!; return student; } Student IWhoIsHappy.WhoIsSad() { - IsHappyField(student) = false; + IsHappyField(student) = false!; return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.g.cs index deb6426..d3ec4f9 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PredicatePrivateFieldClass/CreateStudent.g.cs @@ -28,26 +28,26 @@ public static ICreateStudent InitialStep() public static Student WhoIsHappy(bool isHappy = true) { CreateStudent createStudent = new CreateStudent(); - IsHappyField(createStudent.student) = isHappy; + IsHappyField(createStudent.student) = isHappy!; return createStudent.student; } public static Student WhoIsSad() { CreateStudent createStudent = new CreateStudent(); - IsHappyField(createStudent.student) = false; + IsHappyField(createStudent.student) = false!; return createStudent.student; } Student IWhoIsHappy.WhoIsHappy(bool isHappy) { - IsHappyField(student) = isHappy; + IsHappyField(student) = isHappy!; return student; } Student IWhoIsHappy.WhoIsSad() { - IsHappyField(student) = false; + IsHappyField(student) = false!; return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.expected.txt index 4dd5841..33885b8 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.expected.txt @@ -28,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SemesterField(createStudent.student) = semester; + SemesterField(createStudent.student) = semester!; return createStudent.student; } Student IInSemester.InSemester(int semester) { - SemesterField(student) = semester; + SemesterField(student) = semester!; return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.g.cs index 4dd5841..33885b8 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateFieldClass/CreateStudent.g.cs @@ -28,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SemesterField(createStudent.student) = semester; + SemesterField(createStudent.student) = semester!; return createStudent.student; } Student IInSemester.InSemester(int semester) { - SemesterField(student) = semester; + SemesterField(student) = semester!; return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt index ab9c32e..b8347b2 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.expected.txt @@ -28,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SemesterField(createStudent.student) = semester; + SemesterField(createStudent.student) = semester!; return createStudent.student; } Student IInSemester.InSemester(int semester) { - SemesterField(student) = semester; + SemesterField(student) = semester!; return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs index ab9c32e..b8347b2 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateReadonlyFieldClass/CreateStudent.g.cs @@ -28,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SemesterField(createStudent.student) = semester; + SemesterField(createStudent.student) = semester!; return createStudent.student; } Student IInSemester.InSemester(int semester) { - SemesterField(student) = semester; + SemesterField(student) = semester!; return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.expected.txt index 51448bc..d7a0e0c 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.expected.txt @@ -28,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SemesterField(createStudent.student) = semester; + SemesterField(createStudent.student) = semester!; return createStudent.student; } Student IInSemester.InSemester(int semester) { - SemesterField(student) = semester; + SemesterField(student) = semester!; return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.g.cs index 51448bc..d7a0e0c 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PrivateUnderscoreFieldClass/CreateStudent.g.cs @@ -28,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SemesterField(createStudent.student) = semester; + SemesterField(createStudent.student) = semester!; return createStudent.student; } Student IInSemester.InSemester(int semester) { - SemesterField(student) = semester; + SemesterField(student) = semester!; return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.expected.txt index ad07a6d..a66afb9 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.expected.txt @@ -28,13 +28,13 @@ public class CreateStudent : public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SemesterField(createStudent.student) = semester; + SemesterField(createStudent.student) = semester!; return createStudent.student; } Student IInSemester.InSemester(int semester) { - SemesterField(student) = semester; + SemesterField(student) = semester!; return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.g.cs index ad07a6d..a66afb9 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/PublicReadonlyFieldClass/CreateStudent.g.cs @@ -28,13 +28,13 @@ public static ICreateStudent InitialStep() public static Student InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SemesterField(createStudent.student) = semester; + SemesterField(createStudent.student) = semester!; return createStudent.student; } Student IInSemester.InSemester(int semester) { - SemesterField(student) = semester; + SemesterField(student) = semester!; return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.expected.txt index 546fc98..a0e19e4 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.expected.txt @@ -30,25 +30,25 @@ public class CreateStudent : public static IWithName InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SetSemester(createStudent.student, semester); + SetSemester(createStudent.student, semester!); return createStudent; } IWithName IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return this; } IWithName2 IWithName.WithName(char initial) { - SetInitial(student, initial); + SetInitial(student, initial!); return this; } Student IWithName2.WithName(string lastName) { - SetLastName(student, lastName); + SetLastName(student, lastName!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.g.cs index 546fc98..a0e19e4 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/SameNameMemberClass/CreateStudent.g.cs @@ -30,25 +30,25 @@ public static ICreateStudent InitialStep() public static IWithName InSemester(int semester) { CreateStudent createStudent = new CreateStudent(); - SetSemester(createStudent.student, semester); + SetSemester(createStudent.student, semester!); return createStudent; } IWithName IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return this; } IWithName2 IWithName.WithName(char initial) { - SetInitial(student, initial); + SetInitial(student, initial!); return this; } Student IWithName2.WithName(string lastName) { - SetLastName(student, lastName); + SetLastName(student, lastName!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt index b4f33f1..6548edb 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.expected.txt @@ -31,25 +31,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth!); return this; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs index b4f33f1..6548edb 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreeMemberRecordPrimaryConstructor/CreateStudent.g.cs @@ -31,25 +31,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth!); return this; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt index e6fc7ae..86f1d22 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.expected.txt @@ -31,25 +31,25 @@ public class CreateStudent : public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth!); return this; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs index e6fc7ae..86f1d22 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/ThreePrivateMembersClass/CreateStudent.g.cs @@ -31,25 +31,25 @@ public static ICreateStudent InitialStep() public static IBornOn WithName(string name) { CreateStudent createStudent = new CreateStudent(); - SetName(createStudent.student, name); + SetName(createStudent.student, name!); return createStudent; } IBornOn IWithName.WithName(string name) { - SetName(student, name); + SetName(student, name!); return this; } IInSemester IBornOn.BornOn(System.DateOnly dateOfBirth) { - SetDateOfBirth(student, dateOfBirth); + SetDateOfBirth(student, dateOfBirth!); return this; } Student IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.expected.txt index 7f3b16b..533862f 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.expected.txt @@ -39,23 +39,23 @@ public class CreateDocumentedStudent : public static IOfAgeBornOn Named(string firstName, string lastName) { CreateDocumentedStudent createDocumentedStudent = new CreateDocumentedStudent(); - SetFirstName(createDocumentedStudent.documentedStudent, firstName); - SetLastName(createDocumentedStudent.documentedStudent, lastName); + SetFirstName(createDocumentedStudent.documentedStudent, firstName!); + SetLastName(createDocumentedStudent.documentedStudent, lastName!); return createDocumentedStudent; } /// IOfAgeBornOn INamed.Named(string firstName, string lastName) { - SetFirstName(documentedStudent, firstName); - SetLastName(documentedStudent, lastName); + SetFirstName(documentedStudent, firstName!); + SetLastName(documentedStudent, lastName!); return this; } /// IInSemester IOfAgeBornOn.OfAge(int age) { - SetAge(documentedStudent, age); + SetAge(documentedStudent, age!); return this; } @@ -69,7 +69,7 @@ public class CreateDocumentedStudent : /// ILivingIn IInSemester.InSemester(int semester) { - SetSemester(documentedStudent, semester); + SetSemester(documentedStudent, semester!); return this; } @@ -82,7 +82,7 @@ public class CreateDocumentedStudent : /// IWhoIsHappy ILivingIn.LivingIn(string? city) { - SetCity(documentedStudent, city); + SetCity(documentedStudent, city!); return this; } @@ -95,56 +95,56 @@ public class CreateDocumentedStudent : /// IWhoIsHappy ILivingIn.InUnknownCity() { - SetCity(documentedStudent, null); + SetCity(documentedStudent, null!); return this; } /// IWhoseFriendsAre IWhoIsHappy.WhoIsHappy(bool? isHappy) { - SetIsHappy(documentedStudent, isHappy); + SetIsHappy(documentedStudent, isHappy!); return this; } /// IWhoseFriendsAre IWhoIsHappy.WhoIsSad() { - SetIsHappy(documentedStudent, false); + SetIsHappy(documentedStudent, false!); return this; } /// IWhoseFriendsAre IWhoIsHappy.WithUnknownMood() { - SetIsHappy(documentedStudent, null); + SetIsHappy(documentedStudent, null!); return this; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendsAre(System.Collections.Generic.IReadOnlyCollection friends) { - SetFriends(documentedStudent, friends); + SetFriends(documentedStudent, friends!); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendsAre(params string[] friends) { - SetFriends(documentedStudent, friends); + SetFriends(documentedStudent, friends!); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendIs(string friend) { - SetFriends(documentedStudent, new string[1]{ friend }); + SetFriends(documentedStudent, new string[1]{ friend }!); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoHasNoFriends() { - SetFriends(documentedStudent, new string[0]); + SetFriends(documentedStudent, new string[0]!); return documentedStudent; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.g.cs index 7f3b16b..533862f 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/DocumentedStudentClass/CreateDocumentedStudent.g.cs @@ -39,23 +39,23 @@ public static ICreateDocumentedStudent InitialStep() public static IOfAgeBornOn Named(string firstName, string lastName) { CreateDocumentedStudent createDocumentedStudent = new CreateDocumentedStudent(); - SetFirstName(createDocumentedStudent.documentedStudent, firstName); - SetLastName(createDocumentedStudent.documentedStudent, lastName); + SetFirstName(createDocumentedStudent.documentedStudent, firstName!); + SetLastName(createDocumentedStudent.documentedStudent, lastName!); return createDocumentedStudent; } /// IOfAgeBornOn INamed.Named(string firstName, string lastName) { - SetFirstName(documentedStudent, firstName); - SetLastName(documentedStudent, lastName); + SetFirstName(documentedStudent, firstName!); + SetLastName(documentedStudent, lastName!); return this; } /// IInSemester IOfAgeBornOn.OfAge(int age) { - SetAge(documentedStudent, age); + SetAge(documentedStudent, age!); return this; } @@ -69,7 +69,7 @@ IInSemester IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) /// ILivingIn IInSemester.InSemester(int semester) { - SetSemester(documentedStudent, semester); + SetSemester(documentedStudent, semester!); return this; } @@ -82,7 +82,7 @@ ILivingIn IInSemester.WhoStartsUniversity() /// IWhoIsHappy ILivingIn.LivingIn(string? city) { - SetCity(documentedStudent, city); + SetCity(documentedStudent, city!); return this; } @@ -95,56 +95,56 @@ IWhoIsHappy ILivingIn.LivingInBoston() /// IWhoIsHappy ILivingIn.InUnknownCity() { - SetCity(documentedStudent, null); + SetCity(documentedStudent, null!); return this; } /// IWhoseFriendsAre IWhoIsHappy.WhoIsHappy(bool? isHappy) { - SetIsHappy(documentedStudent, isHappy); + SetIsHappy(documentedStudent, isHappy!); return this; } /// IWhoseFriendsAre IWhoIsHappy.WhoIsSad() { - SetIsHappy(documentedStudent, false); + SetIsHappy(documentedStudent, false!); return this; } /// IWhoseFriendsAre IWhoIsHappy.WithUnknownMood() { - SetIsHappy(documentedStudent, null); + SetIsHappy(documentedStudent, null!); return this; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendsAre(System.Collections.Generic.IReadOnlyCollection friends) { - SetFriends(documentedStudent, friends); + SetFriends(documentedStudent, friends!); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendsAre(params string[] friends) { - SetFriends(documentedStudent, friends); + SetFriends(documentedStudent, friends!); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoseFriendIs(string friend) { - SetFriends(documentedStudent, new string[1]{ friend }); + SetFriends(documentedStudent, new string[1]{ friend }!); return documentedStudent; } /// DocumentedStudent IWhoseFriendsAre.WhoHasNoFriends() { - SetFriends(documentedStudent, new string[0]); + SetFriends(documentedStudent, new string[0]!); return documentedStudent; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.expected.txt index a53d530..9262828 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.expected.txt @@ -35,25 +35,25 @@ public class CreatePerson : public static IWithMiddleName WithFirstName(string firstName) { CreatePerson createPerson = new CreatePerson(); - SetFirstName(createPerson.person, firstName); + SetFirstName(createPerson.person, firstName!); return createPerson; } IWithMiddleName IWithFirstName.WithFirstName(string firstName) { - SetFirstName(person, firstName); + SetFirstName(person, firstName!); return this; } IWithLastName IWithMiddleName.WithMiddleName(string? middleName) { - SetMiddleName(person, middleName); + SetMiddleName(person, middleName!); return this; } IWhoseAddressIsUnknownWhoLivesAtAddressWhoIsADigitalNomad IWithLastName.WithLastName(string lastName) { - SetLastName(person, lastName); + SetLastName(person, lastName!); return this; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.g.cs index a53d530..9262828 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/PersonClass/CreatePerson.g.cs @@ -35,25 +35,25 @@ public static ICreatePerson InitialStep() public static IWithMiddleName WithFirstName(string firstName) { CreatePerson createPerson = new CreatePerson(); - SetFirstName(createPerson.person, firstName); + SetFirstName(createPerson.person, firstName!); return createPerson; } IWithMiddleName IWithFirstName.WithFirstName(string firstName) { - SetFirstName(person, firstName); + SetFirstName(person, firstName!); return this; } IWithLastName IWithMiddleName.WithMiddleName(string? middleName) { - SetMiddleName(person, middleName); + SetMiddleName(person, middleName!); return this; } IWhoseAddressIsUnknownWhoLivesAtAddressWhoIsADigitalNomad IWithLastName.WithLastName(string lastName) { - SetLastName(person, lastName); + SetLastName(person, lastName!); return this; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.expected.txt index 02af185..8cc576a 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.expected.txt @@ -35,21 +35,21 @@ public class CreateStudent : public static IOfAgeBornOn Named(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - SetFirstName(createStudent.student, firstName); - SetLastName(createStudent.student, lastName); + SetFirstName(createStudent.student, firstName!); + SetLastName(createStudent.student, lastName!); return createStudent; } IOfAgeBornOn INamed.Named(string firstName, string lastName) { - SetFirstName(student, firstName); - SetLastName(student, lastName); + SetFirstName(student, firstName!); + SetLastName(student, lastName!); return this; } IInSemester IOfAgeBornOn.OfAge(int age) { - SetAge(student, age); + SetAge(student, age!); return this; } @@ -61,7 +61,7 @@ public class CreateStudent : ILivingIn IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return this; } @@ -72,7 +72,7 @@ public class CreateStudent : IWhoIsHappy ILivingIn.LivingIn(string? city) { - SetCity(student, city); + SetCity(student, city!); return this; } @@ -83,49 +83,49 @@ public class CreateStudent : IWhoIsHappy ILivingIn.InUnknownCity() { - SetCity(student, null); + SetCity(student, null!); return this; } IWhoseFriendsAre IWhoIsHappy.WhoIsHappy(bool? isHappy) { - SetIsHappy(student, isHappy); + SetIsHappy(student, isHappy!); return this; } IWhoseFriendsAre IWhoIsHappy.WhoIsSad() { - SetIsHappy(student, false); + SetIsHappy(student, false!); return this; } IWhoseFriendsAre IWhoIsHappy.WithUnknownMood() { - SetIsHappy(student, null); + SetIsHappy(student, null!); return this; } Student IWhoseFriendsAre.WhoseFriendsAre(System.Collections.Generic.IReadOnlyCollection friends) { - SetFriends(student, friends); + SetFriends(student, friends!); return student; } Student IWhoseFriendsAre.WhoseFriendsAre(params string[] friends) { - SetFriends(student, friends); + SetFriends(student, friends!); return student; } Student IWhoseFriendsAre.WhoseFriendIs(string friend) { - SetFriends(student, new string[1]{ friend }); + SetFriends(student, new string[1]{ friend }!); return student; } Student IWhoseFriendsAre.WhoHasNoFriends() { - SetFriends(student, new string[0]); + SetFriends(student, new string[0]!); return student; } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.g.cs index 02af185..8cc576a 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.g.cs @@ -35,21 +35,21 @@ public static ICreateStudent InitialStep() public static IOfAgeBornOn Named(string firstName, string lastName) { CreateStudent createStudent = new CreateStudent(); - SetFirstName(createStudent.student, firstName); - SetLastName(createStudent.student, lastName); + SetFirstName(createStudent.student, firstName!); + SetLastName(createStudent.student, lastName!); return createStudent; } IOfAgeBornOn INamed.Named(string firstName, string lastName) { - SetFirstName(student, firstName); - SetLastName(student, lastName); + SetFirstName(student, firstName!); + SetLastName(student, lastName!); return this; } IInSemester IOfAgeBornOn.OfAge(int age) { - SetAge(student, age); + SetAge(student, age!); return this; } @@ -61,7 +61,7 @@ IInSemester IOfAgeBornOn.BornOn(System.DateOnly dateOfBirth) ILivingIn IInSemester.InSemester(int semester) { - SetSemester(student, semester); + SetSemester(student, semester!); return this; } @@ -72,7 +72,7 @@ ILivingIn IInSemester.WhoStartsUniversity() IWhoIsHappy ILivingIn.LivingIn(string? city) { - SetCity(student, city); + SetCity(student, city!); return this; } @@ -83,49 +83,49 @@ IWhoIsHappy ILivingIn.LivingInBoston() IWhoIsHappy ILivingIn.InUnknownCity() { - SetCity(student, null); + SetCity(student, null!); return this; } IWhoseFriendsAre IWhoIsHappy.WhoIsHappy(bool? isHappy) { - SetIsHappy(student, isHappy); + SetIsHappy(student, isHappy!); return this; } IWhoseFriendsAre IWhoIsHappy.WhoIsSad() { - SetIsHappy(student, false); + SetIsHappy(student, false!); return this; } IWhoseFriendsAre IWhoIsHappy.WithUnknownMood() { - SetIsHappy(student, null); + SetIsHappy(student, null!); return this; } Student IWhoseFriendsAre.WhoseFriendsAre(System.Collections.Generic.IReadOnlyCollection friends) { - SetFriends(student, friends); + SetFriends(student, friends!); return student; } Student IWhoseFriendsAre.WhoseFriendsAre(params string[] friends) { - SetFriends(student, friends); + SetFriends(student, friends!); return student; } Student IWhoseFriendsAre.WhoseFriendIs(string friend) { - SetFriends(student, new string[1]{ friend }); + SetFriends(student, new string[1]{ friend }!); return student; } Student IWhoseFriendsAre.WhoHasNoFriends() { - SetFriends(student, new string[0]); + SetFriends(student, new string[0]!); return student; } From d7fbe1e49020dd7a973942b4c8f5086d793749bb Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 11:33:04 +0100 Subject: [PATCH 64/67] chore: add example and story book project --- src/ExampleProject/ExampleProject.csproj | 2 +- src/M31.FluentApi.Storybook/M31.FluentApi.Storybook.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ExampleProject/ExampleProject.csproj b/src/ExampleProject/ExampleProject.csproj index 97ff9de..42ea1a2 100644 --- a/src/ExampleProject/ExampleProject.csproj +++ b/src/ExampleProject/ExampleProject.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 enable enable diff --git a/src/M31.FluentApi.Storybook/M31.FluentApi.Storybook.csproj b/src/M31.FluentApi.Storybook/M31.FluentApi.Storybook.csproj index f086922..f947272 100644 --- a/src/M31.FluentApi.Storybook/M31.FluentApi.Storybook.csproj +++ b/src/M31.FluentApi.Storybook/M31.FluentApi.Storybook.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 enable enable false From 72e945db07f40eb9c275c6eeff2c3cf478e49ad4 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 14:29:35 +0100 Subject: [PATCH 65/67] chore: suppress warnings --- .../SourceAnalyzers/FluentApiAnalyzer.cs | 3 ++- .../SourceGenerators/SourceGenerator.cs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiAnalyzer.cs b/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiAnalyzer.cs index 5c47849..0b81074 100644 --- a/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiAnalyzer.cs +++ b/src/M31.FluentApi.Generator/SourceAnalyzers/FluentApiAnalyzer.cs @@ -10,8 +10,9 @@ namespace M31.FluentApi.Generator.SourceAnalyzers; -// todo: https://github.com/dotnet/roslyn-analyzers/issues/7438 +#pragma warning disable RS1038 [DiagnosticAnalyzer(LanguageNames.CSharp)] +#pragma warning restore RS1038 internal class FluentApiAnalyzer : DiagnosticAnalyzer { public override ImmutableArray SupportedDiagnostics { get; } = diff --git a/src/M31.FluentApi.Generator/SourceGenerators/SourceGenerator.cs b/src/M31.FluentApi.Generator/SourceGenerators/SourceGenerator.cs index 2159892..c1ff973 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/SourceGenerator.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/SourceGenerator.cs @@ -6,7 +6,9 @@ namespace M31.FluentApi.Generator.SourceGenerators; +#pragma warning disable RS1038 [Generator(LanguageNames.CSharp)] +#pragma warning restore RS1038 internal class SourceGenerator : IIncrementalGenerator { internal static readonly SourceGeneratorConfig GeneratorConfig = new SourceGeneratorConfig(); From e7037558fc930ed0e7924805b153af6956bd44b5 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 14:35:23 +0100 Subject: [PATCH 66/67] chore: mention UnsafeAccessors --- README.md | 2 +- src/M31.FluentApi.Storybook/01_Basics.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d320df4..da1a93c 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ public class Student ![fluent-api-usage](https://raw.githubusercontent.com/m31coding/M31.FluentAPI/main/media/fluent-api.gif) -You may have a look at the generated code for this example: [CreateStudent.g.cs](src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.g.cs). Note that if you use private members or properties with a private set accessor, as it is the case in this example, the generated code will use reflection to set the properties. +You may have a look at the generated code for this example: [CreateStudent.g.cs](src/M31.FluentApi.Tests/CodeGeneration/TestClasses/StudentClass/CreateStudent.g.cs). Note that if you use private members or properties with a private set accessor, as it is the case in this example, the generated code will use UnsafeAccessors to set the properties. ## Attributes diff --git a/src/M31.FluentApi.Storybook/01_Basics.cs b/src/M31.FluentApi.Storybook/01_Basics.cs index 43ef494..0e446e1 100644 --- a/src/M31.FluentApi.Storybook/01_Basics.cs +++ b/src/M31.FluentApi.Storybook/01_Basics.cs @@ -206,7 +206,7 @@ public static void UseTheGeneratedFluentApi() namespace FluentMethodExample { /* The generated builder methods simply set the values of the fields and properties. For public fields and - properties, this is straightforward. For private fields and private set accessors, reflection will be used. + properties, this is straightforward. For private fields and private set accessors, UnsafeAccessors will be used. Nevertheless, in both cases, the builder methods merely set the values to the given arguments. There might be use cases where you want to have more control over the builder methods, such as setting the value in a particular way or triggering additional behavior. To this end you, can define custom methods that return From f32be8b5593af7e30cc75cf5791f252151f55e69 Mon Sep 17 00:00:00 2001 From: Kevin Schaal Date: Tue, 30 Dec 2025 14:43:07 +0100 Subject: [PATCH 67/67] chore: 2.0.0 and changelog --- CHANGELOG.md | 13 +++++++++++++ README.md | 7 ++++++- .../M31.FluentApi.Generator.csproj | 2 +- src/M31.FluentApi/M31.FluentApi.csproj | 2 +- 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7c364b6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [2.0.0] - 2025-12-30 + +### Changed + +- Generated code now requires .NET 10 instead of .NET 6 +- UnsafeAccessors are used instead of reflection for setting private properties and fields diff --git a/README.md b/README.md index da1a93c..b4aeac3 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,11 @@ Accompanying blog post: [www.m31coding.com>blog>fluent-api](https://www.m31codin - Support for returning arbitrary types - Support for inheritance, generics, and partial classes +## Prerequisites + +- v1.x.x: .NET 6 +- v2.x.x: .NET 10 + ## Installing via NuGet Install the latest version of the package `M31.FluentApi` via your IDE or use the package manager console: @@ -37,7 +42,7 @@ PM> Install-Package M31.FluentApi A package reference will be added to your `csproj` file. Moreover, since this library provides code via source code generation, consumers of your project don't need the reference to `M31.FluentApi`. Therefore, it is recommended to use the `PrivateAssets` metadata tag: ```xml - + ``` If you would like to examine the generated code, you may emit it by adding the following lines to your `csproj` file: diff --git a/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj b/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj index bdf08f9..8076b62 100644 --- a/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj +++ b/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj @@ -11,7 +11,7 @@ true true true - 1.12.0 + 2.0.0 Kevin Schaal The generator package for M31.FluentAPI. Don't install this package explicitly, install M31.FluentAPI instead. fluentapi fluentbuilder fluentinterface fluentdesign fluent codegeneration diff --git a/src/M31.FluentApi/M31.FluentApi.csproj b/src/M31.FluentApi/M31.FluentApi.csproj index 84d1d49..9b432c0 100644 --- a/src/M31.FluentApi/M31.FluentApi.csproj +++ b/src/M31.FluentApi/M31.FluentApi.csproj @@ -7,7 +7,7 @@ enable true true - 1.12.0 + 2.0.0 Kevin Schaal Generate fluent builders in C#. fluentapi fluentbuilder fluentinterface fluentdesign fluent codegeneration