From 1992316db6ee5205cf0057d4724f8d0c89586027 Mon Sep 17 00:00:00 2001 From: Xavier Solau Date: Sat, 3 Feb 2024 19:23:17 +0100 Subject: [PATCH] Add support for Repeat pattern method argument when used with no arguments and add replacePattern support on method --- .github/workflows/build-pr.yml | 2 - .../EntityGeneratorExample.cs | 4 - .../ModelGeneratorExample.cs | 4 - .../Generator/Attributes/RepeatAttribute.cs | 2 +- .../Generator/Impl/AInstanceResolver.cs | 116 ++++++++++++++++++ .../Generator/Impl/AutomatedGenerator.cs | 16 ++- .../Impl/DefaultReplacePatternResolver.cs | 42 +++++++ .../Generator/Impl/DefaultSelectorResolver.cs | 80 +----------- .../Impl/Walker/AutomatedConstantStrategy.cs | 10 ++ .../Walker/AutomatedDeclarationsStrategy.cs | 13 +- .../Impl/Walker/AutomatedGenericStrategy.cs | 15 ++- .../Impl/Walker/AutomatedMethodStrategy.cs | 19 ++- .../Impl/Walker/AutomatedParameterStrategy.cs | 5 + .../Impl/Walker/AutomatedPropertyStrategy.cs | 5 + .../Generator/Impl/Walker/AutomatedWalker.cs | 26 ++++ .../Impl/Walker/IAutomatedStrategy.cs | 7 ++ .../IReplacePatternHandlerFactory.cs | 8 ++ .../ReplacePattern/IReplacePatternResolver.cs | 26 ++++ .../TaskValueTypeReplaceHandler.cs | 79 ++++++++++++ .../Utils/AttributeSyntaxHelper.cs | 12 +- .../Automated/AutomatedGeneratorTest.cs | 36 +++++- .../Patterns/Impl/AsyncMethodPattern.cs | 27 ++++ .../Patterns/Impl/SimpleMethod6Pattern.cs | 56 +++++++++ .../Patterns/Itf/IAsyncMethodPattern.cs | 17 +++ .../Automated/Patterns/MultiSelector.cs | 8 +- .../Automated/Samples/IAsyncMethodSample.cs | 24 ++++ .../AutomatedAsyncMethodTest.snapshot | 37 ++++++ .../AutomatedSimpleMethod6Test.snapshot | 93 ++++++++++++++ ...oX.GeneratorTools.Core.CSharp.ITest.csproj | 6 + .../Impl/ToolsGenerator.cs | 5 - 30 files changed, 688 insertions(+), 112 deletions(-) create mode 100644 src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/AInstanceResolver.cs create mode 100644 src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/DefaultReplacePatternResolver.cs create mode 100644 src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/IReplacePatternResolver.cs create mode 100644 src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/TaskValueTypeReplaceHandler.cs create mode 100644 src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Impl/AsyncMethodPattern.cs create mode 100644 src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Impl/SimpleMethod6Pattern.cs create mode 100644 src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Itf/IAsyncMethodPattern.cs create mode 100644 src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Samples/IAsyncMethodSample.cs create mode 100644 src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Snapshots/AutomatedAsyncMethodTest.snapshot create mode 100644 src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Snapshots/AutomatedSimpleMethod6Test.snapshot diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 89612bd..97342bf 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -55,7 +55,6 @@ jobs: format: cobertura flag-name: test-${{ matrix.test_path }} parallel: true - debug: true end-coverage-pr: needs: coverage-pr @@ -66,4 +65,3 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} parallel-finished: true - debug: true diff --git a/src/examples/SoloX.GeneratorTools.Core.CSharp.Examples/EntityGeneratorExample.cs b/src/examples/SoloX.GeneratorTools.Core.CSharp.Examples/EntityGeneratorExample.cs index 9e53ed2..14428e8 100644 --- a/src/examples/SoloX.GeneratorTools.Core.CSharp.Examples/EntityGeneratorExample.cs +++ b/src/examples/SoloX.GeneratorTools.Core.CSharp.Examples/EntityGeneratorExample.cs @@ -70,16 +70,12 @@ public void Generate(string projectFile) // Setup a locator that will tell the location where the generated classes must be written. var locator = new RelativeLocator(projectFolder, project.RootNameSpace, suffix: "Impl"); - // Setup a selector resolver. - var selectorResolver = new DefaultSelectorResolver(); - // Create the automated generator. var generator = new AutomatedGenerator( new FileWriter(".generated.cs"), locator, resolver, typeof(EntityPattern), - selectorResolver, new GeneratorLogger(this.logger)); // Generate the files. diff --git a/src/examples/SoloX.GeneratorTools.Core.CSharp.Examples/ModelGeneratorExample.cs b/src/examples/SoloX.GeneratorTools.Core.CSharp.Examples/ModelGeneratorExample.cs index e8cfc5f..2031abc 100644 --- a/src/examples/SoloX.GeneratorTools.Core.CSharp.Examples/ModelGeneratorExample.cs +++ b/src/examples/SoloX.GeneratorTools.Core.CSharp.Examples/ModelGeneratorExample.cs @@ -70,16 +70,12 @@ public void Generate(string projectFile) // Setup a locator that will tell the location where the generated classes must be written. var locator = new RelativeLocator(projectFolder, project.RootNameSpace, suffix: "Impl"); - // Setup a selector resolver. - var selectorResolver = new DefaultSelectorResolver(); - // Create the automated generator. var generator = new AutomatedGenerator( new FileWriter(".generated.cs"), locator, resolver, typeof(ModelPattern), - selectorResolver, new GeneratorLogger(this.logger)); // Generate the files. diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Attributes/RepeatAttribute.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Attributes/RepeatAttribute.cs index e4423ee..bff0bbf 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Attributes/RepeatAttribute.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Attributes/RepeatAttribute.cs @@ -14,7 +14,7 @@ namespace SoloX.GeneratorTools.Core.CSharp.Generator.Attributes /// Attribute used to tell that the pattern element must be repeated. /// For example use it if you want to repeat a piece of code. /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue)] public sealed class RepeatAttribute : Attribute { /// diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/AInstanceResolver.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/AInstanceResolver.cs new file mode 100644 index 0000000..9715171 --- /dev/null +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/AInstanceResolver.cs @@ -0,0 +1,116 @@ +// ---------------------------------------------------------------------- +// +// Copyright © 2021 Xavier Solau. +// Licensed under the MIT license. +// See LICENSE file in the project root for full license information. +// +// ---------------------------------------------------------------------- + +using Microsoft.CodeAnalysis; +using SoloX.GeneratorTools.Core.CSharp.Model.Use; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace SoloX.GeneratorTools.Core.CSharp.Generator.Impl +{ + /// + /// Base type resolver to find a Type from a IDeclarationUse + /// + public abstract class AInstanceResolver + { + private readonly Dictionary typesByFullName; + private readonly Dictionary typesByName; + + /// + /// Setup instance with the given types to be resolved. + /// + /// Types to be resolved in selectors. + protected AInstanceResolver(IEnumerable defaultTypes, params Type[] types) + { + var allTypes = types.Concat(defaultTypes).ToArray(); + + this.typesByFullName = allTypes.ToDictionary(t => t.FullName); + this.typesByName = allTypes.ToDictionary(t => t.Name); + } + + /// + /// Create a Type instance from the given declarationUse + /// + /// + /// + /// + /// + protected TInstance? CreateInstance(IDeclarationUse declarationUse) + { + if (declarationUse == null) + { + throw new ArgumentNullException(nameof(declarationUse)); + } + + var instanceType = ResolveAsType(declarationUse); + + if (instanceType != null) + { + return (TInstance)Activator.CreateInstance(instanceType); + } + + return default; + } + + private Type ResolveAsType(IDeclarationUse declarationUse) + { + if (declarationUse is IGenericDeclarationUse genericDeclarationUse) + { + var fullName = declarationUse.Declaration.FullName; + var genericCount = genericDeclarationUse.GenericParameters.Count; + + Type type; + if (genericCount > 0) + { + fullName = fullName + '`' + genericCount; + + type = GetTypeFromName(fullName); + + var genericParameters = new List(); + + foreach (var genericParameter in genericDeclarationUse.GenericParameters) + { + var genericParameterType = ResolveAsType(genericParameter); + + genericParameters.Add(genericParameterType); + } + + type = type.MakeGenericType(genericParameters.ToArray()); + } + else + { + type = GetTypeFromName(fullName); + } + + return type; + } + + return GetTypeFromName(declarationUse.Declaration.Name); + } + + /// + /// Get the type matching the given name. + /// + /// Name of the type to resolve. + /// The resolver Type object or null. + protected Type GetTypeFromName(string name) + { + if (this.typesByFullName.TryGetValue(name, out var type)) + { + return type; + } + else if (this.typesByName.TryGetValue(name, out type)) + { + return type; + } + + throw new NotSupportedException($"Unable to resolve type from name: {name}"); + } + } +} diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/AutomatedGenerator.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/AutomatedGenerator.cs index 74de244..64da98d 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/AutomatedGenerator.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/AutomatedGenerator.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis; using SoloX.GeneratorTools.Core.CSharp.Generator.Attributes; using SoloX.GeneratorTools.Core.CSharp.Generator.Impl.Walker; +using SoloX.GeneratorTools.Core.CSharp.Generator.ReplacePattern; using SoloX.GeneratorTools.Core.CSharp.Generator.Selectors; using SoloX.GeneratorTools.Core.CSharp.Model; using SoloX.GeneratorTools.Core.CSharp.Model.Resolver; @@ -31,6 +32,7 @@ public class AutomatedGenerator : IAutomatedGenerator private readonly IDeclarationResolver resolver; private readonly Type patternType; private readonly ISelectorResolver selectorResolver; + private readonly IReplacePatternResolver replacePatternResolver; private readonly IGeneratorLogger logger; private readonly PatternAttribute patternAttribute; private readonly IDeclaration pattern; @@ -43,9 +45,10 @@ public class AutomatedGenerator : IAutomatedGenerator /// Code generation locator. /// The resolver to resolve workspace symbols. /// The pattern type to use. - /// Logger instance. /// Selector resolver or null to use the default one. - public AutomatedGenerator(IWriter writer, ILocator locator, IDeclarationResolver resolver, Type patternType, ISelectorResolver selectorResolver, IGeneratorLogger logger) + /// + /// Logger instance. + public AutomatedGenerator(IWriter writer, ILocator locator, IDeclarationResolver resolver, Type patternType, IGeneratorLogger logger, ISelectorResolver? selectorResolver = null, IReplacePatternResolver? replacePatternResolver = null) { if (writer == null) { @@ -71,7 +74,8 @@ public AutomatedGenerator(IWriter writer, ILocator locator, IDeclarationResolver this.resolver = resolver; this.locator = locator; this.patternType = patternType; - this.selectorResolver = selectorResolver; + this.selectorResolver = selectorResolver ?? new DefaultSelectorResolver(); + this.replacePatternResolver = replacePatternResolver ?? new DefaultReplacePatternResolver(); this.logger = logger; this.patternAttribute = FindAttribute(this.patternType); @@ -116,7 +120,8 @@ public IEnumerable Generate(IEnumerable files) this.resolver, replacePatternHandlerFactories, this.ignoreUsingList, - this.selectorResolver); + this.selectorResolver, + this.replacePatternResolver); var implName = strategy.ApplyPatternReplace(this.pattern.Name); @@ -151,7 +156,8 @@ public IEnumerable Generate(IEnumerable files) this.resolver, replacePatternHandlerFactories, this.ignoreUsingList, - this.selectorResolver); + this.selectorResolver, + this.replacePatternResolver); var implName = strategy.ComputeTargetName(); diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/DefaultReplacePatternResolver.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/DefaultReplacePatternResolver.cs new file mode 100644 index 0000000..97f5c4f --- /dev/null +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/DefaultReplacePatternResolver.cs @@ -0,0 +1,42 @@ +// ---------------------------------------------------------------------- +// +// Copyright © 2021 Xavier Solau. +// Licensed under the MIT license. +// See LICENSE file in the project root for full license information. +// +// ---------------------------------------------------------------------- + +using Microsoft.CodeAnalysis; +using SoloX.GeneratorTools.Core.CSharp.Model.Use; +using System.Collections.Generic; +using System; +using SoloX.GeneratorTools.Core.CSharp.Generator.ReplacePattern; + +namespace SoloX.GeneratorTools.Core.CSharp.Generator.Impl +{ + /// + /// Default resolver for replace pattern handler factory. + /// + public class DefaultReplacePatternResolver : AInstanceResolver, IReplacePatternResolver + { + private static readonly IEnumerable DefaultTypes = new[] + { + typeof(TaskValueTypeReplaceHandler), + }; + + /// + /// Setup instance with the given types to be resolved. + /// + /// Types to be resolved in selectors. + public DefaultReplacePatternResolver(params Type[] types) + : base(DefaultTypes, types) + { + } + + /// + public IReplacePatternHandlerFactory GetHandlerFactory(IDeclarationUse replacePatternHandlerTypeUse) + { + return CreateInstance(replacePatternHandlerTypeUse); + } + } +} diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/DefaultSelectorResolver.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/DefaultSelectorResolver.cs index 77469d3..d305983 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/DefaultSelectorResolver.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/DefaultSelectorResolver.cs @@ -11,14 +11,13 @@ using SoloX.GeneratorTools.Core.CSharp.Model.Use; using System; using System.Collections.Generic; -using System.Linq; namespace SoloX.GeneratorTools.Core.CSharp.Generator.Impl { /// /// Default selector type resolver. /// - public class DefaultSelectorResolver : ISelectorResolver + public class DefaultSelectorResolver : AInstanceResolver, ISelectorResolver { private static readonly IEnumerable DefaultTypes = new[] { @@ -29,92 +28,19 @@ public class DefaultSelectorResolver : ISelectorResolver typeof(AllSelector), }; - private readonly Dictionary typesByFullName; - private readonly Dictionary typesByName; - /// /// Setup instance with the given types to be resolved. /// /// Types to be resolved in selectors. public DefaultSelectorResolver(params Type[] types) + : base(DefaultTypes, types) { - var allTypes = types.Concat(DefaultTypes).ToArray(); - - this.typesByFullName = allTypes.ToDictionary(t => t.FullName); - this.typesByName = allTypes.ToDictionary(t => t.Name); } /// public ISelector GetSelector(IDeclarationUse selectorTypeUse) { - if (selectorTypeUse == null) - { - throw new ArgumentNullException(nameof(selectorTypeUse)); - } - - var selectorType = ResolveAsType(selectorTypeUse); - - if (selectorType != null) - { - return (ISelector)Activator.CreateInstance(selectorType); - } - - return null; - } - - private Type ResolveAsType(IDeclarationUse selectorTypeUse) - { - if (selectorTypeUse is IGenericDeclarationUse genericDeclarationUse) - { - var fullName = selectorTypeUse.Declaration.FullName; - var genericCount = genericDeclarationUse.GenericParameters.Count; - - Type type; - if (genericCount > 0) - { - fullName = fullName + '`' + genericCount; - - type = GetTypeFromName(fullName); - - var genericParameters = new List(); - - foreach (var genericParameter in genericDeclarationUse.GenericParameters) - { - var genericParameterType = ResolveAsType(genericParameter); - - genericParameters.Add(genericParameterType); - } - - type = type.MakeGenericType(genericParameters.ToArray()); - } - else - { - type = GetTypeFromName(fullName); - } - - return type; - } - - return GetTypeFromName(selectorTypeUse.Declaration.Name); - } - - /// - /// Get the type matching the given name. - /// - /// Name of the type to resolve. - /// The resolver Type object or null. - protected Type GetTypeFromName(string name) - { - if (this.typesByFullName.TryGetValue(name, out var type)) - { - return type; - } - else if (this.typesByName.TryGetValue(name, out type)) - { - return type; - } - - throw new NotSupportedException($"Unable to resolve type from name: {name}"); + return CreateInstance(selectorTypeUse); } } } diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedConstantStrategy.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedConstantStrategy.cs index fce591e..7511b19 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedConstantStrategy.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedConstantStrategy.cs @@ -44,6 +44,11 @@ public IReplacePatternHandler CreateReplacePatternHandler() return new StrategyReplacePatternHandler(ApplyPatternReplace); } + public IReplacePatternHandler CreateReplacePatternHandler(AttributeSyntax replacePatternAttributeSyntax) + { + throw new NotImplementedException(); + } + private string ApplyPatternReplace(string text) { var result = this.textReplaceHelper.ReplacePattern(text); @@ -85,5 +90,10 @@ public bool TryMatchAndRepeatStatement( { return false; } + + public void ReplaceDeclaration(AttributeSyntax repeatAttributeSyntax, Action callback) + { + throw new NotImplementedException(); + } } } diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedDeclarationsStrategy.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedDeclarationsStrategy.cs index b03e392..8a7975a 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedDeclarationsStrategy.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedDeclarationsStrategy.cs @@ -29,6 +29,7 @@ internal class AutomatedDeclarationsStrategy : IAutomatedStrategy private readonly IEnumerable replacePatternHandlerFactories; private readonly IEnumerable ignoreUsingList; private readonly ISelectorResolver selectorResolver; + private readonly IReplacePatternResolver replacePatternResolver; public AutomatedDeclarationsStrategy( IDeclaration pattern, @@ -38,7 +39,8 @@ public AutomatedDeclarationsStrategy( IDeclarationResolver resolver, IEnumerable replacePatternHandlerFactories, IEnumerable ignoreUsingList, - ISelectorResolver selectorResolver) + ISelectorResolver selectorResolver, + IReplacePatternResolver replacePatternResolver) { this.targetName = name; this.currentNameSpace = nameSpace; @@ -48,6 +50,7 @@ public AutomatedDeclarationsStrategy( this.replacePatternHandlerFactories = replacePatternHandlerFactories; this.ignoreUsingList = ignoreUsingList; this.selectorResolver = selectorResolver; + this.replacePatternResolver = replacePatternResolver; } public IReplacePatternHandler CreateReplacePatternHandler() @@ -55,6 +58,11 @@ public IReplacePatternHandler CreateReplacePatternHandler() return new StrategyReplacePatternHandler(ApplyPatternReplace); } + public IReplacePatternHandler CreateReplacePatternHandler(AttributeSyntax replacePatternAttributeSyntax) + { + throw new NotImplementedException(); + } + private string ApplyPatternReplace(string text) { var result = text.Replace(this.pattern.Name, this.targetName); @@ -84,7 +92,8 @@ public void RepeatDeclaration( this.resolver, this.replacePatternHandlerFactories, this.ignoreUsingList, - this.selectorResolver)); + this.selectorResolver, + this.replacePatternResolver)); } } diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedGenericStrategy.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedGenericStrategy.cs index 5ae7d58..ad2bb77 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedGenericStrategy.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedGenericStrategy.cs @@ -30,6 +30,7 @@ internal class AutomatedGenericStrategy : IAutomatedStrategy private readonly IDeclarationResolver resolver; private readonly IEnumerable ignoreUsingList; private readonly ISelectorResolver selectorResolver; + private readonly IReplacePatternResolver replacePatternResolver; private readonly string targetDeclarationName; private readonly string targetPatternName; private readonly IEnumerable replacePatternHandlers; @@ -40,7 +41,8 @@ public AutomatedGenericStrategy( IDeclarationResolver resolver, IEnumerable replacePatternHandlerFactories, IEnumerable ignoreUsingList, - ISelectorResolver selectorResolver) + ISelectorResolver selectorResolver, + IReplacePatternResolver replacePatternResolver) { this.declaration = declaration; this.pattern = pattern; @@ -49,7 +51,7 @@ public AutomatedGenericStrategy( this.targetDeclarationName = GeneratorHelper.ComputeClassName(declaration.Name); this.targetPatternName = GeneratorHelper.ComputeClassName(pattern.Name); this.selectorResolver = selectorResolver; - + this.replacePatternResolver = replacePatternResolver; this.replacePatternHandlers = replacePatternHandlerFactories.Select(f => f.Setup(pattern, declaration)).ToArray(); } @@ -58,6 +60,11 @@ public IReplacePatternHandler CreateReplacePatternHandler() return new StrategyReplacePatternHandler(ApplyPatternReplace); } + public IReplacePatternHandler CreateReplacePatternHandler(AttributeSyntax replacePatternAttributeSyntax) + { + throw new NotImplementedException(); + } + public string ApplyPatternReplace(string text) { string result; @@ -152,7 +159,7 @@ public void RepeatDeclaration( { foreach (var methodDeclaration in selector.GetMethods(this.declaration)) { - var strategy = new AutomatedMethodStrategy(repeatMethod, methodDeclaration, this.resolver, this.declaration, patternPrefix, patternSuffix); + var strategy = new AutomatedMethodStrategy(repeatMethod, methodDeclaration, this.resolver, this.declaration, patternPrefix, patternSuffix, this.replacePatternResolver); callback(strategy); } @@ -255,7 +262,7 @@ public bool TryMatchAndRepeatStatement( { foreach (var methodDeclaration in selector.GetMethods(this.declaration)) { - var strategy = new AutomatedMethodStrategy(repeatMethod, methodDeclaration, this.resolver, this.declaration, patternPrefix, patternSuffix); + var strategy = new AutomatedMethodStrategy(repeatMethod, methodDeclaration, this.resolver, this.declaration, patternPrefix, patternSuffix, this.replacePatternResolver); callback(strategy); } diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedMethodStrategy.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedMethodStrategy.cs index 24b1899..82cf298 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedMethodStrategy.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedMethodStrategy.cs @@ -16,6 +16,7 @@ using SoloX.GeneratorTools.Core.CSharp.Generator.ReplacePattern; using SoloX.GeneratorTools.Core.CSharp.Model; using SoloX.GeneratorTools.Core.CSharp.Model.Resolver; +using SoloX.GeneratorTools.Core.CSharp.Model.Use; namespace SoloX.GeneratorTools.Core.CSharp.Generator.Impl.Walker { @@ -25,6 +26,7 @@ internal class AutomatedMethodStrategy : IAutomatedStrategy private readonly IMethodDeclaration declaration; private readonly IDeclarationResolver resolver; private readonly IGenericDeclaration genericDeclaration; + private readonly IReplacePatternResolver replacePatternResolver; private readonly TextPatternHelper textReplaceHelper; private readonly TextPatternHelper typeReplaceHelper; @@ -33,13 +35,14 @@ public AutomatedMethodStrategy( IMethodDeclaration declaration, IDeclarationResolver resolver, IGenericDeclaration genericDeclaration, - string patternPrefix, string patternSuffix) + string patternPrefix, string patternSuffix, + IReplacePatternResolver replacePatternResolver) { this.pattern = pattern; this.declaration = declaration; this.resolver = resolver; this.genericDeclaration = genericDeclaration; - + this.replacePatternResolver = replacePatternResolver; var patternName = this.pattern.Name; var declarationName = this.declaration.Name; @@ -55,6 +58,18 @@ public IReplacePatternHandler CreateReplacePatternHandler() return new StrategyReplacePatternHandler(ApplyPatternReplace); } + public IReplacePatternHandler CreateReplacePatternHandler(AttributeSyntax replacePatternAttributeSyntax) + { + var replaceHandlerTypeExpression = replacePatternAttributeSyntax.ArgumentList.Arguments.First().Expression; + + var constEvaluator = new ConstantExpressionSyntaxEvaluator>(this.resolver, this.genericDeclaration); + var typeUse = constEvaluator.Visit(replaceHandlerTypeExpression); + + var factory = this.replacePatternResolver.GetHandlerFactory(typeUse); + + return factory.Setup(this.pattern, this.declaration); + } + private string ApplyPatternReplace(string text) { var result = this.textReplaceHelper.ReplacePattern(text); diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedParameterStrategy.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedParameterStrategy.cs index 3558a36..ef6f3ec 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedParameterStrategy.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedParameterStrategy.cs @@ -54,6 +54,11 @@ public IReplacePatternHandler CreateReplacePatternHandler() return new StrategyReplacePatternHandler(ApplyPatternReplace); } + public IReplacePatternHandler CreateReplacePatternHandler(AttributeSyntax replacePatternAttributeSyntax) + { + throw new NotImplementedException(); + } + private string ApplyPatternReplace(string text) { var result = this.textReplaceHelper.ReplacePattern(text); diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedPropertyStrategy.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedPropertyStrategy.cs index 5e5db86..08a977b 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedPropertyStrategy.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedPropertyStrategy.cs @@ -46,6 +46,11 @@ public IReplacePatternHandler CreateReplacePatternHandler() return new StrategyReplacePatternHandler(ApplyPatternReplace); } + public IReplacePatternHandler CreateReplacePatternHandler(AttributeSyntax replacePatternAttributeSyntax) + { + throw new NotImplementedException(); + } + private string ApplyPatternReplace(string text) { var result = this.textReplaceHelper.ReplacePattern(text); diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedWalker.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedWalker.cs index 60a045f..a5658bc 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedWalker.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/AutomatedWalker.cs @@ -1014,6 +1014,12 @@ private void WriteConstructorDeclaration(ConstructorDeclarationSyntax node) private void WriteMethodDeclaration(MethodDeclarationSyntax node) { + IReplacePatternHandler replacePatternHandler = null; + if (node.AttributeLists.TryMatchAttributeName(out var replaceAttributeSyntax)) + { + replacePatternHandler = this.CurrentStrategy().CreateReplacePatternHandler(replaceAttributeSyntax); + } + this.WriteAttributeLists(node.AttributeLists); this.Write(node.Modifiers.ToFullString()); @@ -1037,8 +1043,23 @@ private void WriteMethodDeclaration(MethodDeclarationSyntax node) }); } + if (node.AttributeLists.TryMatchAttributeName(out var attributeSyntax, true)) + { + CurrentStrategy().RepeatDeclaration( + attributeSyntax, + itemStrategy => + { + PushStrategy(itemStrategy); + }); + } + this.Visit(node.ParameterList); + if (replacePatternHandler != null) + { + this.strategiesReplacePatternHandlers.Push(replacePatternHandler); + } + foreach (var constraintClauses in node.ConstraintClauses) { this.WriteNode(constraintClauses); @@ -1048,6 +1069,11 @@ private void WriteMethodDeclaration(MethodDeclarationSyntax node) this.Visit(node.ExpressionBody); this.Write(node.SemicolonToken.ToFullString()); + if (replacePatternHandler != null) + { + PopReplacePatternHandlers(); + } + this.strategies = savedStrategies; } diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/IAutomatedStrategy.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/IAutomatedStrategy.cs index a31c8d7..e80d92c 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/IAutomatedStrategy.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/Impl/Walker/IAutomatedStrategy.cs @@ -52,6 +52,13 @@ void RepeatDeclaration( AttributeSyntax repeatAttributeSyntax, Action callback); + /// + /// Create the IReplacePatternHandler from the current strategy. + /// + /// ReplacePatternAttribute node + /// + IReplacePatternHandler CreateReplacePatternHandler(AttributeSyntax replacePatternAttributeSyntax); + /// /// Create the IReplacePatternHandler from the current strategy. /// diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/IReplacePatternHandlerFactory.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/IReplacePatternHandlerFactory.cs index c23868f..7d2741a 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/IReplacePatternHandlerFactory.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/IReplacePatternHandlerFactory.cs @@ -25,5 +25,13 @@ public interface IReplacePatternHandlerFactory IReplacePatternHandler Setup( IGenericDeclaration pattern, IGenericDeclaration declaration); + + /// + /// Setup replace handler. + /// + /// The method pattern. + /// The method declaration. + /// + IReplacePatternHandler Setup(IMethodDeclaration pattern, IMethodDeclaration declaration); } } diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/IReplacePatternResolver.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/IReplacePatternResolver.cs new file mode 100644 index 0000000..4871e5b --- /dev/null +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/IReplacePatternResolver.cs @@ -0,0 +1,26 @@ +// ---------------------------------------------------------------------- +// +// Copyright © 2021 Xavier Solau. +// Licensed under the MIT license. +// See LICENSE file in the project root for full license information. +// +// ---------------------------------------------------------------------- + +using Microsoft.CodeAnalysis; +using SoloX.GeneratorTools.Core.CSharp.Model.Use; + +namespace SoloX.GeneratorTools.Core.CSharp.Generator.ReplacePattern +{ + /// + /// ReplacePatternHandler resolver instantiating handler factory from a given name. + /// + public interface IReplacePatternResolver + { + /// + /// Try get a handler factory matching a given name. + /// + /// + /// + IReplacePatternHandlerFactory GetHandlerFactory(IDeclarationUse replacePatternHandlerTypeUse); + } +} diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/TaskValueTypeReplaceHandler.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/TaskValueTypeReplaceHandler.cs new file mode 100644 index 0000000..2af06f9 --- /dev/null +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Generator/ReplacePattern/TaskValueTypeReplaceHandler.cs @@ -0,0 +1,79 @@ +// ---------------------------------------------------------------------- +// +// Copyright © 2021 Xavier Solau. +// Licensed under the MIT license. +// See LICENSE file in the project root for full license information. +// +// ---------------------------------------------------------------------- + +using Microsoft.CodeAnalysis; +using SoloX.GeneratorTools.Core.CSharp.Model; +using SoloX.GeneratorTools.Core.CSharp.Model.Use; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace SoloX.GeneratorTools.Core.CSharp.Generator.ReplacePattern +{ + /// + /// Task Value type replace handler. + /// + public class TaskValueTypeReplaceHandler : IReplacePatternHandlerFactory, IReplacePatternHandler + { + private string patternName; + private string declarationName; + + /// + public string ApplyOn(string patternText) + { + if (patternText == null) + { + throw new ArgumentNullException(nameof(patternText)); + } + + return patternText.Replace(this.patternName, this.declarationName); + } + + /// + public IReplacePatternHandler Setup(IGenericDeclaration pattern, IGenericDeclaration declaration) + { + throw new System.NotImplementedException(); + } + + /// + public IReplacePatternHandler Setup(IMethodDeclaration pattern, IMethodDeclaration declaration) + { + if (pattern == null) + { + throw new ArgumentNullException(nameof(pattern)); + } + + if (declaration == null) + { + throw new ArgumentNullException(nameof(declaration)); + } + + if (pattern.ReturnType is IGenericDeclarationUse patternUse + && (patternUse.Declaration.FullName == typeof(Task).FullName || patternUse.Declaration.FullName == typeof(ValueTask).FullName + || patternUse.Declaration.Name == nameof(Task) || patternUse.Declaration.Name == nameof(ValueTask))) + { + var patternAsyncReturnType = patternUse.GenericParameters.First(); + + this.patternName = patternAsyncReturnType.SyntaxNodeProvider.SyntaxNode.ToString(); + + if (declaration.ReturnType is IGenericDeclarationUse declarationUse + && (declarationUse.Declaration.FullName == typeof(Task).FullName || declarationUse.Declaration.FullName == typeof(ValueTask).FullName + || declarationUse.Declaration.Name == nameof(Task) || declarationUse.Declaration.Name == nameof(ValueTask))) + { + var declarationAsyncReturnType = declarationUse.GenericParameters.First(); + + this.declarationName = declarationAsyncReturnType.SyntaxNodeProvider.SyntaxNode.ToString(); + + return this; + } + + } + return null; + } + } +} diff --git a/src/libs/SoloX.GeneratorTools.Core.CSharp/Utils/AttributeSyntaxHelper.cs b/src/libs/SoloX.GeneratorTools.Core.CSharp/Utils/AttributeSyntaxHelper.cs index 08805af..e6229e8 100644 --- a/src/libs/SoloX.GeneratorTools.Core.CSharp/Utils/AttributeSyntaxHelper.cs +++ b/src/libs/SoloX.GeneratorTools.Core.CSharp/Utils/AttributeSyntaxHelper.cs @@ -25,16 +25,18 @@ public static class AttributeSyntaxHelper /// Attribute type to match. /// The attribute syntax lists to test. /// The attribute syntax node that match the attribute type. + /// Tells if we are looking for a return value target attribute. /// True if the attribute type name match one of the attribute syntax node. public static bool TryMatchAttributeName( this SyntaxList attributeLists, - out AttributeSyntax attributeSyntax) + out AttributeSyntax attributeSyntax, + bool targetReturnValue = false) where TAttribute : Attribute { attributeSyntax = null; foreach (var attributeList in attributeLists) { - if (attributeList.TryMatchAttributeName(out attributeSyntax)) + if (attributeList.TryMatchAttributeName(out attributeSyntax, targetReturnValue)) { return true; } @@ -77,14 +79,16 @@ public static bool TryMatchAttributeName( /// Attribute type to match. /// The attribute syntax lists to test. /// The matching attribute syntax node. + /// Tells if we are looking for a return value target attribute. /// True if the attribute type name match one of the attribute syntax node. public static bool TryMatchAttributeName( this AttributeListSyntax attributeLists, - out AttributeSyntax matchingAttributeSyntax) + out AttributeSyntax matchingAttributeSyntax, + bool targetReturnValue = false) where TAttribute : Attribute { matchingAttributeSyntax = null; - if (attributeLists != null) + if (attributeLists != null && ((!targetReturnValue && attributeLists.Target == null) || (targetReturnValue && attributeLists.Target != null))) { foreach (var attributeSyntax in attributeLists.Attributes) { diff --git a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/AutomatedGeneratorTest.cs b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/AutomatedGeneratorTest.cs index fcf36ce..49dfad9 100644 --- a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/AutomatedGeneratorTest.cs +++ b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/AutomatedGeneratorTest.cs @@ -139,6 +139,40 @@ public void AutomatedSimpleMethod5Test() declarationInterfaceFile); } + [Fact] + public void AutomatedSimpleMethod6Test() + { + var patternInterfaceFile = @"Generator/Automated/Patterns/Itf/ISimpleMethodPattern.cs"; + var patternImplementationFile = @"Generator/Automated/Patterns/Impl/SimpleMethod6Pattern.cs"; + var declarationInterfaceFile = @"Generator/Automated/Samples/ISimpleMethodSample.cs"; + var targetNameSpace = "SoloX.GeneratorTools.Core.CSharp.ITest"; + + GenerateAndAssertSnapshot( + typeof(SimpleMethod6Pattern), + patternInterfaceFile, + patternImplementationFile, + targetNameSpace, + nameof(this.AutomatedSimpleMethod6Test), + declarationInterfaceFile); + } + + [Fact] + public void AutomatedAsyncMethodTest() + { + var patternInterfaceFile = @"Generator/Automated/Patterns/Itf/IAsyncMethodPattern.cs"; + var patternImplementationFile = @"Generator/Automated/Patterns/Impl/AsyncMethodPattern.cs"; + var declarationInterfaceFile = @"Generator/Automated/Samples/IAsyncMethodSample.cs"; + var targetNameSpace = "SoloX.GeneratorTools.Core.CSharp.ITest"; + + GenerateAndAssertSnapshot( + typeof(AsyncMethodPattern), + patternInterfaceFile, + patternImplementationFile, + targetNameSpace, + nameof(this.AutomatedAsyncMethodTest), + declarationInterfaceFile); + } + [Fact] public void AutomatedSimpleWithCallTest() { @@ -345,7 +379,7 @@ private void GenerateAndAssertSnapshot( var selectorResolver = CreateSelectorResolver(); var implGenerator = new AutomatedGenerator( - snapshotGenerator, locator, resolver, patternType, selectorResolver, Mock.Of()); + snapshotGenerator, locator, resolver, patternType, Mock.Of(), selectorResolver: selectorResolver); implGenerator.Generate(files); diff --git a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Impl/AsyncMethodPattern.cs b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Impl/AsyncMethodPattern.cs new file mode 100644 index 0000000..a838c01 --- /dev/null +++ b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Impl/AsyncMethodPattern.cs @@ -0,0 +1,27 @@ +// ---------------------------------------------------------------------- +// +// Copyright © 2021 Xavier Solau. +// Licensed under the MIT license. +// See LICENSE file in the project root for full license information. +// +// ---------------------------------------------------------------------- + +using SoloX.GeneratorTools.Core.CSharp.Generator.Attributes; +using SoloX.GeneratorTools.Core.CSharp.Generator.ReplacePattern; +using SoloX.GeneratorTools.Core.CSharp.ITest.Generator.Automated.Patterns.Itf; +using System.Threading.Tasks; + +namespace SoloX.GeneratorTools.Core.CSharp.ITest.Generator.Automated.Patterns.Impl +{ + [Pattern] + [Repeat(Pattern = nameof(IAsyncMethodPattern), Prefix = "I")] + public class AsyncMethodPattern : IAsyncMethodPattern + { + [Repeat(Pattern = nameof(IAsyncMethodPattern.PatternMethodAsync))] + [ReplacePattern(typeof(TaskValueTypeReplaceHandler))] + public Task PatternMethodAsync([Repeat(Pattern = "someArgument")] object someArgument) + { + return Task.FromResult(default); + } + } +} diff --git a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Impl/SimpleMethod6Pattern.cs b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Impl/SimpleMethod6Pattern.cs new file mode 100644 index 0000000..8138a74 --- /dev/null +++ b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Impl/SimpleMethod6Pattern.cs @@ -0,0 +1,56 @@ +// ---------------------------------------------------------------------- +// +// Copyright © 2021 Xavier Solau. +// Licensed under the MIT license. +// See LICENSE file in the project root for full license information. +// +// ---------------------------------------------------------------------- + +using SoloX.GeneratorTools.Core.CSharp.Generator; +using SoloX.GeneratorTools.Core.CSharp.Generator.Attributes; +using SoloX.GeneratorTools.Core.CSharp.ITest.Generator.Automated.Patterns.Itf; +using System; + +namespace SoloX.GeneratorTools.Core.CSharp.ITest.Generator.Automated.Patterns.Impl +{ + [Pattern] + [Repeat(Pattern = nameof(ISimpleMethodPattern), Prefix = "I")] + public class SimpleMethod6Pattern : ISimpleMethodPattern + { + [Repeat(Pattern = nameof(ISimpleMethodPattern.PatternMethod))] +#pragma warning disable CA1034 // Nested types should not be visible + public class PatternMethodPayload + { + [Repeat(Pattern = "someArgument")] + public object SomeArgument { get; set; } + } +#pragma warning restore CA1034 // Nested types should not be visible + + + + [Repeat(Pattern = nameof(ISimpleMethodPattern.PatternMethod))] + public object PatternMethod([Repeat(Pattern = "someArgument")] object someArgument) + { + var payload = new PatternMethodPayload + { + SomeArgument = Repeat.Affectation("someArgument", someArgument), + }; + + return ProcessPatternMethodPayload(payload); + } + + [Repeat(Pattern = nameof(ISimpleMethodPattern.PatternMethod))] + [return: Repeat(Pattern = "someArgument")] + private object ProcessPatternMethodPayload(PatternMethodPayload payload) + { + var someArgument = Repeat.Affectation("someArgument", payload.SomeArgument); + + return Process(Repeat.Argument("someArgument", someArgument)); + } + + private object Process(params object[] arguments) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Itf/IAsyncMethodPattern.cs b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Itf/IAsyncMethodPattern.cs new file mode 100644 index 0000000..7c7ff38 --- /dev/null +++ b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/Itf/IAsyncMethodPattern.cs @@ -0,0 +1,17 @@ +// ---------------------------------------------------------------------- +// +// Copyright © 2021 Xavier Solau. +// Licensed under the MIT license. +// See LICENSE file in the project root for full license information. +// +// ---------------------------------------------------------------------- + +using System.Threading.Tasks; + +namespace SoloX.GeneratorTools.Core.CSharp.ITest.Generator.Automated.Patterns.Itf +{ + public interface IAsyncMethodPattern + { + Task PatternMethodAsync(object someArgument); + } +} diff --git a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/MultiSelector.cs b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/MultiSelector.cs index f155899..5d209f4 100644 --- a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/MultiSelector.cs +++ b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Patterns/MultiSelector.cs @@ -26,7 +26,13 @@ public IEnumerable> GetDeclarations(IEnumerable file.Declarations) - .Where(d => d.Name == nameof(ISimpleSample) || d.Name == nameof(IOtherSample) || d.Name == nameof(IConstSample) || d.Name == nameof(IRepeatSample) || d.Name == nameof(IAttributeSelectorSample) || d.Name == nameof(ISimpleMethodSample)); + .Where(d => d.Name == nameof(ISimpleSample) + || d.Name == nameof(IOtherSample) + || d.Name == nameof(IConstSample) + || d.Name == nameof(IRepeatSample) + || d.Name == nameof(IAttributeSelectorSample) + || d.Name == nameof(ISimpleMethodSample) + || d.Name == nameof(IAsyncMethodSample)); } public IEnumerable GetMethods(IGenericDeclaration declaration) diff --git a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Samples/IAsyncMethodSample.cs b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Samples/IAsyncMethodSample.cs new file mode 100644 index 0000000..2d367de --- /dev/null +++ b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Samples/IAsyncMethodSample.cs @@ -0,0 +1,24 @@ +// ---------------------------------------------------------------------- +// +// Copyright © 2021 Xavier Solau. +// Licensed under the MIT license. +// See LICENSE file in the project root for full license information. +// +// ---------------------------------------------------------------------- + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace SoloX.GeneratorTools.Core.CSharp.ITest.Generator.Automated.Samples +{ + public interface IAsyncMethodSample + { + Task Method(); + + Task Method1(string arg); + + Task Method2(int arg1, string arg2); + + Task> Method3(); + } +} diff --git a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Snapshots/AutomatedAsyncMethodTest.snapshot b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Snapshots/AutomatedAsyncMethodTest.snapshot new file mode 100644 index 0000000..f0d340e --- /dev/null +++ b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Snapshots/AutomatedAsyncMethodTest.snapshot @@ -0,0 +1,37 @@ +--------------------- +AsyncMethodSample +--------------------- +// ---------------------------------------------------------------------- +// +// Copyright © 2021 Xavier Solau. +// Licensed under the MIT license. +// See LICENSE file in the project root for full license information. +// +// ---------------------------------------------------------------------- + +using SoloX.GeneratorTools.Core.CSharp.ITest.Generator.Automated.Samples; +using System.Threading.Tasks; + +namespace SoloX.GeneratorTools.Core.CSharp.ITest.Generator.Automated.Samples +{ + public class AsyncMethodSample : IAsyncMethodSample + { + public Task Method() + { + return Task.FromResult(default); + } + public Task Method1(string arg) + { + return Task.FromResult(default); + } + public Task Method2(int arg1, string arg2) + { + return Task.FromResult(default); + } + public Task> Method3() + { + return Task.FromResult>(default); + } + } +} + diff --git a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Snapshots/AutomatedSimpleMethod6Test.snapshot b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Snapshots/AutomatedSimpleMethod6Test.snapshot new file mode 100644 index 0000000..4f294d1 --- /dev/null +++ b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/Generator/Automated/Snapshots/AutomatedSimpleMethod6Test.snapshot @@ -0,0 +1,93 @@ +--------------------- +SimpleMethod6Pattern +--------------------- +using SoloX.GeneratorTools.Core.CSharp.ITest.Generator.Automated.Samples; +using System; + +namespace SoloX.GeneratorTools.Core.CSharp.ITest.Generator.Automated.Samples +{ + public class SimpleMethod6Pattern : ISimpleMethodSample + { +#pragma warning disable CA1034 // Nested types should not be visible + public class MethodPayload + { + } +#pragma warning disable CA1034 // Nested types should not be visible + public class Method1Payload + { + public string Arg { get; set; } + } +#pragma warning disable CA1034 // Nested types should not be visible + public class Method2Payload + { + public int Arg1 { get; set; } + public double Arg2 { get; set; } + } +#pragma warning restore CA1034 // Nested types should not be visible + + + + public int Method() + { + var payload = new MethodPayload + { + }; + + return ProcessMethodPayload(payload); + } +#pragma warning restore CA1034 // Nested types should not be visible + + + + public int Method1(string arg) + { + var payload = new Method1Payload + { + Arg = arg, + }; + + return ProcessMethod1Payload(payload); + } +#pragma warning restore CA1034 // Nested types should not be visible + + + + public double Method2(int arg1, double arg2) + { + var payload = new Method2Payload + { + Arg1 = arg1, + Arg2 = arg2, + }; + + return ProcessMethod2Payload(payload); + } + + private int ProcessMethodPayload(MethodPayload payload) + { + + return Process(); + } + + private int ProcessMethod1Payload(Method1Payload payload) + { + var arg = payload.Arg; + + return Process(arg); + } + + private double ProcessMethod2Payload(Method2Payload payload) + { + var arg1 = payload.Arg1; + var arg2 = payload.Arg2; + + return Process(arg1, arg2); + } + + private object Process(params object[] arguments) + { + throw new NotImplementedException(); + } + } +} + diff --git a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/SoloX.GeneratorTools.Core.CSharp.ITest.csproj b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/SoloX.GeneratorTools.Core.CSharp.ITest.csproj index 6b18516..f599342 100644 --- a/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/SoloX.GeneratorTools.Core.CSharp.ITest.csproj +++ b/src/tests/SoloX.GeneratorTools.Core.CSharp.ITest/SoloX.GeneratorTools.Core.CSharp.ITest.csproj @@ -43,4 +43,10 @@ + + + PreserveNewest + + + diff --git a/src/tools/SoloX.GeneratorTools.Generator/Impl/ToolsGenerator.cs b/src/tools/SoloX.GeneratorTools.Generator/Impl/ToolsGenerator.cs index 6493664..0b21c61 100644 --- a/src/tools/SoloX.GeneratorTools.Generator/Impl/ToolsGenerator.cs +++ b/src/tools/SoloX.GeneratorTools.Generator/Impl/ToolsGenerator.cs @@ -68,14 +68,11 @@ internal void Generate(ICSharpWorkspace workspace, RelativeLocator locator, IWri var resolver = workspace.DeepLoad(); - var selectorResolver = new DefaultSelectorResolver(); - var generator1 = new AutomatedGenerator( fileGenerator, locator, resolver, typeof(IFactoryPattern), - selectorResolver, this.logger); var generatedItems1 = generator1.Generate(files); @@ -85,7 +82,6 @@ internal void Generate(ICSharpWorkspace workspace, RelativeLocator locator, IWri locator, resolver, typeof(FactoryPattern), - selectorResolver, this.logger); var generatedItems2 = generator2.Generate(files); @@ -95,7 +91,6 @@ internal void Generate(ICSharpWorkspace workspace, RelativeLocator locator, IWri locator, resolver, typeof(ObjectPattern), - selectorResolver, this.logger); var generatedItems3 = generator3.Generate(files);