From fe625e84bc46d8de233adb1c146d3e77270832ef Mon Sep 17 00:00:00 2001 From: Kevin Schaal <76872371+m31coding@users.noreply.github.com> Date: Sun, 16 Jun 2024 19:52:16 +0200 Subject: [PATCH] feat: Lambda methods by default (#24) * feat: fluent lambda per default * feat: lambda parameters for compounds * fix: lambda method parameter names * feat(LambdaByDefault): LambdaBuilderInfo for the FluentCollectionAttributeInfo * fix(FluentApiInfoCreator): remove assumptions from TryGetLambdaBuilderInfoOfCollectionType * feat: WithItem method with lambda parameter * test(FluentLambdaCollectionClass): add expected result * test: CanExecuteFluentLambdaCollectionClass * feat: WithItems method with lambda parameters * improve(Readme): feature list and acknowledgements * chore: make FluentLambda obsolete * fix(Readme) * chore: replace FluentLambda with FluentMember in exmaples and tests * chore(Storybook): NestedFluentApis example instead of FluentLambdaExample * fix(ArrayCreator): remove semicolon in CreateCollectionFromEnumerable * fix(ArrayCreator): add using only when needed * test: FluentLambdaCollectionClass2 * test: FluentLambdaManyCollectionsClass and FluentLambdaManyPrivateCollectionsClass * improve: property order in FluentLambdaManyPrivateCollectionsClass and FluentLambdaManyCollectionsClass * fix: execution tests * improve(CodeGenerationExecutionTests): blocks between different subtests * test: add failing test TryBreakFluentApiClass3 * refactor(CollectionMethodCreator): cleanup * fix: make TryBreakFluentApiClass3 test work * chore: adjust storybook and readme * chore: increase package version to 1.7.0 * fix: minor change --- README.md | 49 +- src/ExampleProject/Order.cs | 2 +- src/ExampleProject/OrderArbitrarySteps.cs | 2 +- .../Collections/ArrayCreator.cs | 8 +- .../Collections/CollectionMethodCreator.cs | 81 ++- .../Collections/CollectionMethods.cs | 7 +- .../Collections/HashSetCreator.cs | 10 +- .../MethodCreation/Collections/ListCreator.cs | 10 +- .../MethodCreation/CompoundMethods.cs | 70 ++- .../MethodCreation/LambdaMethod.cs | 87 ++- .../MethodCreation/MemberMethod.cs | 15 +- .../M31.FluentApi.Generator.csproj | 2 +- .../FluentCollectionAttributeInfo.cs | 13 +- .../FluentMemberAttributeInfo.cs | 15 +- .../Collections/CollectionInference.cs | 9 +- .../Collections/CollectionType.cs | 31 +- .../SourceGenerators/FluentApiInfoCreator.cs | 75 ++- src/M31.FluentApi.Storybook/01_Basics.cs | 37 +- .../AnalyzerAndCodeFixTests.cs | 2 +- .../Student.cs | 2 + .../CodeGenerationExecutionTests.cs | 534 ++++++++++++------ .../Abstract/FluentLambdaClass/Student.cs | 2 +- .../Student.cs | 2 +- .../FluentLambdaCollectionClass/Address.cs | 20 + .../CreateAddress.g.cs | 73 +++ .../CreateStudent.expected.txt | 104 ++++ .../CreateStudent.g.cs | 104 ++++ .../FluentLambdaCollectionClass/Student.cs | 18 + .../FluentLambdaCompoundClass/Address.cs | 20 + .../CreateAddress.g.cs | 73 +++ .../CreatePhone.g.cs | 61 ++ .../CreateStudent.expected.txt | 72 +++ .../CreateStudent.g.cs | 72 +++ .../FluentLambdaCompoundClass/Phone.cs | 17 + .../FluentLambdaCompoundClass/Student.cs | 20 + .../Address.cs | 20 + .../CreateAddress.g.cs | 73 +++ .../CreateStudent.expected.txt | 72 +++ .../CreateStudent.g.cs | 72 +++ .../Student.cs | 20 + .../Address.cs | 20 + .../CreateAddress.g.cs | 73 +++ .../CreateStudent.expected.txt | 360 ++++++++++++ .../CreateStudent.g.cs | 360 ++++++++++++ .../Student.cs | 36 ++ .../Address.cs | 20 + .../CreateAddress.g.cs | 73 +++ .../CreateStudent.expected.txt | 381 +++++++++++++ .../CreateStudent.g.cs | 381 +++++++++++++ .../Student.cs | 36 ++ .../Student.cs | 2 +- .../CreateStudent.expected.txt | 6 +- .../CreateStudent.g.cs | 6 +- .../FluentLambdaRecursiveClass/Student.cs | 2 +- .../FluentLambdaSingleStepClass/Student.cs | 2 +- .../TryBreakFluentApiClass3/Address.cs | 20 + .../CreateAddress.g.cs | 73 +++ .../CreateStudent.expected.txt | 69 +++ .../CreateStudent.g.cs | 69 +++ .../TryBreakFluentApiClass3/Student.cs | 17 + .../CodeGeneration/TestDataProvider.cs | 6 + .../Components/CollectionInferenceTests.cs | 2 +- src/M31.FluentApi.sln.DotSettings | 3 +- .../Attributes/FluentLambdaAttribute.cs | 3 + src/M31.FluentApi/M31.FluentApi.csproj | 2 +- 65 files changed, 3702 insertions(+), 296 deletions(-) create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/Address.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateAddress.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateStudent.expected.txt create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateStudent.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/Student.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Address.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateAddress.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreatePhone.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateStudent.expected.txt create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateStudent.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Phone.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Student.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/Address.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateAddress.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateStudent.expected.txt create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateStudent.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/Student.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/Address.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateAddress.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateStudent.expected.txt create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateStudent.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/Student.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/Address.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateAddress.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.expected.txt create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/Student.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/Address.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateAddress.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateStudent.expected.txt create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateStudent.g.cs create mode 100644 src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/Student.cs diff --git a/README.md b/README.md index 3da4657..ec49f36 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,18 @@ The generated code follows the builder design pattern and allows you to construc Accompanying blog post: [www.m31coding.com>blog>fluent-api](https://www.m31coding.com/blog/fluent-api.html) +## Features + +- Builder code generation controlled by attributes +- Stepwise object construction +- Special handling for boolean, collection, and nullable members +- Nested fluent APIs via lambda methods +- Custom builder methods +- Optional (skippable) builder methods +- Forking and branching capabilities +- Support for returning arbitrary types +- Support for generics and partial classes + ## Installing via NuGet Install the latest version of the package `M31.FluentApi` via your IDE or use the package manager console: @@ -25,7 +37,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: @@ -106,7 +118,7 @@ You may have a look at the generated code for this example: [CreateStudent.g.cs] The attributes `FluentApi` and `FluentMember` are all you need in order to get started. -The attributes `FluentPredicate`, `FluentCollection`, and `FluentLambda` can be used instead of the `FluentMember` attribute if the decorated member is a boolean, a collection, or has its own Fluent API, respectively. +The attributes `FluentPredicate` and `FluentCollection` can be used instead of the `FluentMember` attribute if the decorated member is a boolean or a collection, respectively. `FluentDefault` and `FluentNullable` can be used in combination with these attributes to set a default value or null, respectively. @@ -170,6 +182,17 @@ public string LastName { get; private set; } ```cs ...Named("Alice", "King")... ``` + +If the decorated member has its own Fluent API, an additional lambda method is generated, e.g. + +```cs +[FluentMember(1)] +public Address Address { get; private set; } +``` + +```cs +...WithAddress(a => a.WithHouseNumber("108").WithStreet("5th Avenue").InCity("New York"))... +``` ### FluentPredicate @@ -217,25 +240,20 @@ public IReadOnlyCollection Friends { get; private set; } ...WhoHasNoFriends()... ``` - -### FluentLambda +If the element type of the decorated member has its own Fluent API, additional lambda methods are generated, e.g. ```cs -FluentLambda(int builderStep, string method = "With{Name}") +[FluentCollection(1, "Address")] +public IReadOnlyCollection
Addresses { get; private set; } ``` -Can be used instead of the `FluentMember` attribute if the decorated member has its own Fluent API. Generates an additional builder method that accepts a lambda expression for creating the target field or property. - ```cs -[FluentLambda(1)] -public Address Address { get; private set; } +...WithAddresses( + a => a.WithHouseNumber("108").WithStreet("5th Avenue").InCity("New York"), + a => a.WithHouseNumber("42").WithStreet("Maple Ave").InCity("Boston"))... +...WithAddress(a => a.WithHouseNumber("82").WithStreet("Friedrichstraße").InCity("Berlin"))... ``` -```cs -...WithAddress(new Address("23", "Market Street", "San Francisco"))... -...WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"))... -``` - ### FluentDefault @@ -438,7 +456,7 @@ public void AddStudent(Func createStudent university.AddStudent(s => s.Named("Alice", "King").OfAge(22)...); ``` -Note that if you want to set a single field or property on a Fluent API class, you can instead use the `FluentLambda` attribute. +Note that if you want to set a member of a Fluent API class, you can simply use `FluentMember` or `FluentCollection` instead of the pattern above. ## Problems with the IDE @@ -451,6 +469,7 @@ In particular, if your IDE visually indicates that there are errors in your code - Unload and reload the project - Close and reopen the IDE - Remove the .vs folder (Visual Studio) or the .idea folder (Rider) + ## Support and Contribution diff --git a/src/ExampleProject/Order.cs b/src/ExampleProject/Order.cs index e40f3bd..a8504c2 100644 --- a/src/ExampleProject/Order.cs +++ b/src/ExampleProject/Order.cs @@ -18,7 +18,7 @@ public class Order [FluentMember(1, "{Name}")] public DateTime CreatedOn { get; private set; } - [FluentLambda(2, "ShippedTo")] + [FluentMember(2, "ShippedTo")] public Address ShippingAddress { get; private set; } } diff --git a/src/ExampleProject/OrderArbitrarySteps.cs b/src/ExampleProject/OrderArbitrarySteps.cs index cb5af64..1f047a7 100644 --- a/src/ExampleProject/OrderArbitrarySteps.cs +++ b/src/ExampleProject/OrderArbitrarySteps.cs @@ -20,7 +20,7 @@ public class Order2 [FluentContinueWith(0)] public DateTime? CreatedOn { get; private set; } - [FluentLambda(0, "ShippedTo")] + [FluentMember(0, "ShippedTo")] [FluentContinueWith(0)] public Address2? ShippingAddress { get; private set; } diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/ArrayCreator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/ArrayCreator.cs index c40bcfb..f04ca1d 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/ArrayCreator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/ArrayCreator.cs @@ -18,6 +18,12 @@ protected override string CreateCollectionFromArray(string genericTypeArgument, return arrayParameter; } + protected override string CreateCollectionFromEnumerable(string genericTypeArgument, string enumerableParameter) + { + RequiredUsings.Add("System.Linq"); + return $"{enumerableParameter}.ToArray()"; + } + protected override string CreateCollectionFromSingleItem(string genericTypeArgument, string itemParameter) { return $"new {genericTypeArgument}[1]{{ {itemParameter} }}"; @@ -27,6 +33,4 @@ protected override string CreateCollectionWithZeroItems(string genericTypeArgume { return $"new {genericTypeArgument}[0]"; } - - internal override IReadOnlyCollection RequiredUsings => Array.Empty(); } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/CollectionMethodCreator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/CollectionMethodCreator.cs index 30e248c..d5f4d4e 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/CollectionMethodCreator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/CollectionMethodCreator.cs @@ -10,6 +10,7 @@ internal abstract class CollectionMethodCreator private readonly FluentCollectionAttributeInfo collectionAttributeInfo; private readonly string genericTypeArgument; private readonly MemberSymbolInfo symbolInfo; + private readonly string questionMarkIfNullable; internal CollectionMethodCreator( FluentCollectionAttributeInfo collectionAttributeInfo, @@ -19,20 +20,25 @@ internal CollectionMethodCreator( this.collectionAttributeInfo = collectionAttributeInfo; this.genericTypeArgument = genericTypeArgument; this.symbolInfo = symbolInfo; + questionMarkIfNullable = symbolInfo.IsNullable ? "?" : string.Empty; } internal BuilderMethod? CreateWithItemsMethod(MethodCreator methodCreator) { - return symbolInfo.TypeForCodeGeneration == $"{genericTypeArgument}[]" || - symbolInfo.TypeForCodeGeneration == $"{genericTypeArgument}[]?" - ? null - : methodCreator.CreateMethod(symbolInfo, collectionAttributeInfo.WithItems); + return !ShouldCreateWithItemsMethod() ? null : + methodCreator.CreateMethod(symbolInfo, collectionAttributeInfo.WithItems); + } + + private bool ShouldCreateWithItemsMethod() + { + return symbolInfo.TypeForCodeGeneration != $"{genericTypeArgument}[]" && + symbolInfo.TypeForCodeGeneration != $"{genericTypeArgument}[]?"; } internal BuilderMethod CreateWithItemsParamsMethod(MethodCreator methodCreator) { Parameter parameter = new Parameter( - symbolInfo.IsNullable ? $"{genericTypeArgument}[]?" : $"{genericTypeArgument}[]", + $"{genericTypeArgument}[]{questionMarkIfNullable}", symbolInfo.NameInCamelCase, null, null, @@ -45,6 +51,44 @@ internal BuilderMethod CreateWithItemsParamsMethod(MethodCreator methodCreator) p => CreateCollectionFromArray(genericTypeArgument, p)); } + internal BuilderMethod? CreateWithItemsLambdaParamsMethod(MethodCreator methodCreator) + { + if (collectionAttributeInfo.LambdaBuilderInfo == null) + { + return null; + } + + ComputeValueCode lambdaCode = LambdaMethod.GetComputeValueCode( + genericTypeArgument, + collectionAttributeInfo.SingularNameInCamelCase, + symbolInfo.Name, + collectionAttributeInfo.LambdaBuilderInfo); + + string parameterType = $"{lambdaCode.Parameter!.Type}[]{questionMarkIfNullable}"; + string parameterName = LambdaMethod.GetFullParameterName(symbolInfo.NameInCamelCase); + + Parameter parameter = new Parameter( + parameterType, + parameterName, + null, + null, + new ParameterAnnotations(ParameterKinds.Params)); + + ComputeValueCode computeValueCode = ComputeValueCode.Create( + lambdaCode.TargetMember, + parameter, + p => CreateCollectionFromEnumerable( + genericTypeArgument, + $"{p}{questionMarkIfNullable}.Select({lambdaCode.Parameter!.Name} => {lambdaCode.Code})")); + + RequiredUsings.Add("System"); + RequiredUsings.Add("System.Linq"); + + return methodCreator.BuilderMethodFactory.CreateBuilderMethod( + collectionAttributeInfo.WithItems, + computeValueCode); + } + internal BuilderMethod CreateWithItemMethod(MethodCreator methodCreator) { Parameter parameter = new Parameter(genericTypeArgument, collectionAttributeInfo.SingularNameInCamelCase); @@ -55,6 +99,30 @@ internal BuilderMethod CreateWithItemMethod(MethodCreator methodCreator) p => CreateCollectionFromSingleItem(genericTypeArgument, p)); } + internal BuilderMethod? CreateWithItemLambdaMethod(MethodCreator methodCreator) + { + if (collectionAttributeInfo.LambdaBuilderInfo == null) + { + return null; + } + + ComputeValueCode lambdaCode = LambdaMethod.GetComputeValueCode( + genericTypeArgument, + collectionAttributeInfo.SingularNameInCamelCase, + symbolInfo.Name, + collectionAttributeInfo.LambdaBuilderInfo); + + ComputeValueCode computeValueCode = ComputeValueCode.Create( + lambdaCode.TargetMember, + lambdaCode.Parameter!, + _ => CreateCollectionFromSingleItem(genericTypeArgument, lambdaCode.Code)); + + RequiredUsings.Add("System"); + + return methodCreator.BuilderMethodFactory.CreateBuilderMethod(collectionAttributeInfo.WithItem, + computeValueCode); + } + internal BuilderMethod CreateWithZeroItemsMethod(MethodCreator methodCreator) { string collectionWithZeroItemsCode = CreateCollectionWithZeroItems(genericTypeArgument); @@ -65,7 +133,8 @@ internal BuilderMethod CreateWithZeroItemsMethod(MethodCreator methodCreator) } protected abstract string CreateCollectionFromArray(string genericTypeArgument, string arrayParameter); + protected abstract string CreateCollectionFromEnumerable(string genericTypeArgument, string enumerableParameter); protected abstract string CreateCollectionFromSingleItem(string genericTypeArgument, string itemParameter); protected abstract string CreateCollectionWithZeroItems(string genericTypeArgument); - internal abstract IReadOnlyCollection RequiredUsings { get; } + internal HashSet RequiredUsings { get; } = new HashSet(); } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/CollectionMethods.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/CollectionMethods.cs index 01ed5b6..401da51 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/CollectionMethods.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/CollectionMethods.cs @@ -43,11 +43,14 @@ public BuilderMethods CreateBuilderMethods(MethodCreator methodCreator) { collectionMethodCreator.CreateWithItemsMethod(methodCreator), collectionMethodCreator.CreateWithItemsParamsMethod(methodCreator), + collectionMethodCreator.CreateWithItemsLambdaParamsMethod(methodCreator), collectionMethodCreator.CreateWithItemMethod(methodCreator), + collectionMethodCreator.CreateWithItemLambdaMethod(methodCreator), collectionMethodCreator.CreateWithZeroItemsMethod(methodCreator), }; - return new BuilderMethods(builderMethods.OfType().ToList(), - new HashSet(collectionMethodCreator.RequiredUsings)); + return new BuilderMethods( + builderMethods.OfType().ToList(), + collectionMethodCreator.RequiredUsings); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/HashSetCreator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/HashSetCreator.cs index 2b1c110..aadd4f1 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/HashSetCreator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/HashSetCreator.cs @@ -11,11 +11,17 @@ internal HashSetCreator( MemberSymbolInfo symbolInfo) : base(collectionAttributeInfo, genericTypeArgument, symbolInfo) { + RequiredUsings.Add("System.Collections.Generic"); } protected override string CreateCollectionFromArray(string genericTypeArgument, string arrayParameter) { - return $"new HashSet<{genericTypeArgument}>({arrayParameter})"; + return CreateCollectionFromEnumerable(genericTypeArgument, arrayParameter); + } + + protected override string CreateCollectionFromEnumerable(string genericTypeArgument, string enumerableParameter) + { + return $"new HashSet<{genericTypeArgument}>({enumerableParameter})"; } protected override string CreateCollectionFromSingleItem(string genericTypeArgument, string itemParameter) @@ -27,6 +33,4 @@ protected override string CreateCollectionWithZeroItems(string genericTypeArgume { return $"new HashSet<{genericTypeArgument}>(0)"; } - - internal override IReadOnlyCollection RequiredUsings => new string[] { "System.Collections.Generic" }; } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/ListCreator.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/ListCreator.cs index 3dd4783..25651a6 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/ListCreator.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/Collections/ListCreator.cs @@ -11,11 +11,17 @@ internal ListCreator( MemberSymbolInfo symbolInfo) : base(collectionAttributeInfo, genericTypeArgument, symbolInfo) { + RequiredUsings.Add("System.Collections.Generic"); } protected override string CreateCollectionFromArray(string genericTypeArgument, string arrayParameter) { - return $"new List<{genericTypeArgument}>({arrayParameter})"; + return CreateCollectionFromEnumerable(genericTypeArgument, arrayParameter); + } + + protected override string CreateCollectionFromEnumerable(string genericTypeArgument, string enumerableParameter) + { + return $"new List<{genericTypeArgument}>({enumerableParameter})"; } protected override string CreateCollectionFromSingleItem(string genericTypeArgument, string itemParameter) @@ -27,6 +33,4 @@ protected override string CreateCollectionWithZeroItems(string genericTypeArgume { return $"new List<{genericTypeArgument}>(0)"; } - - internal override IReadOnlyCollection RequiredUsings => new string[] { "System.Collections.Generic" }; } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/CompoundMethods.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/CompoundMethods.cs index 61dd35b..146eb75 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/CompoundMethods.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/CompoundMethods.cs @@ -1,5 +1,6 @@ using M31.FluentApi.Generator.CodeBuilding; using M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.Commons; +using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; namespace M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.MethodCreation; @@ -16,18 +17,73 @@ internal CompoundMethods(string fluentMethodName, IReadOnlyCollection compoundMethods = new List(); + HashSet requiredUsings = new HashSet(); + + compoundMethods.Add(CreateStandardCompoundBuilderMethod(methodCreator)); + + BuilderMethod? lambdaCompoundBuilderMethod = TryCreateLambdaCompoundBuilderMethod(methodCreator); + if (lambdaCompoundBuilderMethod != null) + { + compoundMethods.Add(lambdaCompoundBuilderMethod); + requiredUsings.Add("System"); + } + + return new BuilderMethods(compoundMethods, requiredUsings); + } + + private BuilderMethod CreateStandardCompoundBuilderMethod(MethodCreator methodCreator) + { + List computeValues = new List(Parts.Count); + + foreach (CompoundPart compoundPart in Parts.OrderBy(p => p.AttributeInfo.ParameterPosition)) + { + computeValues.Add(GetStandardComputeValueCode(compoundPart)); + } + + return methodCreator.BuilderMethodFactory.CreateBuilderMethod(FluentMethodName, computeValues); + } + + private static ComputeValueCode GetStandardComputeValueCode( + CompoundPart compoundPart, + ReservedVariableNames? reservedParameterNames = null) + { + string parameterName = compoundPart.SymbolInfo.NameInCamelCase; + if (reservedParameterNames != null) + { + parameterName = reservedParameterNames.GetNewLocalVariableName(parameterName); + } + + Parameter parameter = + new Parameter(compoundPart.SymbolInfo.TypeForCodeGeneration, parameterName); + return ComputeValueCode.Create(compoundPart.SymbolInfo.Name, parameter); + } + + private BuilderMethod? TryCreateLambdaCompoundBuilderMethod(MethodCreator methodCreator) + { + if (Parts.All(p => p.AttributeInfo.LambdaBuilderInfo == null)) + { + return null; + } + + ReservedVariableNames reservedParameterNames = new ReservedVariableNames(); List computeValues = new List(Parts.Count); foreach (CompoundPart compoundPart in Parts.OrderBy(p => p.AttributeInfo.ParameterPosition)) { - Parameter parameter = - new Parameter(compoundPart.SymbolInfo.TypeForCodeGeneration, compoundPart.SymbolInfo.NameInCamelCase); - ComputeValueCode computeValueCode = ComputeValueCode.Create(compoundPart.SymbolInfo.Name, parameter); - computeValues.Add(computeValueCode); + if (compoundPart.AttributeInfo.LambdaBuilderInfo != null) + { + computeValues.Add(LambdaMethod.GetComputeValueCode( + compoundPart.SymbolInfo, + compoundPart.AttributeInfo.LambdaBuilderInfo, + reservedParameterNames)); + } + else + { + computeValues.Add(GetStandardComputeValueCode(compoundPart, reservedParameterNames)); + } } - BuilderMethod builderMethod = - methodCreator.BuilderMethodFactory.CreateBuilderMethod(FluentMethodName, computeValues); - return new BuilderMethods(builderMethod); + return methodCreator.BuilderMethodFactory.CreateBuilderMethod(FluentMethodName, computeValues); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/LambdaMethod.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/LambdaMethod.cs index 74f2f8e..3946116 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/LambdaMethod.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/LambdaMethod.cs @@ -1,6 +1,7 @@ using M31.FluentApi.Generator.CodeBuilding; using M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.Commons; using M31.FluentApi.Generator.CodeGeneration.CodeBoardElements; +using M31.FluentApi.Generator.Commons; using M31.FluentApi.Generator.SourceGenerators.AttributeInfo; namespace M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.MethodCreation; @@ -23,27 +24,79 @@ public BuilderMethods CreateBuilderMethods(MethodCreator methodCreator) BuilderMethod memberBuilderMethod = methodCreator.CreateMethod(SymbolInfo, LambdaAttributeInfo.FluentMethodName); - string builderType = LambdaAttributeInfo.BuilderInfo.BuilderTypeForCodeGeneration; - string builderInstanceName = LambdaAttributeInfo.BuilderInfo.BuilderInstanceName; - string initialStepInterfaceName = LambdaAttributeInfo.BuilderInfo.InitialStepInterfaceName; + BuilderMethod lambdaBuilderMethod = CreateLambdaBuilderMethod( + methodCreator, LambdaAttributeInfo.Method, SymbolInfo, LambdaAttributeInfo.BuilderInfo); + return new BuilderMethods( + new List() { memberBuilderMethod, lambdaBuilderMethod }, + new HashSet() { "System" }); + } + + internal static BuilderMethod CreateLambdaBuilderMethod( + MethodCreator methodCreator, + string methodName, + MemberSymbolInfo symbolInfo, + LambdaBuilderInfo lambdaBuilderInfo) + { + ComputeValueCode computeValueCode = GetComputeValueCode(symbolInfo, lambdaBuilderInfo); + return methodCreator.BuilderMethodFactory.CreateBuilderMethod(methodName, computeValueCode); + } + + internal static Parameter GetParameter( + string parameterType, + string parameterName, + LambdaBuilderInfo lambdaBuilderInfo, + ReservedVariableNames? reservedParameterNames = null) + { + string builderType = lambdaBuilderInfo.BuilderTypeForCodeGeneration; + string initialStepInterfaceName = lambdaBuilderInfo.InitialStepInterfaceName; + string fullParameterName = GetFullParameterName(parameterName); + + if (reservedParameterNames != null) + { + fullParameterName = reservedParameterNames.GetNewLocalVariableName(fullParameterName); + } + + // Func address + return new Parameter( + $"Func<{builderType}.{initialStepInterfaceName}, " + + $"{parameterType}>", + fullParameterName); + } + + internal static string GetFullParameterName(string parameterName) + { + return $"create{parameterName.FirstCharToUpper()}"; + } + + internal static ComputeValueCode GetComputeValueCode( + MemberSymbolInfo symbolInfo, + LambdaBuilderInfo lambdaBuilderInfo, + ReservedVariableNames? reservedParameterNames = null) + { + return GetComputeValueCode( + symbolInfo.TypeForCodeGeneration, + symbolInfo.NameInCamelCase, + symbolInfo.Name, + lambdaBuilderInfo, + reservedParameterNames); + } + + internal static ComputeValueCode GetComputeValueCode( + string parameterType, + string parameterName, + string targetMember, + LambdaBuilderInfo lambdaBuilderInfo, + ReservedVariableNames? reservedParameterNames = null) + { // createAddress(Func address) // { // student.Address = address(CreateAddress.InitialStep()); // } - Parameter parameter = - new Parameter( - $"Func<{builderType}.{initialStepInterfaceName}, " + - $"{SymbolInfo.TypeForCodeGeneration}>", - builderInstanceName); - BuilderMethod lambdaBuilderMethod = methodCreator.CreateMethodWithComputedValue( - SymbolInfo, - LambdaAttributeInfo.Method, - parameter, - p => $"{p}({builderType}.InitialStep())"); - - return new BuilderMethods( - new List() { memberBuilderMethod, lambdaBuilderMethod }, - new HashSet() { "System" }); + string builderType = lambdaBuilderInfo.BuilderTypeForCodeGeneration; + Parameter parameter = GetParameter( + parameterType, parameterName, lambdaBuilderInfo, reservedParameterNames); + string BuildCodeWithParameter(string p) => $"{p}({builderType}.InitialStep())"; + return ComputeValueCode.Create(targetMember, parameter, BuildCodeWithParameter); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/MemberMethod.cs b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/MemberMethod.cs index e96e8dd..c7644bd 100644 --- a/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/MemberMethod.cs +++ b/src/M31.FluentApi.Generator/CodeGeneration/CodeBoardActors/MethodCreation/MemberMethod.cs @@ -17,7 +17,20 @@ internal MemberMethod(MemberSymbolInfo symbolInfo, FluentMemberAttributeInfo mem public BuilderMethods CreateBuilderMethods(MethodCreator methodCreator) { + List builderMethods = new List(); + HashSet requiredUsings = new HashSet(); + BuilderMethod builderMethod = methodCreator.CreateMethod(SymbolInfo, MemberAttributeInfo.FluentMethodName); - return new BuilderMethods(builderMethod); + builderMethods.Add(builderMethod); + + if (MemberAttributeInfo.LambdaBuilderInfo != null) + { + BuilderMethod lambdaBuilderMethod = LambdaMethod.CreateLambdaBuilderMethod( + methodCreator, MemberAttributeInfo.Method, SymbolInfo, MemberAttributeInfo.LambdaBuilderInfo); + builderMethods.Add(lambdaBuilderMethod); + requiredUsings.Add("System"); + } + + return new BuilderMethods(builderMethods, requiredUsings); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj b/src/M31.FluentApi.Generator/M31.FluentApi.Generator.csproj index 13db9b1..fd5936a 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.6.0 + 1.7.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.Generator/SourceGenerators/AttributeInfo/FluentCollectionAttributeInfo.cs b/src/M31.FluentApi.Generator/SourceGenerators/AttributeInfo/FluentCollectionAttributeInfo.cs index 6b3c89d..a700399 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/AttributeInfo/FluentCollectionAttributeInfo.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/AttributeInfo/FluentCollectionAttributeInfo.cs @@ -11,7 +11,8 @@ private FluentCollectionAttributeInfo( string singularName, string withItems, string withItem, - string withZeroItems) + string withZeroItems, + LambdaBuilderInfo? lambdaBuilderInfo) : base(builderStep) { SingularName = singularName; @@ -19,6 +20,7 @@ private FluentCollectionAttributeInfo( WithItems = withItems; WithItem = withItem; WithZeroItems = withZeroItems; + LambdaBuilderInfo = lambdaBuilderInfo; } internal string SingularName { get; } @@ -26,9 +28,13 @@ private FluentCollectionAttributeInfo( internal string WithItems { get; } internal string WithItem { get; } internal string WithZeroItems { get; } + internal LambdaBuilderInfo? LambdaBuilderInfo { get; } internal override string FluentMethodName => WithItems; - internal static FluentCollectionAttributeInfo Create(AttributeData attributeData, string memberName) + internal static FluentCollectionAttributeInfo Create( + AttributeData attributeData, + string memberName, + LambdaBuilderInfo? lambdaBuilderInfo) { (int builderStep, string singularName, string withItems, string withItem, string withZeroItems) = attributeData.GetConstructorArguments(); @@ -37,6 +43,7 @@ internal static FluentCollectionAttributeInfo Create(AttributeData attributeData withItem = NameCreator.CreateName(withItem, memberName, singularName); withZeroItems = NameCreator.CreateName(withZeroItems, memberName, singularName); - return new FluentCollectionAttributeInfo(builderStep, singularName, withItems, withItem, withZeroItems); + return new FluentCollectionAttributeInfo( + builderStep, singularName, withItems, withItem, withZeroItems, lambdaBuilderInfo); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/SourceGenerators/AttributeInfo/FluentMemberAttributeInfo.cs b/src/M31.FluentApi.Generator/SourceGenerators/AttributeInfo/FluentMemberAttributeInfo.cs index 172be10..ac8bf61 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/AttributeInfo/FluentMemberAttributeInfo.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/AttributeInfo/FluentMemberAttributeInfo.cs @@ -5,21 +5,30 @@ namespace M31.FluentApi.Generator.SourceGenerators.AttributeInfo; internal record FluentMemberAttributeInfo : AttributeInfoBase { - private FluentMemberAttributeInfo(int builderStep, string method, int parameterPosition) + private FluentMemberAttributeInfo( + int builderStep, + string method, + int parameterPosition, + LambdaBuilderInfo? lambdaBuilderInfo) : base(builderStep) { Method = method; ParameterPosition = parameterPosition; + LambdaBuilderInfo = lambdaBuilderInfo; } internal string Method { get; } internal int ParameterPosition { get; } internal override string FluentMethodName => Method; + internal LambdaBuilderInfo? LambdaBuilderInfo { get; } - internal static FluentMemberAttributeInfo Create(AttributeData attributeData, string memberName) + internal static FluentMemberAttributeInfo Create( + AttributeData attributeData, + string memberName, + LambdaBuilderInfo? lambdaBuilderInfo) { (int builderStep, string method, int parameter) = attributeData.GetConstructorArguments(); method = NameCreator.CreateName(method, memberName); - return new FluentMemberAttributeInfo(builderStep, method, parameter); + return new FluentMemberAttributeInfo(builderStep, method, parameter, lambdaBuilderInfo); } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/SourceGenerators/Collections/CollectionInference.cs b/src/M31.FluentApi.Generator/SourceGenerators/Collections/CollectionInference.cs index 831064e..5b875de 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/Collections/CollectionInference.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/Collections/CollectionInference.cs @@ -33,7 +33,10 @@ internal class CollectionInference { if (typeSymbol is IArrayTypeSymbol arrayTypeSymbol) { - return new CollectionType(GeneratedCollection.Array, GetTypeForCodeGeneration(arrayTypeSymbol.ElementType)); + return new CollectionType( + GeneratedCollection.Array, + GetTypeForCodeGeneration(arrayTypeSymbol.ElementType), + arrayTypeSymbol.ElementType); } if (typeSymbol is INamedTypeSymbol { IsGenericType: true, TypeArguments.Length: 1 } genericNamedTypeSymbol) @@ -47,7 +50,7 @@ internal class CollectionInference return null; } - return new CollectionType(collection, genericTypeArgument); + return new CollectionType(collection, genericTypeArgument, genericArgument); } if (typeSymbol is INamedTypeSymbol { IsGenericType: false } nonGenericNamedTypeSymbol) @@ -59,7 +62,7 @@ internal class CollectionInference return null; } - return new CollectionType(collection, "object"); + return new CollectionType(collection, "object", null); } return null; diff --git a/src/M31.FluentApi.Generator/SourceGenerators/Collections/CollectionType.cs b/src/M31.FluentApi.Generator/SourceGenerators/Collections/CollectionType.cs index 14a1a70..0c9860a 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/Collections/CollectionType.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/Collections/CollectionType.cs @@ -1,15 +1,38 @@ using M31.FluentApi.Generator.CodeGeneration.CodeBoardActors.MethodCreation.Collections; +using M31.FluentApi.Generator.Commons; +using Microsoft.CodeAnalysis; namespace M31.FluentApi.Generator.SourceGenerators.Collections; -internal record CollectionType +internal class CollectionType { - internal CollectionType(GeneratedCollection collection, string genericTypeArgument) + internal CollectionType(GeneratedCollection collection, string genericTypeArgument, ITypeSymbol? genericTypeSymbol) { - this.Collection = collection; - this.GenericTypeArgument = genericTypeArgument; + Collection = collection; + GenericTypeArgument = genericTypeArgument; + GenericTypeSymbol = genericTypeSymbol; } internal GeneratedCollection Collection { get; } internal string GenericTypeArgument { get; } + internal ITypeSymbol? GenericTypeSymbol { get; } + + protected bool Equals(CollectionType other) + { + // Exclude GenericTypeSymbol from the comparison, it is unstable additional information. + return Collection == other.Collection && GenericTypeArgument == other.GenericTypeArgument; + } + + 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((CollectionType)obj); + } + + public override int GetHashCode() + { + return new HashCode().Add(Collection, GenericTypeArgument); + } } \ No newline at end of file diff --git a/src/M31.FluentApi.Generator/SourceGenerators/FluentApiInfoCreator.cs b/src/M31.FluentApi.Generator/SourceGenerators/FluentApiInfoCreator.cs index f7a225f..884c5b1 100644 --- a/src/M31.FluentApi.Generator/SourceGenerators/FluentApiInfoCreator.cs +++ b/src/M31.FluentApi.Generator/SourceGenerators/FluentApiInfoCreator.cs @@ -19,8 +19,8 @@ internal FluentApiInfoCreator(ClassInfoReport classInfoReport) internal FluentApiInfo? Create(ISymbol symbol, FluentApiAttributeData attributeData) { - AttributeInfoBase? attributeInfo = - CreateAttributeInfo(attributeData.MainAttributeData, symbol); + FluentApiSymbolInfo symbolInfo = SymbolInfoCreator.Create(symbol); + AttributeInfoBase? attributeInfo = CreateAttributeInfo(attributeData.MainAttributeData, symbol, symbolInfo); if (attributeInfo == null) { @@ -40,7 +40,6 @@ internal FluentApiInfoCreator(ClassInfoReport classInfoReport) FluentReturnAttributeInfo? fluentReturnAttributeInfo = controlDataAndInfos.Select(d => d.info) .OfType().FirstOrDefault(); - FluentApiSymbolInfo symbolInfo = SymbolInfoCreator.Create(symbol); FluentApiAdditionalInfo additionalInfo = new FluentApiAdditionalInfo( symbol, attributeData.MainAttributeData, @@ -68,18 +67,21 @@ private static List ToInfos( return dataAndInfoArray.Select(dataAndInfo => dataAndInfo.info).ToList(); } - private AttributeInfoBase? CreateAttributeInfo(AttributeDataExtended attributeData, ISymbol symbol) + private AttributeInfoBase? CreateAttributeInfo( + AttributeDataExtended attributeData, + ISymbol symbol, + FluentApiSymbolInfo symbolInfo) { string memberName = symbol.Name; return attributeData.FullName switch { FullNames.FluentMemberAttribute => - FluentMemberAttributeInfo.Create(attributeData.AttributeData, memberName), + CreateFluentMemberAttributeInfo(attributeData.AttributeData, memberName, symbol), FullNames.FluentPredicateAttribute => FluentPredicateAttributeInfo.Create(attributeData.AttributeData, memberName), FullNames.FluentCollectionAttribute => - FluentCollectionAttributeInfo.Create(attributeData.AttributeData, memberName), + CreateFluentCollectionAttributeInfo(attributeData.AttributeData, memberName, symbolInfo), FullNames.FluentLambdaAttribute => CreateFluentLambdaAttributeInfo(attributeData, memberName, symbol), FullNames.FluentMethodAttribute => @@ -118,34 +120,63 @@ private static ControlAttributeInfoBase CreateControlAttributeInfo(AttributeData }; } + private FluentMemberAttributeInfo CreateFluentMemberAttributeInfo( + AttributeData attributeData, + string memberName, + ISymbol symbol) + { + ITypeSymbol typeSymbol = GetTypeSymbol(symbol); + LambdaBuilderInfo? lambdaBuilderInfo = TryGetLambdaBuilderInfo(typeSymbol); + return FluentMemberAttributeInfo.Create(attributeData, memberName, lambdaBuilderInfo); + } + + private FluentCollectionAttributeInfo CreateFluentCollectionAttributeInfo( + AttributeData attributeData, + string memberName, + FluentApiSymbolInfo symbolInfo) + { + LambdaBuilderInfo? lambdaBuilderInfo = TryGetLambdaBuilderInfoOfCollectionType(symbolInfo); + return FluentCollectionAttributeInfo.Create(attributeData, memberName, lambdaBuilderInfo); + } + + private LambdaBuilderInfo? TryGetLambdaBuilderInfoOfCollectionType(FluentApiSymbolInfo symbolInfo) + { + if (symbolInfo is not MemberSymbolInfo memberSymbolInfo || + memberSymbolInfo.CollectionType?.GenericTypeSymbol == null) + { + return null; + } + + return TryGetLambdaBuilderInfo(memberSymbolInfo.CollectionType.GenericTypeSymbol); + } + private FluentLambdaAttributeInfo? CreateFluentLambdaAttributeInfo( AttributeDataExtended attributeDataExtended, string memberName, ISymbol symbol) { - LambdaBuilderInfo? lambdaBuilderInfo = GetLambdaBuilderInfo(attributeDataExtended, symbol); + ITypeSymbol typeSymbol = GetTypeSymbol(symbol); + LambdaBuilderInfo? lambdaBuilderInfo = TryGetLambdaBuilderInfo(typeSymbol); + + if (lambdaBuilderInfo == null) + { + classInfoReport.ReportDiagnostic( + FluentLambdaMemberWithoutFluentApi.CreateDiagnostic(attributeDataExtended, typeSymbol.Name)); + } + return lambdaBuilderInfo == null ? null : FluentLambdaAttributeInfo.Create(attributeDataExtended.AttributeData, memberName, lambdaBuilderInfo); } - private LambdaBuilderInfo? GetLambdaBuilderInfo(AttributeDataExtended attributeDataExtended, ISymbol symbol) + private LambdaBuilderInfo? TryGetLambdaBuilderInfo(ITypeSymbol type) { - ITypeSymbol type = symbol switch - { - IPropertySymbol propertySymbol => propertySymbol.Type, - IFieldSymbol fieldSymbol => fieldSymbol.Type, - _ => throw new GenerationException($"Unexpected symbol type: {symbol.GetType().Name}") - }; - AttributeDataExtended[] fluentApiAttributes = type.GetAttributes().Select(AttributeDataExtended.Create) .OfType().Where(a => a.FullName == FullNames.FluentApiAttribute) .ToArray(); if (fluentApiAttributes.Length == 0) { - classInfoReport.ReportDiagnostic( - FluentLambdaMemberWithoutFluentApi.CreateDiagnostic(attributeDataExtended, type.Name)); return null; } @@ -169,4 +200,14 @@ private static string GetBuilderTypeForCodeGeneration( string[] split = fluentApiTypeForCodeGeneration.Split('.'); return string.Join(".", split.Take(split.Length - 1).Concat(new string[] { builderClassName })); } + + private static ITypeSymbol GetTypeSymbol(ISymbol symbol) + { + return symbol switch + { + IPropertySymbol propertySymbol => propertySymbol.Type, + IFieldSymbol fieldSymbol => fieldSymbol.Type, + _ => throw new GenerationException($"Unexpected symbol type: {symbol.GetType().Name}") + }; + } } \ No newline at end of file diff --git a/src/M31.FluentApi.Storybook/01_Basics.cs b/src/M31.FluentApi.Storybook/01_Basics.cs index eef17dc..e5ad1f2 100644 --- a/src/M31.FluentApi.Storybook/01_Basics.cs +++ b/src/M31.FluentApi.Storybook/01_Basics.cs @@ -308,14 +308,16 @@ public static void UseTheGeneratedFluentApi() } } -namespace FluentLambdaExample +namespace NestedFluentApis { - /* Last but not least, I would like to introduce the FluentLambda attribute. It can be applied to fields and - properties whose types have their own Fluent API. The FluentLambda attribute results in an additional builder - method that accepts a lambda expression to create the decorated member. + /* Lastly, I would like to demonstrate the effect of applying the FluentMember attribute to a member whose type has + its own Fluent API. In this scenario, an additional builder method that accepts a lambda expression is generated. In the example below, the Student class has an Address property, and the Address class has its own Fluent API. The advantage of the lambda method is that the user does not have to figure out the builder name of the Address - class when creating a student, as shown in the usage examples below. + class when creating a student. + Similarly, additional lambda methods are generated if the FluentCollection attribute is applied to a collection + whose element type has its own Fluent API. The employee class below is modeled with several addresses that can be + conveniently set using lambda methods. In the next chapter, you will learn how to create non-linear paths with control attributes. @@ -331,10 +333,23 @@ public class Student [FluentMember(0, "Named", 1)] public string LastName { get; private set; } - [FluentLambda(1)] + [FluentMember(1)] public Address Address { get; private set; } } + [FluentApi] + public class Employee + { + [FluentMember(0, "Named", 0)] + public string FirstName { get; private set; } + + [FluentMember(0, "Named", 1)] + public string LastName { get; private set; } + + [FluentCollection(1, "Address")] + public IReadOnlyCollection
Addresses { get; private set; } + } + [FluentApi] public class Address { @@ -364,13 +379,21 @@ public static class Usage public static void UseTheGeneratedFluentApi() { Student student1 = CreateStudent.Named("Alice", "King") - .WithAddress(new Address("111", "5th Avenue", "New York")); + .WithAddress(new Address("108", "5th Avenue", "New York")); Student student2 = CreateStudent.Named("Bob", "Bishop") .WithAddress(CreateAddress.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); Student student3 = CreateStudent.Named("Eve", "Knight") .WithAddress(a => a.WithHouseNumber("82").WithStreet("Friedrichstraße").InCity("Berlin")); + + Employee employee1 = CreateEmployee.Named("Alice", "King") + .WithAddresses( + a => a.WithHouseNumber("108").WithStreet("5th Avenue").InCity("New York"), + a => a.WithHouseNumber("42").WithStreet("Maple Ave").InCity("Boston")); + + Employee employee2 = CreateEmployee.Named("Eve", "Knight") + .WithAddress(a => a.WithHouseNumber("82").WithStreet("Friedrichstraße").InCity("Berlin")); } } } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/AnalyzerAndCodeFixTests.cs b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/AnalyzerAndCodeFixTests.cs index 79c7b25..9f341b9 100644 --- a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/AnalyzerAndCodeFixTests.cs +++ b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/AnalyzerAndCodeFixTests.cs @@ -60,7 +60,7 @@ public async Task CanDetectFluentLambdaMemberWithoutFluentApiClass() SourceWithFix source = ReadSource("FluentLambdaMemberWithoutFluentApiClass", "Student"); var expectedDiagnostic = Verifier.Diagnostic(FluentLambdaMemberWithoutFluentApi.Descriptor.Id) - .WithLocation(15, 6) + .WithLocation(17, 6) .WithArguments("Address"); await Verifier.VerifyCodeFixAsync(source, expectedDiagnostic); diff --git a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/TestClasses/FluentLambdaMemberWithoutFluentApiClass/Student.cs b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/TestClasses/FluentLambdaMemberWithoutFluentApiClass/Student.cs index f28d376..a2b0dc5 100644 --- a/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/TestClasses/FluentLambdaMemberWithoutFluentApiClass/Student.cs +++ b/src/M31.FluentApi.Tests/AnalyzerAndCodeFixes/TestClasses/FluentLambdaMemberWithoutFluentApiClass/Student.cs @@ -1,5 +1,7 @@ // Non-nullable member is uninitialized #pragma warning disable CS8618 +// Type or member is obsolete +#pragma warning disable CS0618 // ReSharper disable All using M31.FluentApi.Attributes; diff --git a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs index 2626c0c..158538b 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/CodeGenerationExecutionTests.cs @@ -16,30 +16,33 @@ public partial class CodeGenerationTests [Fact, Priority(1)] public void CanExecuteContinueWithInForkClass() { - var student1 = TestClasses.Abstract.ContinueWithInForkClass - .CreateStudent - .WithMember1("1") - .WithMember2A("2A") - .WithMember3("3") - .WithMember4("4"); - - var student2 = TestClasses.Abstract.ContinueWithInForkClass - .CreateStudent - .WithMember1("1") - .WithMember2B("2B") - .WithMember4("4"); - - Assert.Equal("1", student1.Member1); - Assert.Equal("2A", student1.Member2A); - Assert.Null(student1.Member2B); - Assert.Equal("3", student1.Member3); - Assert.Equal("4", student1.Member4); - - Assert.Equal("1", student2.Member1); - Assert.Null(student2.Member2A); - Assert.Equal("2B", student2.Member2B); - Assert.Null(student2.Member3); - Assert.Equal("4", student2.Member4); + { + 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)] @@ -57,33 +60,161 @@ public void CanExecuteFluentLambdaClass() } [Fact, Priority(1)] - public void CanExecuteFluentLambdaNullablePropertyClass() + public void CanExecuteFluentLambdaCollectionClass() { - var student1 = TestClasses.Abstract.FluentLambdaNullablePropertyClass + var student = TestClasses.Abstract.FluentLambdaCollectionClass .CreateStudent .WithName("Alice") - .WithAddress(a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco")); + .WithAddresses( + a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), + a => a.WithHouseNumber("108").WithStreet("5th Avenue").InCity("New York")); - Assert.Equal("Alice", student1.Name); - Assert.Equal("23", student1.Address!.HouseNumber); - Assert.Equal("Market Street", student1.Address!.Street); - Assert.Equal("San Francisco", student1.Address!.City); + 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); + } - var student2 = TestClasses.Abstract.FluentLambdaNullablePropertyClass + [Fact, Priority(1)] + public void CanExecuteFluentLambdaCompoundClass() + { + var student = TestClasses.Abstract.FluentLambdaCompoundClass .CreateStudent .WithName("Alice") - .WithoutAddress(); + .WithDetails( + a => a.WithHouseNumber("23").WithStreet("Market Street").InCity("San Francisco"), + p => p.WithNumber("222-222-2222").WithUsage("CELL")); - Assert.Equal("Alice", student2.Name); - Assert.Null(student2.Address); + 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); + } - var student3 = TestClasses.Abstract.FluentLambdaNullablePropertyClass - .CreateStudent - .WithName("Alice") - .WithAddress(_ => null); + [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]); + } + } - Assert.Equal("Alice", student3.Name); - Assert.Null(student3.Address); + [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)] @@ -133,43 +264,51 @@ public void CanExecuteFluentMethodClass() [Fact, Priority(1)] public void CanExecuteFluentReturnMultiStepPrivateMethodsClass() { - string string1 = "string1"; - - TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnVoidMethod(); - - int result1 = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnIntMethod(); - Assert.Equal(24, result1); - - int result2 = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnIntMethodWithRefParameter(ref string1); - Assert.Equal(28, result2); - - List result3 = TestClasses.Abstract.FluentReturnMultiStepPrivateMethodsClass - .CreateStudent.WithName("Alice").ReturnListMethod(); - Assert.Equal(new List() { 1, 2, 3 }, result3); + { + 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() { - string string1 = "string1"; - - TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnVoidMethod(); - - int result1 = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnIntMethod(); - Assert.Equal(24, result1); - - int result2 = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnIntMethodWithRefParameter(ref string1); - Assert.Equal(28, result2); - - List result3 = TestClasses.Abstract.FluentReturnSingleStepPrivateMethodsClass - .CreateStudent.ReturnListMethod(); - Assert.Equal(new List() { 1, 2, 3 }, result3); + { + 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)] @@ -213,73 +352,89 @@ public void CanExecuteGenericClassWithPrivateGenericMethods() [Fact, Priority(1)] public void CanExecuteGenericOverloadedMethodClass() { - string string1 = "string1"; - string string2 = "string2"; - int int0 = 0; - - var student1 = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student1.Logs); - - var student2 = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student2.Logs); - - var student3 = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1("string1", "string2"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student3.Logs); - - var student4 = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student4.Logs); - - var student5 = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(0, out string1); - Assert.Equal(new string[] { "Called Method1(T, out string)" }, student5.Logs); - - var student6 = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(in int0, "string1"); - Assert.Equal(new string[] { "Called Method1(in T, string)" }, student6.Logs); - - var student7 = TestClasses.Abstract.GenericOverloadedMethodClass - .CreateStudent.Method1(in int0, ref string2); - Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student7.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(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() { - string string1 = "string1"; - string string2 = "string2"; - int int0 = 0; - - var student1 = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student1.Logs); - - var student2 = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(int, string)" }, student2.Logs); - - var student3 = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1("string1", "string2"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student3.Logs); - - var student4 = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, "string1"); - Assert.Equal(new string[] { "Called Method1(T, string)" }, student4.Logs); - - var student5 = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(0, out string1); - Assert.Equal(new string[] { "Called Method1(T, out string)" }, student5.Logs); - - var student6 = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(in int0, "string1"); - Assert.Equal(new string[] { "Called Method1(in T, string)" }, student6.Logs); - - var student7 = TestClasses.Abstract.GenericOverloadedPrivateMethodClass - .CreateStudent.Method1(in int0, ref string2); - Assert.Equal(new string[] { "Called Method1(in T, ref string)" }, student7.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(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)] @@ -355,43 +510,49 @@ public void CanExecutePublicReadonlyFieldClass() [Fact, Priority(1)] public void CanExecuteSkippableMemberClass() { - var student1 = TestClasses.Abstract.SkippableMemberClass - .CreateStudent - .WithFirstName("Alice") - .WithMiddleName("Sophia") - .WithLastName("King"); - - Assert.Equal("Alice", student1.FirstName); - Assert.Equal("Sophia", student1.MiddleName); - Assert.Equal("King", student1.LastName); - - var student2 = TestClasses.Abstract.SkippableMemberClass - .CreateStudent - .WithFirstName("Alice") - .WithLastName("King"); - - Assert.Equal("Alice", student2.FirstName); - Assert.Null(student2.MiddleName); - Assert.Equal("King", student2.LastName); + { + 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 student1 = TestClasses.Abstract.SkippableFirstMemberClass - .CreateStudent - .WithFirstName("Alice") - .WithLastName("King"); - - Assert.Equal("Alice", student1.FirstName); - Assert.Equal("King", student1.LastName); - - var student2 = TestClasses.Abstract.SkippableFirstMemberClass - .CreateStudent - .WithLastName("King"); - - Assert.Null(student2.FirstName); - Assert.Equal("King", student2.LastName); + { + 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)] @@ -412,24 +573,27 @@ public void CanExecuteSkippableLoopClass() [Fact, Priority(1)] public void CanExecuteSkippableSeveralMembersClass() { - var student1 = TestClasses.Abstract.SkippableSeveralMembersClass - .CreateStudent - .WithMember2("2") - .WithMember4("4"); - - Assert.Null(student1.Member1); - Assert.Equal("2", student1.Member2); - Assert.Null(student1.Member3); - Assert.Equal("4", student1.Member4); - - var student2 = TestClasses.Abstract.SkippableSeveralMembersClass - .CreateStudent - .WithMember4("4"); - - Assert.Null(student2.Member1); - Assert.Null(student2.Member2); - Assert.Null(student2.Member3); - Assert.Equal("4", student2.Member4); + { + 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)] diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClass/Student.cs index 05c4798..cff61f8 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClass/Student.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClass/Student.cs @@ -12,6 +12,6 @@ public class Student [FluentMember(0)] public string Name { get; set; } - [FluentLambda(1)] + [FluentMember(1)] public Address Address { get; set; } } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClassInDifferentNamespace/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClassInDifferentNamespace/Student.cs index c9f93ab..ef14a33 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClassInDifferentNamespace/Student.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaClassInDifferentNamespace/Student.cs @@ -13,6 +13,6 @@ public class Student [FluentMember(0)] public string Name { get; set; } - [FluentLambda(1)] + [FluentMember(1)] public Address Address { get; set; } } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/Address.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/Address.cs new file mode 100644 index 0000000..3cad9d2 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/Address.cs @@ -0,0 +1,20 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass; + +[FluentApi] +public class Address +{ + [FluentMember(0)] + public string HouseNumber { get; set; } + + [FluentMember(1)] + public string Street { get; set; } + + [FluentMember(2, "InCity")] + public string City { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateAddress.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateAddress.g.cs new file mode 100644 index 0000000..4f89690 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateAddress.g.cs @@ -0,0 +1,73 @@ +// +// 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 M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass; + +public class CreateAddress : + CreateAddress.ICreateAddress, + CreateAddress.IWithHouseNumber, + CreateAddress.IWithStreet, + CreateAddress.IInCity +{ + private readonly Address address; + + private CreateAddress() + { + address = new Address(); + } + + public static ICreateAddress InitialStep() + { + return new CreateAddress(); + } + + public static IWithStreet WithHouseNumber(string houseNumber) + { + CreateAddress createAddress = new CreateAddress(); + createAddress.address.HouseNumber = houseNumber; + return createAddress; + } + + IWithStreet IWithHouseNumber.WithHouseNumber(string houseNumber) + { + address.HouseNumber = houseNumber; + return this; + } + + IInCity IWithStreet.WithStreet(string street) + { + address.Street = street; + return this; + } + + Address IInCity.InCity(string city) + { + address.City = city; + return address; + } + + public interface ICreateAddress : IWithHouseNumber + { + } + + public interface IWithHouseNumber + { + IWithStreet WithHouseNumber(string houseNumber); + } + + public interface IWithStreet + { + IInCity WithStreet(string street); + } + + public interface IInCity + { + Address InCity(string city); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateStudent.expected.txt new file mode 100644 index 0000000..35431ed --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateStudent.expected.txt @@ -0,0 +1,104 @@ +// +// 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.Collections.Generic; +using M31.FluentApi.Attributes; +using System; +using System.Linq; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithName, + CreateStudent.IWithAddresses +{ + private readonly Student student; + + private CreateStudent() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithAddresses WithName(string name) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Name = name; + return createStudent; + } + + IWithAddresses IWithName.WithName(string name) + { + student.Name = name; + return this; + } + + Student IWithAddresses.WithAddresses(System.Collections.Generic.List addresses) + { + student.Addresses = addresses; + return student; + } + + Student IWithAddresses.WithAddresses(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.Address[] addresses) + { + student.Addresses = new List(addresses); + return student; + } + + Student IWithAddresses.WithAddresses(params Func[] createAddresses) + { + student.Addresses = new List(createAddresses.Select(createAddress => createAddress(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.CreateAddress.InitialStep()))); + return student; + } + + Student IWithAddresses.WithAddress(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.Address address) + { + student.Addresses = new List(1){ address }; + return student; + } + + Student IWithAddresses.WithAddress(Func createAddress) + { + student.Addresses = new List(1){ createAddress(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddresses.WithZeroAddresses() + { + student.Addresses = new List(0); + return student; + } + + public interface ICreateStudent : IWithName + { + } + + public interface IWithName + { + IWithAddresses WithName(string name); + } + + public interface IWithAddresses + { + Student WithAddresses(System.Collections.Generic.List addresses); + + Student WithAddresses(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.Address[] addresses); + + Student WithAddresses(params Func[] createAddresses); + + Student WithAddress(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.Address address); + + Student WithAddress(Func createAddress); + + Student WithZeroAddresses(); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateStudent.g.cs new file mode 100644 index 0000000..35431ed --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/CreateStudent.g.cs @@ -0,0 +1,104 @@ +// +// 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.Collections.Generic; +using M31.FluentApi.Attributes; +using System; +using System.Linq; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithName, + CreateStudent.IWithAddresses +{ + private readonly Student student; + + private CreateStudent() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithAddresses WithName(string name) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Name = name; + return createStudent; + } + + IWithAddresses IWithName.WithName(string name) + { + student.Name = name; + return this; + } + + Student IWithAddresses.WithAddresses(System.Collections.Generic.List addresses) + { + student.Addresses = addresses; + return student; + } + + Student IWithAddresses.WithAddresses(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.Address[] addresses) + { + student.Addresses = new List(addresses); + return student; + } + + Student IWithAddresses.WithAddresses(params Func[] createAddresses) + { + student.Addresses = new List(createAddresses.Select(createAddress => createAddress(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.CreateAddress.InitialStep()))); + return student; + } + + Student IWithAddresses.WithAddress(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.Address address) + { + student.Addresses = new List(1){ address }; + return student; + } + + Student IWithAddresses.WithAddress(Func createAddress) + { + student.Addresses = new List(1){ createAddress(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddresses.WithZeroAddresses() + { + student.Addresses = new List(0); + return student; + } + + public interface ICreateStudent : IWithName + { + } + + public interface IWithName + { + IWithAddresses WithName(string name); + } + + public interface IWithAddresses + { + Student WithAddresses(System.Collections.Generic.List addresses); + + Student WithAddresses(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.Address[] addresses); + + Student WithAddresses(params Func[] createAddresses); + + Student WithAddress(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass.Address address); + + Student WithAddress(Func createAddress); + + Student WithZeroAddresses(); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/Student.cs new file mode 100644 index 0000000..5231682 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCollectionClass/Student.cs @@ -0,0 +1,18 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using System.Collections.Generic; +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCollectionClass; + +[FluentApi] +public class Student +{ + [FluentMember(0)] + public string Name { get; set; } + + [FluentCollection(1, "Address")] + public List
Addresses { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Address.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Address.cs new file mode 100644 index 0000000..805672e --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Address.cs @@ -0,0 +1,20 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass; + +[FluentApi] +public class Address +{ + [FluentMember(0)] + public string HouseNumber { get; set; } + + [FluentMember(1)] + public string Street { get; set; } + + [FluentMember(2, "InCity")] + public string City { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateAddress.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateAddress.g.cs new file mode 100644 index 0000000..b909212 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateAddress.g.cs @@ -0,0 +1,73 @@ +// +// 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 M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass; + +public class CreateAddress : + CreateAddress.ICreateAddress, + CreateAddress.IWithHouseNumber, + CreateAddress.IWithStreet, + CreateAddress.IInCity +{ + private readonly Address address; + + private CreateAddress() + { + address = new Address(); + } + + public static ICreateAddress InitialStep() + { + return new CreateAddress(); + } + + public static IWithStreet WithHouseNumber(string houseNumber) + { + CreateAddress createAddress = new CreateAddress(); + createAddress.address.HouseNumber = houseNumber; + return createAddress; + } + + IWithStreet IWithHouseNumber.WithHouseNumber(string houseNumber) + { + address.HouseNumber = houseNumber; + return this; + } + + IInCity IWithStreet.WithStreet(string street) + { + address.Street = street; + return this; + } + + Address IInCity.InCity(string city) + { + address.City = city; + return address; + } + + public interface ICreateAddress : IWithHouseNumber + { + } + + public interface IWithHouseNumber + { + IWithStreet WithHouseNumber(string houseNumber); + } + + public interface IWithStreet + { + IInCity WithStreet(string street); + } + + public interface IInCity + { + Address InCity(string city); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreatePhone.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreatePhone.g.cs new file mode 100644 index 0000000..6ee3c40 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreatePhone.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 + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass; + +public class CreatePhone : + CreatePhone.ICreatePhone, + CreatePhone.IWithNumber, + CreatePhone.IWithUsage +{ + private readonly Phone phone; + + private CreatePhone() + { + phone = new Phone(); + } + + public static ICreatePhone InitialStep() + { + return new CreatePhone(); + } + + public static IWithUsage WithNumber(string number) + { + CreatePhone createPhone = new CreatePhone(); + createPhone.phone.Number = number; + return createPhone; + } + + IWithUsage IWithNumber.WithNumber(string number) + { + phone.Number = number; + return this; + } + + Phone IWithUsage.WithUsage(string usage) + { + phone.Usage = usage; + return phone; + } + + public interface ICreatePhone : IWithNumber + { + } + + public interface IWithNumber + { + IWithUsage WithNumber(string number); + } + + public interface IWithUsage + { + Phone WithUsage(string usage); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateStudent.expected.txt new file mode 100644 index 0000000..acb10c5 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateStudent.expected.txt @@ -0,0 +1,72 @@ +// +// 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 M31.FluentApi.Attributes; +using System; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithName, + CreateStudent.IWithDetails +{ + private readonly Student student; + + private CreateStudent() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithDetails WithName(string name) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Name = name; + return createStudent; + } + + IWithDetails IWithName.WithName(string name) + { + student.Name = name; + return this; + } + + Student IWithDetails.WithDetails(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.Address address, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.Phone phone) + { + student.Address = address; + student.Phone = phone; + return student; + } + + Student IWithDetails.WithDetails(Func createAddress, Func createPhone) + { + student.Address = createAddress(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.CreateAddress.InitialStep()); + student.Phone = createPhone(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.CreatePhone.InitialStep()); + return student; + } + + public interface ICreateStudent : IWithName + { + } + + public interface IWithName + { + IWithDetails WithName(string name); + } + + public interface IWithDetails + { + Student WithDetails(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.Address address, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.Phone phone); + + Student WithDetails(Func createAddress, Func createPhone); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateStudent.g.cs new file mode 100644 index 0000000..acb10c5 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/CreateStudent.g.cs @@ -0,0 +1,72 @@ +// +// 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 M31.FluentApi.Attributes; +using System; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithName, + CreateStudent.IWithDetails +{ + private readonly Student student; + + private CreateStudent() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithDetails WithName(string name) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Name = name; + return createStudent; + } + + IWithDetails IWithName.WithName(string name) + { + student.Name = name; + return this; + } + + Student IWithDetails.WithDetails(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.Address address, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.Phone phone) + { + student.Address = address; + student.Phone = phone; + return student; + } + + Student IWithDetails.WithDetails(Func createAddress, Func createPhone) + { + student.Address = createAddress(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.CreateAddress.InitialStep()); + student.Phone = createPhone(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.CreatePhone.InitialStep()); + return student; + } + + public interface ICreateStudent : IWithName + { + } + + public interface IWithName + { + IWithDetails WithName(string name); + } + + public interface IWithDetails + { + Student WithDetails(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.Address address, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass.Phone phone); + + Student WithDetails(Func createAddress, Func createPhone); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Phone.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Phone.cs new file mode 100644 index 0000000..95fcd7e --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Phone.cs @@ -0,0 +1,17 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass; + +[FluentApi] +public class Phone +{ + [FluentMember(0)] + public string Number { get; set; } + + [FluentMember(1)] + public string Usage { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Student.cs new file mode 100644 index 0000000..f1d9ab1 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundClass/Student.cs @@ -0,0 +1,20 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundClass; + +[FluentApi] +public class Student +{ + [FluentMember(0)] + public string Name { get; set; } + + [FluentMember(1, "WithDetails")] + public Address Address { get; set; } + + [FluentMember(1, "WithDetails")] + public Phone Phone { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/Address.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/Address.cs new file mode 100644 index 0000000..606f0c3 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/Address.cs @@ -0,0 +1,20 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass; + +[FluentApi] +public class Address +{ + [FluentMember(0)] + public string HouseNumber { get; set; } + + [FluentMember(1)] + public string Street { get; set; } + + [FluentMember(2, "InCity")] + public string City { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateAddress.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateAddress.g.cs new file mode 100644 index 0000000..70febaa --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateAddress.g.cs @@ -0,0 +1,73 @@ +// +// 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 M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass; + +public class CreateAddress : + CreateAddress.ICreateAddress, + CreateAddress.IWithHouseNumber, + CreateAddress.IWithStreet, + CreateAddress.IInCity +{ + private readonly Address address; + + private CreateAddress() + { + address = new Address(); + } + + public static ICreateAddress InitialStep() + { + return new CreateAddress(); + } + + public static IWithStreet WithHouseNumber(string houseNumber) + { + CreateAddress createAddress = new CreateAddress(); + createAddress.address.HouseNumber = houseNumber; + return createAddress; + } + + IWithStreet IWithHouseNumber.WithHouseNumber(string houseNumber) + { + address.HouseNumber = houseNumber; + return this; + } + + IInCity IWithStreet.WithStreet(string street) + { + address.Street = street; + return this; + } + + Address IInCity.InCity(string city) + { + address.City = city; + return address; + } + + public interface ICreateAddress : IWithHouseNumber + { + } + + public interface IWithHouseNumber + { + IWithStreet WithHouseNumber(string houseNumber); + } + + public interface IWithStreet + { + IInCity WithStreet(string street); + } + + public interface IInCity + { + Address InCity(string city); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateStudent.expected.txt new file mode 100644 index 0000000..10904f4 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateStudent.expected.txt @@ -0,0 +1,72 @@ +// +// 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 M31.FluentApi.Attributes; +using System; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithName, + CreateStudent.IWithDetails +{ + private readonly Student student; + + private CreateStudent() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithDetails WithName(string name) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Name = name; + return createStudent; + } + + IWithDetails IWithName.WithName(string name) + { + student.Name = name; + return this; + } + + Student IWithDetails.WithDetails(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.Address address1, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.Address address2) + { + student.Address1 = address1; + student.Address2 = address2; + return student; + } + + Student IWithDetails.WithDetails(Func createAddress1, Func createAddress2) + { + student.Address1 = createAddress1(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.CreateAddress.InitialStep()); + student.Address2 = createAddress2(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.CreateAddress.InitialStep()); + return student; + } + + public interface ICreateStudent : IWithName + { + } + + public interface IWithName + { + IWithDetails WithName(string name); + } + + public interface IWithDetails + { + Student WithDetails(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.Address address1, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.Address address2); + + Student WithDetails(Func createAddress1, Func createAddress2); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateStudent.g.cs new file mode 100644 index 0000000..10904f4 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/CreateStudent.g.cs @@ -0,0 +1,72 @@ +// +// 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 M31.FluentApi.Attributes; +using System; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithName, + CreateStudent.IWithDetails +{ + private readonly Student student; + + private CreateStudent() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithDetails WithName(string name) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Name = name; + return createStudent; + } + + IWithDetails IWithName.WithName(string name) + { + student.Name = name; + return this; + } + + Student IWithDetails.WithDetails(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.Address address1, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.Address address2) + { + student.Address1 = address1; + student.Address2 = address2; + return student; + } + + Student IWithDetails.WithDetails(Func createAddress1, Func createAddress2) + { + student.Address1 = createAddress1(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.CreateAddress.InitialStep()); + student.Address2 = createAddress2(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.CreateAddress.InitialStep()); + return student; + } + + public interface ICreateStudent : IWithName + { + } + + public interface IWithName + { + IWithDetails WithName(string name); + } + + public interface IWithDetails + { + Student WithDetails(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.Address address1, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass.Address address2); + + Student WithDetails(Func createAddress1, Func createAddress2); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/Student.cs new file mode 100644 index 0000000..e4d73db --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaCompoundOfSameTypeClass/Student.cs @@ -0,0 +1,20 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaCompoundOfSameTypeClass; + +[FluentApi] +public class Student +{ + [FluentMember(0)] + public string Name { get; set; } + + [FluentMember(1, "WithDetails")] + public Address Address1 { get; set; } + + [FluentMember(1, "WithDetails")] + public Address Address2 { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/Address.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/Address.cs new file mode 100644 index 0000000..e2283e9 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/Address.cs @@ -0,0 +1,20 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass; + +[FluentApi] +public class Address +{ + [FluentMember(0)] + public string HouseNumber { get; set; } + + [FluentMember(1)] + public string Street { get; set; } + + [FluentMember(2, "InCity")] + public string City { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateAddress.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateAddress.g.cs new file mode 100644 index 0000000..eff0e04 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateAddress.g.cs @@ -0,0 +1,73 @@ +// +// 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 M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass; + +public class CreateAddress : + CreateAddress.ICreateAddress, + CreateAddress.IWithHouseNumber, + CreateAddress.IWithStreet, + CreateAddress.IInCity +{ + private readonly Address address; + + private CreateAddress() + { + address = new Address(); + } + + public static ICreateAddress InitialStep() + { + return new CreateAddress(); + } + + public static IWithStreet WithHouseNumber(string houseNumber) + { + CreateAddress createAddress = new CreateAddress(); + createAddress.address.HouseNumber = houseNumber; + return createAddress; + } + + IWithStreet IWithHouseNumber.WithHouseNumber(string houseNumber) + { + address.HouseNumber = houseNumber; + return this; + } + + IInCity IWithStreet.WithStreet(string street) + { + address.Street = street; + return this; + } + + Address IInCity.InCity(string city) + { + address.City = city; + return address; + } + + public interface ICreateAddress : IWithHouseNumber + { + } + + public interface IWithHouseNumber + { + IWithStreet WithHouseNumber(string houseNumber); + } + + public interface IWithStreet + { + IInCity WithStreet(string street); + } + + public interface IInCity + { + Address InCity(string city); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateStudent.expected.txt new file mode 100644 index 0000000..9e0bee7 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateStudent.expected.txt @@ -0,0 +1,360 @@ +// +// 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.Collections.Generic; +using M31.FluentApi.Attributes; +using System; +using System.Linq; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithName, + CreateStudent.IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG +{ + private readonly Student student; + + private CreateStudent() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Name = name; + return createStudent; + } + + IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG IWithName.WithName(string name) + { + student.Name = name; + return this; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(System.Collections.Generic.List addressesA) + { + student.AddressesA = addressesA; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesA) + { + student.AddressesA = new List(addressesA); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params Func[] createAddressesA) + { + student.AddressesA = new List(createAddressesA.Select(createAddressA => createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()))); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressA) + { + student.AddressesA = new List(1){ addressA }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(Func createAddressA) + { + student.AddressesA = new List(1){ createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesA() + { + student.AddressesA = new List(0); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB) + { + student.AddressesB = addressesB; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesB) + { + student.AddressesB = addressesB; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params Func[] createAddressesB) + { + student.AddressesB = createAddressesB.Select(createAddressB => createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep())).ToArray(); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressB) + { + student.AddressesB = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ addressB }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(Func createAddressB) + { + student.AddressesB = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesB() + { + student.AddressesB = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[0]; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesC) + { + student.AddressesC = addressesC; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params Func[] createAddressesC) + { + student.AddressesC = createAddressesC.Select(createAddressC => createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep())).ToArray(); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressC) + { + student.AddressesC = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ addressC }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(Func createAddressC) + { + student.AddressesC = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesC() + { + student.AddressesC = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[0]; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(System.Collections.Generic.HashSet addressesD) + { + student.AddressesD = addressesD; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesD) + { + student.AddressesD = new HashSet(addressesD); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params Func[] createAddressesD) + { + student.AddressesD = new HashSet(createAddressesD.Select(createAddressD => createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()))); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressD) + { + student.AddressesD = new HashSet(1){ addressD }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(Func createAddressD) + { + student.AddressesD = new HashSet(1){ createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesD() + { + student.AddressesD = new HashSet(0); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[]? addressesE) + { + student.AddressesE = addressesE; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params Func[]? createAddressesE) + { + student.AddressesE = createAddressesE?.Select(createAddressE => createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep())).ToArray(); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressE) + { + student.AddressesE = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ addressE }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(Func createAddressE) + { + student.AddressesE = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesE() + { + student.AddressesE = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[0]; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[] addressesF) + { + student.AddressesF = addressesF; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params Func[] createAddressesF) + { + student.AddressesF = createAddressesF.Select(createAddressF => createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep())).ToArray(); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address? addressF) + { + student.AddressesF = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[1]{ addressF }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(Func createAddressF) + { + student.AddressesF = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[1]{ createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesF() + { + student.AddressesF = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[0]; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[]? addressesG) + { + student.AddressesG = addressesG; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params Func[]? createAddressesG) + { + student.AddressesG = createAddressesG?.Select(createAddressG => createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep())).ToArray(); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address? addressG) + { + student.AddressesG = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[1]{ addressG }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(Func createAddressG) + { + student.AddressesG = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[1]{ createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesG() + { + student.AddressesG = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[0]; + return student; + } + + public interface ICreateStudent : IWithName + { + } + + public interface IWithName + { + IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name); + } + + public interface IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG + { + Student WithAddressesA(System.Collections.Generic.List addressesA); + + Student WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesA); + + Student WithAddressesA(params Func[] createAddressesA); + + Student WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressA); + + Student WithAddressA(Func createAddressA); + + Student WithZeroAddressesA(); + + Student WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB); + + Student WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesB); + + Student WithAddressesB(params Func[] createAddressesB); + + Student WithAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressB); + + Student WithAddressB(Func createAddressB); + + Student WithZeroAddressesB(); + + Student WithAddressesC(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesC); + + Student WithAddressesC(params Func[] createAddressesC); + + Student WithAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressC); + + Student WithAddressC(Func createAddressC); + + Student WithZeroAddressesC(); + + Student WithAddressesD(System.Collections.Generic.HashSet addressesD); + + Student WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesD); + + Student WithAddressesD(params Func[] createAddressesD); + + Student WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressD); + + Student WithAddressD(Func createAddressD); + + Student WithZeroAddressesD(); + + Student WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[]? addressesE); + + Student WithAddressesE(params Func[]? createAddressesE); + + Student WithAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressE); + + Student WithAddressE(Func createAddressE); + + Student WithZeroAddressesE(); + + Student WithAddressesF(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[] addressesF); + + Student WithAddressesF(params Func[] createAddressesF); + + Student WithAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address? addressF); + + Student WithAddressF(Func createAddressF); + + Student WithZeroAddressesF(); + + Student WithAddressesG(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[]? addressesG); + + Student WithAddressesG(params Func[]? createAddressesG); + + Student WithAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address? addressG); + + Student WithAddressG(Func createAddressG); + + Student WithZeroAddressesG(); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateStudent.g.cs new file mode 100644 index 0000000..9e0bee7 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/CreateStudent.g.cs @@ -0,0 +1,360 @@ +// +// 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.Collections.Generic; +using M31.FluentApi.Attributes; +using System; +using System.Linq; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithName, + CreateStudent.IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG +{ + private readonly Student student; + + private CreateStudent() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.Name = name; + return createStudent; + } + + IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG IWithName.WithName(string name) + { + student.Name = name; + return this; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(System.Collections.Generic.List addressesA) + { + student.AddressesA = addressesA; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesA) + { + student.AddressesA = new List(addressesA); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params Func[] createAddressesA) + { + student.AddressesA = new List(createAddressesA.Select(createAddressA => createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()))); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressA) + { + student.AddressesA = new List(1){ addressA }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(Func createAddressA) + { + student.AddressesA = new List(1){ createAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesA() + { + student.AddressesA = new List(0); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB) + { + student.AddressesB = addressesB; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesB) + { + student.AddressesB = addressesB; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params Func[] createAddressesB) + { + student.AddressesB = createAddressesB.Select(createAddressB => createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep())).ToArray(); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressB) + { + student.AddressesB = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ addressB }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressB(Func createAddressB) + { + student.AddressesB = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ createAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesB() + { + student.AddressesB = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[0]; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesC) + { + student.AddressesC = addressesC; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesC(params Func[] createAddressesC) + { + student.AddressesC = createAddressesC.Select(createAddressC => createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep())).ToArray(); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressC) + { + student.AddressesC = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ addressC }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressC(Func createAddressC) + { + student.AddressesC = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ createAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesC() + { + student.AddressesC = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[0]; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(System.Collections.Generic.HashSet addressesD) + { + student.AddressesD = addressesD; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesD) + { + student.AddressesD = new HashSet(addressesD); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params Func[] createAddressesD) + { + student.AddressesD = new HashSet(createAddressesD.Select(createAddressD => createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()))); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressD) + { + student.AddressesD = new HashSet(1){ addressD }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(Func createAddressD) + { + student.AddressesD = new HashSet(1){ createAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesD() + { + student.AddressesD = new HashSet(0); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[]? addressesE) + { + student.AddressesE = addressesE; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params Func[]? createAddressesE) + { + student.AddressesE = createAddressesE?.Select(createAddressE => createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep())).ToArray(); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressE) + { + student.AddressesE = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ addressE }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressE(Func createAddressE) + { + student.AddressesE = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[1]{ createAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesE() + { + student.AddressesE = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[0]; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[] addressesF) + { + student.AddressesF = addressesF; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesF(params Func[] createAddressesF) + { + student.AddressesF = createAddressesF.Select(createAddressF => createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep())).ToArray(); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address? addressF) + { + student.AddressesF = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[1]{ addressF }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressF(Func createAddressF) + { + student.AddressesF = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[1]{ createAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesF() + { + student.AddressesF = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[0]; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[]? addressesG) + { + student.AddressesG = addressesG; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesG(params Func[]? createAddressesG) + { + student.AddressesG = createAddressesG?.Select(createAddressG => createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep())).ToArray(); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address? addressG) + { + student.AddressesG = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[1]{ addressG }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressG(Func createAddressG) + { + student.AddressesG = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[1]{ createAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.CreateAddress.InitialStep()) }; + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesG() + { + student.AddressesG = new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[0]; + return student; + } + + public interface ICreateStudent : IWithName + { + } + + public interface IWithName + { + IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name); + } + + public interface IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG + { + Student WithAddressesA(System.Collections.Generic.List addressesA); + + Student WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesA); + + Student WithAddressesA(params Func[] createAddressesA); + + Student WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressA); + + Student WithAddressA(Func createAddressA); + + Student WithZeroAddressesA(); + + Student WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB); + + Student WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesB); + + Student WithAddressesB(params Func[] createAddressesB); + + Student WithAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressB); + + Student WithAddressB(Func createAddressB); + + Student WithZeroAddressesB(); + + Student WithAddressesC(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesC); + + Student WithAddressesC(params Func[] createAddressesC); + + Student WithAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressC); + + Student WithAddressC(Func createAddressC); + + Student WithZeroAddressesC(); + + Student WithAddressesD(System.Collections.Generic.HashSet addressesD); + + Student WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[] addressesD); + + Student WithAddressesD(params Func[] createAddressesD); + + Student WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressD); + + Student WithAddressD(Func createAddressD); + + Student WithZeroAddressesD(); + + Student WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address[]? addressesE); + + Student WithAddressesE(params Func[]? createAddressesE); + + Student WithAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address addressE); + + Student WithAddressE(Func createAddressE); + + Student WithZeroAddressesE(); + + Student WithAddressesF(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[] addressesF); + + Student WithAddressesF(params Func[] createAddressesF); + + Student WithAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address? addressF); + + Student WithAddressF(Func createAddressF); + + Student WithZeroAddressesF(); + + Student WithAddressesG(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address?[]? addressesG); + + Student WithAddressesG(params Func[]? createAddressesG); + + Student WithAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass.Address? addressG); + + Student WithAddressG(Func createAddressG); + + Student WithZeroAddressesG(); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/Student.cs new file mode 100644 index 0000000..b1b8b32 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyCollectionsClass/Student.cs @@ -0,0 +1,36 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using System.Collections.Generic; +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyCollectionsClass; + +[FluentApi] +public class Student +{ + [FluentMember(0)] + public string Name { get; set; } + + [FluentCollection(1, "AddressA")] + public List
AddressesA { get; set; } + + [FluentCollection(1, "AddressB")] + public IReadOnlyCollection
AddressesB { get; set; } + + [FluentCollection(1, "AddressC")] + public Address[] AddressesC { get; set; } + + [FluentCollection(1, "AddressD")] + public HashSet
AddressesD { get; set; } + + [FluentCollection(1, "AddressE")] + public Address[]? AddressesE { get; set; } + + [FluentCollection(1, "AddressF")] + public Address?[] AddressesF { get; set; } + + [FluentCollection(1, "AddressG")] + public Address?[]? AddressesG { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/Address.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/Address.cs new file mode 100644 index 0000000..b93f299 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/Address.cs @@ -0,0 +1,20 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass; + +[FluentApi] +public class Address +{ + [FluentMember(0)] + public string HouseNumber { get; set; } + + [FluentMember(1)] + public string Street { get; set; } + + [FluentMember(2, "InCity")] + public string City { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateAddress.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateAddress.g.cs new file mode 100644 index 0000000..6dfa814 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateAddress.g.cs @@ -0,0 +1,73 @@ +// +// 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 M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass; + +public class CreateAddress : + CreateAddress.ICreateAddress, + CreateAddress.IWithHouseNumber, + CreateAddress.IWithStreet, + CreateAddress.IInCity +{ + private readonly Address address; + + private CreateAddress() + { + address = new Address(); + } + + public static ICreateAddress InitialStep() + { + return new CreateAddress(); + } + + public static IWithStreet WithHouseNumber(string houseNumber) + { + CreateAddress createAddress = new CreateAddress(); + createAddress.address.HouseNumber = houseNumber; + return createAddress; + } + + IWithStreet IWithHouseNumber.WithHouseNumber(string houseNumber) + { + address.HouseNumber = houseNumber; + return this; + } + + IInCity IWithStreet.WithStreet(string street) + { + address.Street = street; + return this; + } + + Address IInCity.InCity(string city) + { + address.City = city; + return address; + } + + public interface ICreateAddress : IWithHouseNumber + { + } + + public interface IWithHouseNumber + { + IWithStreet WithHouseNumber(string houseNumber); + } + + public interface IWithStreet + { + IInCity WithStreet(string street); + } + + public interface IInCity + { + Address InCity(string city); + } +} \ No newline at end of file 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 new file mode 100644 index 0000000..f993191 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.expected.txt @@ -0,0 +1,381 @@ +// +// 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.Collections.Generic; +using M31.FluentApi.Attributes; +using System.Reflection; +using System; +using System.Linq; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithName, + 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() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name) + { + CreateStudent createStudent = new CreateStudent(); + CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + return createStudent; + } + + IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG IWithName.WithName(string name) + { + CreateStudent.namePropertyInfo.SetValue(student, name); + return this; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(System.Collections.Generic.List addressesA) + { + CreateStudent.addressesAPropertyInfo.SetValue(student, addressesA); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesA) + { + CreateStudent.addressesAPropertyInfo.SetValue(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())))); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressA) + { + CreateStudent.addressesAPropertyInfo.SetValue(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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesA() + { + CreateStudent.addressesAPropertyInfo.SetValue(student, new List(0)); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB) + { + CreateStudent.addressesBPropertyInfo.SetValue(student, addressesB); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesB) + { + CreateStudent.addressesBPropertyInfo.SetValue(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()); + 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 }); + 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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesB() + { + CreateStudent.addressesBPropertyInfo.SetValue(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); + 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()); + 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 }); + 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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesC() + { + CreateStudent.addressesCPropertyInfo.SetValue(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); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesD) + { + CreateStudent.addressesDPropertyInfo.SetValue(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())))); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressD) + { + CreateStudent.addressesDPropertyInfo.SetValue(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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesD() + { + CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(0)); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[]? addressesE) + { + CreateStudent.addressesEPropertyInfo.SetValue(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()); + 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 }); + 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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesE() + { + CreateStudent.addressesEPropertyInfo.SetValue(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); + 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()); + 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 }); + 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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesF() + { + CreateStudent.addressesFPropertyInfo.SetValue(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); + 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()); + 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 }); + 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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesG() + { + CreateStudent.addressesGPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); + return student; + } + + public interface ICreateStudent : IWithName + { + } + + public interface IWithName + { + IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name); + } + + public interface IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG + { + Student WithAddressesA(System.Collections.Generic.List addressesA); + + Student WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesA); + + Student WithAddressesA(params Func[] createAddressesA); + + Student WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressA); + + Student WithAddressA(Func createAddressA); + + Student WithZeroAddressesA(); + + Student WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB); + + Student WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesB); + + Student WithAddressesB(params Func[] createAddressesB); + + Student WithAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressB); + + Student WithAddressB(Func createAddressB); + + Student WithZeroAddressesB(); + + Student WithAddressesC(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesC); + + Student WithAddressesC(params Func[] createAddressesC); + + Student WithAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressC); + + Student WithAddressC(Func createAddressC); + + Student WithZeroAddressesC(); + + Student WithAddressesD(System.Collections.Generic.HashSet addressesD); + + Student WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesD); + + Student WithAddressesD(params Func[] createAddressesD); + + Student WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressD); + + Student WithAddressD(Func createAddressD); + + Student WithZeroAddressesD(); + + Student WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[]? addressesE); + + Student WithAddressesE(params Func[]? createAddressesE); + + Student WithAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressE); + + Student WithAddressE(Func createAddressE); + + Student WithZeroAddressesE(); + + Student WithAddressesF(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[] addressesF); + + Student WithAddressesF(params Func[] createAddressesF); + + Student WithAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressF); + + Student WithAddressF(Func createAddressF); + + Student WithZeroAddressesF(); + + Student WithAddressesG(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[]? addressesG); + + Student WithAddressesG(params Func[]? createAddressesG); + + Student WithAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressG); + + Student WithAddressG(Func createAddressG); + + Student WithZeroAddressesG(); + } +} \ 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 new file mode 100644 index 0000000..f993191 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/CreateStudent.g.cs @@ -0,0 +1,381 @@ +// +// 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.Collections.Generic; +using M31.FluentApi.Attributes; +using System.Reflection; +using System; +using System.Linq; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithName, + 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() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name) + { + CreateStudent createStudent = new CreateStudent(); + CreateStudent.namePropertyInfo.SetValue(createStudent.student, name); + return createStudent; + } + + IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG IWithName.WithName(string name) + { + CreateStudent.namePropertyInfo.SetValue(student, name); + return this; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(System.Collections.Generic.List addressesA) + { + CreateStudent.addressesAPropertyInfo.SetValue(student, addressesA); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesA) + { + CreateStudent.addressesAPropertyInfo.SetValue(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())))); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressA) + { + CreateStudent.addressesAPropertyInfo.SetValue(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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesA() + { + CreateStudent.addressesAPropertyInfo.SetValue(student, new List(0)); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB) + { + CreateStudent.addressesBPropertyInfo.SetValue(student, addressesB); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesB) + { + CreateStudent.addressesBPropertyInfo.SetValue(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()); + 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 }); + 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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesB() + { + CreateStudent.addressesBPropertyInfo.SetValue(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); + 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()); + 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 }); + 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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesC() + { + CreateStudent.addressesCPropertyInfo.SetValue(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); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesD) + { + CreateStudent.addressesDPropertyInfo.SetValue(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())))); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressD) + { + CreateStudent.addressesDPropertyInfo.SetValue(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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesD() + { + CreateStudent.addressesDPropertyInfo.SetValue(student, new HashSet(0)); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[]? addressesE) + { + CreateStudent.addressesEPropertyInfo.SetValue(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()); + 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 }); + 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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesE() + { + CreateStudent.addressesEPropertyInfo.SetValue(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); + 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()); + 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 }); + 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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesF() + { + CreateStudent.addressesFPropertyInfo.SetValue(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); + 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()); + 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 }); + 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()) }); + return student; + } + + Student IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG.WithZeroAddressesG() + { + CreateStudent.addressesGPropertyInfo.SetValue(student, new M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[0]); + return student; + } + + public interface ICreateStudent : IWithName + { + } + + public interface IWithName + { + IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG WithName(string name); + } + + public interface IWithAddressesAWithAddressesBWithAddressesCWithAddressesDWithAddressesEWithAddressesFWithAddressesG + { + Student WithAddressesA(System.Collections.Generic.List addressesA); + + Student WithAddressesA(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesA); + + Student WithAddressesA(params Func[] createAddressesA); + + Student WithAddressA(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressA); + + Student WithAddressA(Func createAddressA); + + Student WithZeroAddressesA(); + + Student WithAddressesB(System.Collections.Generic.IReadOnlyCollection addressesB); + + Student WithAddressesB(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesB); + + Student WithAddressesB(params Func[] createAddressesB); + + Student WithAddressB(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressB); + + Student WithAddressB(Func createAddressB); + + Student WithZeroAddressesB(); + + Student WithAddressesC(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesC); + + Student WithAddressesC(params Func[] createAddressesC); + + Student WithAddressC(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressC); + + Student WithAddressC(Func createAddressC); + + Student WithZeroAddressesC(); + + Student WithAddressesD(System.Collections.Generic.HashSet addressesD); + + Student WithAddressesD(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[] addressesD); + + Student WithAddressesD(params Func[] createAddressesD); + + Student WithAddressD(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressD); + + Student WithAddressD(Func createAddressD); + + Student WithZeroAddressesD(); + + Student WithAddressesE(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address[]? addressesE); + + Student WithAddressesE(params Func[]? createAddressesE); + + Student WithAddressE(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address addressE); + + Student WithAddressE(Func createAddressE); + + Student WithZeroAddressesE(); + + Student WithAddressesF(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[] addressesF); + + Student WithAddressesF(params Func[] createAddressesF); + + Student WithAddressF(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressF); + + Student WithAddressF(Func createAddressF); + + Student WithZeroAddressesF(); + + Student WithAddressesG(params M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address?[]? addressesG); + + Student WithAddressesG(params Func[]? createAddressesG); + + Student WithAddressG(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass.Address? addressG); + + Student WithAddressG(Func createAddressG); + + Student WithZeroAddressesG(); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/Student.cs new file mode 100644 index 0000000..5be5364 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaManyPrivateCollectionsClass/Student.cs @@ -0,0 +1,36 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using System.Collections.Generic; +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaManyPrivateCollectionsClass; + +[FluentApi] +public class Student +{ + [FluentMember(0)] + public string Name { get; private set; } + + [FluentCollection(1, "AddressA")] + public List
AddressesA { get; private set; } + + [FluentCollection(1, "AddressB")] + public IReadOnlyCollection
AddressesB { get; private set; } + + [FluentCollection(1, "AddressC")] + public Address[] AddressesC { get; private set; } + + [FluentCollection(1, "AddressD")] + public HashSet
AddressesD { get; private set; } + + [FluentCollection(1, "AddressE")] + public Address[]? AddressesE { get; private set; } + + [FluentCollection(1, "AddressF")] + public Address?[] AddressesF { get; private set; } + + [FluentCollection(1, "AddressG")] + public Address?[]? AddressesG { get; private set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaNullablePropertyClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaNullablePropertyClass/Student.cs index 27ffe12..cdb08b2 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaNullablePropertyClass/Student.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaNullablePropertyClass/Student.cs @@ -12,7 +12,7 @@ public class Student [FluentMember(0)] public string Name { get; set; } - [FluentLambda(1)] + [FluentMember(1)] [FluentNullable] public Address? Address { get; set; } } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/CreateStudent.expected.txt index 0d5ac15..5d78bd4 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/CreateStudent.expected.txt +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/CreateStudent.expected.txt @@ -46,9 +46,9 @@ public class CreateStudent : return student; } - Student IWithFriend.WithFriend(Func createStudent) + Student IWithFriend.WithFriend(Func createFriend) { - student.Friend = createStudent(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaRecursiveClass.CreateStudent.InitialStep()); + student.Friend = createFriend(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaRecursiveClass.CreateStudent.InitialStep()); return student; } @@ -71,7 +71,7 @@ public class CreateStudent : { Student WithFriend(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaRecursiveClass.Student? friend); - Student WithFriend(Func createStudent); + Student WithFriend(Func createFriend); Student WithoutFriend(); } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/CreateStudent.g.cs index 0d5ac15..5d78bd4 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/CreateStudent.g.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/CreateStudent.g.cs @@ -46,9 +46,9 @@ Student IWithFriend.WithFriend(M31.FluentApi.Tests.CodeGeneration.TestClasses.Ab return student; } - Student IWithFriend.WithFriend(Func createStudent) + Student IWithFriend.WithFriend(Func createFriend) { - student.Friend = createStudent(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaRecursiveClass.CreateStudent.InitialStep()); + student.Friend = createFriend(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaRecursiveClass.CreateStudent.InitialStep()); return student; } @@ -71,7 +71,7 @@ public interface IWithFriend { Student WithFriend(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaRecursiveClass.Student? friend); - Student WithFriend(Func createStudent); + Student WithFriend(Func createFriend); Student WithoutFriend(); } diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/Student.cs index 0769793..cb555ed 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/Student.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaRecursiveClass/Student.cs @@ -12,7 +12,7 @@ public class Student [FluentMember(0)] public string Name { get; set; } - [FluentLambda(1)] + [FluentMember(1)] [FluentNullable] public Student? Friend { get; set; } } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaSingleStepClass/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaSingleStepClass/Student.cs index 9b362cb..439ee4d 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaSingleStepClass/Student.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/FluentLambdaSingleStepClass/Student.cs @@ -9,6 +9,6 @@ namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.FluentLambdaSi [FluentApi] public class Student { - [FluentLambda(0)] + [FluentMember(0)] public Address Address { get; set; } } \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/Address.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/Address.cs new file mode 100644 index 0000000..15c4841 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/Address.cs @@ -0,0 +1,20 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable all + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3; + +[FluentApi] +public class Address +{ + [FluentMember(0)] + public string HouseNumber { get; set; } + + [FluentMember(1)] + public string Street { get; set; } + + [FluentMember(2, "InCity")] + public string City { get; set; } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateAddress.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateAddress.g.cs new file mode 100644 index 0000000..fa03061 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateAddress.g.cs @@ -0,0 +1,73 @@ +// +// 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 M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3; + +public class CreateAddress : + CreateAddress.ICreateAddress, + CreateAddress.IWithHouseNumber, + CreateAddress.IWithStreet, + CreateAddress.IInCity +{ + private readonly Address address; + + private CreateAddress() + { + address = new Address(); + } + + public static ICreateAddress InitialStep() + { + return new CreateAddress(); + } + + public static IWithStreet WithHouseNumber(string houseNumber) + { + CreateAddress createAddress = new CreateAddress(); + createAddress.address.HouseNumber = houseNumber; + return createAddress; + } + + IWithStreet IWithHouseNumber.WithHouseNumber(string houseNumber) + { + address.HouseNumber = houseNumber; + return this; + } + + IInCity IWithStreet.WithStreet(string street) + { + address.Street = street; + return this; + } + + Address IInCity.InCity(string city) + { + address.City = city; + return address; + } + + public interface ICreateAddress : IWithHouseNumber + { + } + + public interface IWithHouseNumber + { + IWithStreet WithHouseNumber(string houseNumber); + } + + public interface IWithStreet + { + IInCity WithStreet(string street); + } + + public interface IInCity + { + Address InCity(string city); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateStudent.expected.txt b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateStudent.expected.txt new file mode 100644 index 0000000..2d76be7 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateStudent.expected.txt @@ -0,0 +1,69 @@ +// +// 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 M31.FluentApi.Attributes; +using System; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithDetails +{ + private readonly Student student; + + private CreateStudent() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static Student WithDetails(string createAddress, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3.Address address) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.CreateAddress = createAddress; + createStudent.student.Address = address; + return createStudent.student; + } + + public static Student WithDetails(string createAddress, Func createAddress2) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.CreateAddress = createAddress; + createStudent.student.Address = createAddress2(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3.CreateAddress.InitialStep()); + return createStudent.student; + } + + Student IWithDetails.WithDetails(string createAddress, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3.Address address) + { + student.CreateAddress = createAddress; + student.Address = address; + return student; + } + + Student IWithDetails.WithDetails(string createAddress, Func createAddress2) + { + student.CreateAddress = createAddress; + student.Address = createAddress2(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3.CreateAddress.InitialStep()); + return student; + } + + public interface ICreateStudent : IWithDetails + { + } + + public interface IWithDetails + { + Student WithDetails(string createAddress, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3.Address address); + + Student WithDetails(string createAddress, Func createAddress2); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateStudent.g.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateStudent.g.cs new file mode 100644 index 0000000..2d76be7 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/CreateStudent.g.cs @@ -0,0 +1,69 @@ +// +// 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 M31.FluentApi.Attributes; +using System; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3; + +public class CreateStudent : + CreateStudent.ICreateStudent, + CreateStudent.IWithDetails +{ + private readonly Student student; + + private CreateStudent() + { + student = new Student(); + } + + public static ICreateStudent InitialStep() + { + return new CreateStudent(); + } + + public static Student WithDetails(string createAddress, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3.Address address) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.CreateAddress = createAddress; + createStudent.student.Address = address; + return createStudent.student; + } + + public static Student WithDetails(string createAddress, Func createAddress2) + { + CreateStudent createStudent = new CreateStudent(); + createStudent.student.CreateAddress = createAddress; + createStudent.student.Address = createAddress2(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3.CreateAddress.InitialStep()); + return createStudent.student; + } + + Student IWithDetails.WithDetails(string createAddress, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3.Address address) + { + student.CreateAddress = createAddress; + student.Address = address; + return student; + } + + Student IWithDetails.WithDetails(string createAddress, Func createAddress2) + { + student.CreateAddress = createAddress; + student.Address = createAddress2(M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3.CreateAddress.InitialStep()); + return student; + } + + public interface ICreateStudent : IWithDetails + { + } + + public interface IWithDetails + { + Student WithDetails(string createAddress, M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3.Address address); + + Student WithDetails(string createAddress, Func createAddress2); + } +} \ No newline at end of file diff --git a/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/Student.cs b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/Student.cs new file mode 100644 index 0000000..b30afc1 --- /dev/null +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestClasses/Abstract/TryBreakFluentApiClass3/Student.cs @@ -0,0 +1,17 @@ +// Non-nullable member is uninitialized +#pragma warning disable CS8618 +// ReSharper disable All + +using M31.FluentApi.Attributes; + +namespace M31.FluentApi.Tests.CodeGeneration.TestClasses.Abstract.TryBreakFluentApiClass3; + +[FluentApi] +public class Student +{ + [FluentMember(0, "WithDetails")] + public string CreateAddress { get; set; } + + [FluentMember(0, "WithDetails")] + public Address Address { get; set; } +} \ 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 4930406..7ea7887 100644 --- a/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs +++ b/src/M31.FluentApi.Tests/CodeGeneration/TestDataProvider.cs @@ -24,6 +24,11 @@ internal class TestDataProvider : IEnumerable 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" }, @@ -83,6 +88,7 @@ internal class TestDataProvider : IEnumerable 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" }, diff --git a/src/M31.FluentApi.Tests/Components/CollectionInferenceTests.cs b/src/M31.FluentApi.Tests/Components/CollectionInferenceTests.cs index d9f8ed4..7b48701 100644 --- a/src/M31.FluentApi.Tests/Components/CollectionInferenceTests.cs +++ b/src/M31.FluentApi.Tests/Components/CollectionInferenceTests.cs @@ -98,7 +98,7 @@ private void TestType(string propertyName, GeneratedCollection expectedCollectio { ITypeSymbol typeSymbol = typeSymbolProvider.GetTypeSymbol(propertyName); CollectionType? actual = CollectionInference.InferCollectionType(typeSymbol); - CollectionType expected = new CollectionType(expectedCollection, genericTypeArgument); + CollectionType expected = new CollectionType(expectedCollection, genericTypeArgument, null); Assert.Equal(expected, actual); } } \ No newline at end of file diff --git a/src/M31.FluentApi.sln.DotSettings b/src/M31.FluentApi.sln.DotSettings index 907061c..54f6756 100644 --- a/src/M31.FluentApi.sln.DotSettings +++ b/src/M31.FluentApi.sln.DotSettings @@ -1,4 +1,5 @@  True True - True \ No newline at end of file + True + True \ No newline at end of file diff --git a/src/M31.FluentApi/Attributes/FluentLambdaAttribute.cs b/src/M31.FluentApi/Attributes/FluentLambdaAttribute.cs index 082053e..6961f32 100644 --- a/src/M31.FluentApi/Attributes/FluentLambdaAttribute.cs +++ b/src/M31.FluentApi/Attributes/FluentLambdaAttribute.cs @@ -6,6 +6,9 @@ namespace M31.FluentApi.Attributes; /// Generates a builder method that accepts a lambda expression for creating the target field or property with its /// Fluent API. /// +[Obsolete( + "Use FluentMember instead. Lambda methods are generated by default if the decorated member has a Fluent API.", + false)] [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public class FluentLambdaAttribute : Attribute { diff --git a/src/M31.FluentApi/M31.FluentApi.csproj b/src/M31.FluentApi/M31.FluentApi.csproj index ea64458..a83af37 100644 --- a/src/M31.FluentApi/M31.FluentApi.csproj +++ b/src/M31.FluentApi/M31.FluentApi.csproj @@ -7,7 +7,7 @@ enable true true - 1.6.0 + 1.7.0 Kevin Schaal Generate fluent builders in C#. fluentapi fluentbuilder fluentinterface fluentdesign fluent codegeneration