From 5ea8c6075ce2f0f97ef58a5881058c2a4a375981 Mon Sep 17 00:00:00 2001 From: Cezary Piatek Date: Thu, 20 Sep 2018 20:47:03 +0200 Subject: [PATCH] Improve converting plural to singular form for lambda parameter name --- .../MappingGeneratorTestCases.Designer.cs | 261 ++++++++++++++++++ .../MappingGeneratorTestCases.resx | 24 ++ .../MappingGenerator/MappingGeneratorTests.cs | 27 ++ ...MappingWithSingularLambdaParameterName.txt | 25 ++ ...gWithSingularLambdaParameterName_FIXED.txt | 30 ++ ...MappingWithPrefixedLambdaParameterName.txt | 26 ++ ...WithPrefixedLambdaParameterName_FIXED..txt | 31 +++ .../014_CollectionMappingWithGenericName.txt | 26 ++ ...CollectionMappingWithGenericName_FIXED.txt | 31 +++ ...ollectionMappingWithPostfixGenericName.txt | 26 ++ ...ionMappingWithPostfixGenericName_FIXED.txt | 31 +++ .../MappingGenerator/MappingEngine.cs | 100 ++++--- .../ObjectMembersMappingSourceFinder.cs | 4 +- 13 files changed, 603 insertions(+), 39 deletions(-) create mode 100644 MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/012_CollectionMappingWithSingularLambdaParameterName.txt create mode 100644 MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/012_CollectionMappingWithSingularLambdaParameterName_FIXED.txt create mode 100644 MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/013_CollectionMappingWithPrefixedLambdaParameterName.txt create mode 100644 MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/013_CollectionMappingWithPrefixedLambdaParameterName_FIXED..txt create mode 100644 MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/014_CollectionMappingWithGenericName.txt create mode 100644 MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/014_CollectionMappingWithGenericName_FIXED.txt create mode 100644 MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/015_CollectionMappingWithPostfixGenericName.txt create mode 100644 MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/015_CollectionMappingWithPostfixGenericName_FIXED.txt diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTestCases.Designer.cs b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTestCases.Designer.cs index 6955eb8..413a502 100644 --- a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTestCases.Designer.cs +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTestCases.Designer.cs @@ -601,5 +601,266 @@ internal static string _011_IdentityFunctionMappingForCollection_FIXED { return ResourceManager.GetString("_011_IdentityFunctionMappingForCollection_FIXED", resourceCulture); } } + + /// + /// Looks up a localized string similar to using System; + ///using System.Collections.Generic; + ///using System.Linq; + /// + ///namespace TestAutoMapper.Identity.X + ///{ + /// public class XX + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public class YY + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public static class Mapper{ + /// + /// public static List<YY> [|Map|](List<XX> categories) + /// { + /// } + /// } + ///}. + /// + internal static string _012_CollectionMappingWithSingularLambdaParameterName { + get { + return ResourceManager.GetString("_012_CollectionMappingWithSingularLambdaParameterName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to using System; + ///using System.Collections.Generic; + ///using System.Linq; + /// + ///namespace TestAutoMapper.Identity.X + ///{ + /// public class XX + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public class YY + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public static class Mapper{ + /// + /// public static List<YY> Map(List<XX> categories) + /// { + /// return categories.Select(category => new YY() + /// [rest of string was truncated]";. + /// + internal static string _012_CollectionMappingWithSingularLambdaParameterName_FIXED { + get { + return ResourceManager.GetString("_012_CollectionMappingWithSingularLambdaParameterName_FIXED", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to using System; + ///using System.Collections.Generic; + ///using System.Collections.ObjectModel; + ///using System.Linq; + /// + ///namespace TestAutoMapper.Identity.X + ///{ + /// public class XX + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public class ZZ + /// { + /// public int CategoryId { get; set; } + /// public string CategoryName { get; set; } + /// } + /// + /// public static class Mapper{ + /// + /// public static List<ZZ> [|MapNew|](List<XX> categories) + /// { + /// [rest of string was truncated]";. + /// + internal static string _013_CollectionMappingWithPrefixedLambdaParameterName { + get { + return ResourceManager.GetString("_013_CollectionMappingWithPrefixedLambdaParameterName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to using System; + ///using System.Collections.Generic; + ///using System.Collections.ObjectModel; + ///using System.Linq; + /// + ///namespace TestAutoMapper.Identity.X + ///{ + /// public class XX + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public class ZZ + /// { + /// public int CategoryId { get; set; } + /// public string CategoryName { get; set; } + /// } + /// + /// public static class Mapper{ + /// + /// public static List<ZZ> MapNew(List<XX> categories) + /// { + /// [rest of string was truncated]";. + /// + internal static string _013_CollectionMappingWithPrefixedLambdaParameterName_FIXED_ { + get { + return ResourceManager.GetString("_013_CollectionMappingWithPrefixedLambdaParameterName_FIXED_", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to using System; + ///using System.Collections.Generic; + ///using System.Collections.ObjectModel; + ///using System.Linq; + /// + ///namespace TestAutoMapper.Identity.X + ///{ + /// public class XX + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public class ZZ + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public static class Mapper{ + /// + /// public static List<ZZ> [|MapNew|](List<XX> dictionary) + /// { + /// } + /// } + ///}. + /// + internal static string _014_CollectionMappingWithGenericName { + get { + return ResourceManager.GetString("_014_CollectionMappingWithGenericName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to using System; + ///using System.Collections.Generic; + ///using System.Collections.ObjectModel; + ///using System.Linq; + /// + ///namespace TestAutoMapper.Identity.X + ///{ + /// public class XX + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public class ZZ + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public static class Mapper{ + /// + /// public static List<ZZ> MapNew(List<XX> dictionary) + /// { + /// return dict [rest of string was truncated]";. + /// + internal static string _014_CollectionMappingWithGenericName_FIXED { + get { + return ResourceManager.GetString("_014_CollectionMappingWithGenericName_FIXED", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to using System; + ///using System.Collections.Generic; + ///using System.Collections.ObjectModel; + ///using System.Linq; + /// + ///namespace TestAutoMapper.Identity.X + ///{ + /// public class XX + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public class ZZ + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public static class Mapper{ + /// + /// public static List<ZZ> [|MapNew|](List<XX> usersList) + /// { + /// } + /// } + ///}. + /// + internal static string _015_CollectionMappingWithPostfixGenericName { + get { + return ResourceManager.GetString("_015_CollectionMappingWithPostfixGenericName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to using System; + ///using System.Collections.Generic; + ///using System.Collections.ObjectModel; + ///using System.Linq; + /// + ///namespace TestAutoMapper.Identity.X + ///{ + /// public class XX + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public class ZZ + /// { + /// public int Id { get; set; } + /// public string Name { get; set; } + /// } + /// + /// public static class Mapper{ + /// + /// public static List<ZZ> MapNew(List<XX> usersList) + /// { + /// return users [rest of string was truncated]";. + /// + internal static string _015_CollectionMappingWithPostfixGenericName_FIXED { + get { + return ResourceManager.GetString("_015_CollectionMappingWithPostfixGenericName_FIXED", resourceCulture); + } + } } } diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTestCases.resx b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTestCases.resx index ef637d5..5b9bbfa 100644 --- a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTestCases.resx +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTestCases.resx @@ -184,4 +184,28 @@ TestCaseData\011_IdentityFunctionMappingForCollection_FIXED.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + TestCaseData\012_CollectionMappingWithSingularLambdaParameterName.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + TestCaseData\012_CollectionMappingWithSingularLambdaParameterName_FIXED.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + TestCaseData\013_CollectionMappingWithPrefixedLambdaParameterName.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + TestCaseData\013_CollectionMappingWithPrefixedLambdaParameterName_FIXED..txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + TestCaseData\014_CollectionMappingWithGenericName.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + TestCaseData\014_CollectionMappingWithGenericName_FIXED.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + TestCaseData\015_CollectionMappingWithPostfixGenericName.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + TestCaseData\015_CollectionMappingWithPostfixGenericName_FIXED.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + \ No newline at end of file diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTests.cs b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTests.cs index a42050e..dbc54b7 100644 --- a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTests.cs +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/MappingGeneratorTests.cs @@ -75,6 +75,33 @@ public void should_be_able_to_generate_identity_mapping_function_for_collections TestCodeRefactoring(_011_IdentityFunctionMappingForCollection, _011_IdentityFunctionMappingForCollection_FIXED); } + [Test] + public void should_be_able_to_generate_collection_mapping_with_lambda_parameter_name_in_singular_form() + { + TestCodeRefactoring(_012_CollectionMappingWithSingularLambdaParameterName, _012_CollectionMappingWithSingularLambdaParameterName_FIXED); + } + + + [Test] + public void should_be_able_to_generate_collection_mapping_with_lambda_parameter_name_with_variable_name_as_prefix() + { + TestCodeRefactoring(_013_CollectionMappingWithPrefixedLambdaParameterName, _013_CollectionMappingWithPrefixedLambdaParameterName_FIXED_); + } + + + [Test] + public void should_be_able_to_generate_collection_mapping_with_lambda_parameter_from_generic_name() + { + TestCodeRefactoring(_014_CollectionMappingWithGenericName, _014_CollectionMappingWithGenericName_FIXED); + } + + + [Test] + public void should_be_able_to_generate_collection_mapping_with_lambda_parameter_from_postfiex_generic_name() + { + TestCodeRefactoring(_015_CollectionMappingWithPostfixGenericName, _015_CollectionMappingWithPostfixGenericName_FIXED); + } + protected override string LanguageName => LanguageNames.CSharp; protected override CodeRefactoringProvider CreateProvider() diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/012_CollectionMappingWithSingularLambdaParameterName.txt b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/012_CollectionMappingWithSingularLambdaParameterName.txt new file mode 100644 index 0000000..d94fe10 --- /dev/null +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/012_CollectionMappingWithSingularLambdaParameterName.txt @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace TestAutoMapper.Identity.X +{ + public class XX + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class YY + { + public int Id { get; set; } + public string Name { get; set; } + } + + public static class Mapper{ + + public static List [|Map|](List categories) + { + } + } +} \ No newline at end of file diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/012_CollectionMappingWithSingularLambdaParameterName_FIXED.txt b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/012_CollectionMappingWithSingularLambdaParameterName_FIXED.txt new file mode 100644 index 0000000..75be809 --- /dev/null +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/012_CollectionMappingWithSingularLambdaParameterName_FIXED.txt @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace TestAutoMapper.Identity.X +{ + public class XX + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class YY + { + public int Id { get; set; } + public string Name { get; set; } + } + + public static class Mapper{ + + public static List Map(List categories) + { + return categories.Select(category => new YY() + { + Id = category.Id, + Name = category.Name + }).ToList(); + } + } +} \ No newline at end of file diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/013_CollectionMappingWithPrefixedLambdaParameterName.txt b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/013_CollectionMappingWithPrefixedLambdaParameterName.txt new file mode 100644 index 0000000..880846d --- /dev/null +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/013_CollectionMappingWithPrefixedLambdaParameterName.txt @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace TestAutoMapper.Identity.X +{ + public class XX + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class ZZ + { + public int CategoryId { get; set; } + public string CategoryName { get; set; } + } + + public static class Mapper{ + + public static List [|MapNew|](List categories) + { + } + } +} \ No newline at end of file diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/013_CollectionMappingWithPrefixedLambdaParameterName_FIXED..txt b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/013_CollectionMappingWithPrefixedLambdaParameterName_FIXED..txt new file mode 100644 index 0000000..8d3eea5 --- /dev/null +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/013_CollectionMappingWithPrefixedLambdaParameterName_FIXED..txt @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace TestAutoMapper.Identity.X +{ + public class XX + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class ZZ + { + public int CategoryId { get; set; } + public string CategoryName { get; set; } + } + + public static class Mapper{ + + public static List MapNew(List categories) + { + return categories.Select(category => new ZZ() + { + CategoryId = category.Id, + CategoryName = category.Name + }).ToList(); + } + } +} \ No newline at end of file diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/014_CollectionMappingWithGenericName.txt b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/014_CollectionMappingWithGenericName.txt new file mode 100644 index 0000000..c647a5e --- /dev/null +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/014_CollectionMappingWithGenericName.txt @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace TestAutoMapper.Identity.X +{ + public class XX + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class ZZ + { + public int Id { get; set; } + public string Name { get; set; } + } + + public static class Mapper{ + + public static List [|MapNew|](List dictionary) + { + } + } +} \ No newline at end of file diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/014_CollectionMappingWithGenericName_FIXED.txt b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/014_CollectionMappingWithGenericName_FIXED.txt new file mode 100644 index 0000000..7612235 --- /dev/null +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/014_CollectionMappingWithGenericName_FIXED.txt @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace TestAutoMapper.Identity.X +{ + public class XX + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class ZZ + { + public int Id { get; set; } + public string Name { get; set; } + } + + public static class Mapper{ + + public static List MapNew(List dictionary) + { + return dictionary.Select(item => new ZZ() + { + Id = item.Id, + Name = item.Name + }).ToList(); + } + } +} \ No newline at end of file diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/015_CollectionMappingWithPostfixGenericName.txt b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/015_CollectionMappingWithPostfixGenericName.txt new file mode 100644 index 0000000..4d23e64 --- /dev/null +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/015_CollectionMappingWithPostfixGenericName.txt @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace TestAutoMapper.Identity.X +{ + public class XX + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class ZZ + { + public int Id { get; set; } + public string Name { get; set; } + } + + public static class Mapper{ + + public static List [|MapNew|](List usersList) + { + } + } +} \ No newline at end of file diff --git a/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/015_CollectionMappingWithPostfixGenericName_FIXED.txt b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/015_CollectionMappingWithPostfixGenericName_FIXED.txt new file mode 100644 index 0000000..fa24fff --- /dev/null +++ b/MappingGenerator/MappingGenerator/MappingGenerator.Test/MappingGenerator/TestCaseData/015_CollectionMappingWithPostfixGenericName_FIXED.txt @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace TestAutoMapper.Identity.X +{ + public class XX + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class ZZ + { + public int Id { get; set; } + public string Name { get; set; } + } + + public static class Mapper{ + + public static List MapNew(List usersList) + { + return usersList.Select(user => new ZZ() + { + Id = user.Id, + Name = user.Name + }).ToList(); + } + } +} \ No newline at end of file diff --git a/MappingGenerator/MappingGenerator/MappingGenerator/MappingEngine.cs b/MappingGenerator/MappingGenerator/MappingGenerator/MappingEngine.cs index f47ee18..f47fc6c 100644 --- a/MappingGenerator/MappingGenerator/MappingGenerator/MappingEngine.cs +++ b/MappingGenerator/MappingGenerator/MappingGenerator/MappingEngine.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -11,6 +12,65 @@ namespace MappingGenerator { + public class NameHelper + { + private static readonly char[] ForbiddenSigns = new[] {'.', '[', ']', '(', ')'}; + private static Pluralizer Pluralizer = new Pluralizer(); + + public static string CreateLambdaParameterName(SyntaxNode sourceList) + { + var originalName = sourceList.ToFullString(); + var localVariableName = ToLocalVariableName(originalName); + var finalName = ToSingularLocalVariableName(localVariableName); + if (originalName == finalName) + { + return $"{finalName}Element"; + } + return finalName; + } + + public static string ToLocalVariableName(string proposalLocalName) + { + var withoutForbiddenSigns = string.Join("",proposalLocalName.Trim().Split(ForbiddenSigns).Where(x=> string.IsNullOrWhiteSpace(x) == false).Select(x=> + { + var cleanElement = x.Trim(); + return $"{cleanElement.Substring(0, 1).ToUpper()}{cleanElement.Substring(1)}"; + })); + return $"{withoutForbiddenSigns.Substring(0, 1).ToLower()}{withoutForbiddenSigns.Substring(1)}"; + } + + private static readonly string[] collectionSynonym = new[] {"List", "Collection", "Set", "Queue", "Dictionary", "Stack", "Array"}; + + private static string ToSingularLocalVariableName(string proposalLocalName) + { + if (collectionSynonym.Any(x=> x.Equals(proposalLocalName, StringComparison.OrdinalIgnoreCase))) + { + return "item"; + } + + foreach (var collectionName in collectionSynonym) + { + if (proposalLocalName.EndsWith(collectionName, StringComparison.OrdinalIgnoreCase)) + { + proposalLocalName = proposalLocalName.Substring(0, proposalLocalName.Length - collectionName.Length - 1); + break; + } + } + + if (proposalLocalName.EndsWith("Set")) + { + return $"{proposalLocalName}Element"; + } + + if (proposalLocalName.EndsWith("s")) + { + return Pluralizer.Singularize(proposalLocalName); + } + + return proposalLocalName; + } + } + public class MappingEngine { protected readonly SemanticModel semanticModel; @@ -261,7 +321,7 @@ private SyntaxNode MapCollections(SyntaxNode sourceAccess, ITypeSymbol sourceLis if (ShouldCreateConversionBetweenTypes(targetListElementType, sourceListElementType)) { var selectAccess = syntaxGenerator.MemberAccessExpression(sourceAccess, "Select"); - var lambdaParameterName = CreateLambdaParameterName(sourceAccess); + var lambdaParameterName = NameHelper.CreateLambdaParameterName(sourceAccess); var mappingLambda = CreateMappingLambda(lambdaParameterName, sourceListElementType, targetListElementType, mappingPath); var selectInvocation = syntaxGenerator.InvocationExpression(selectAccess, mappingLambda); var toList = AddMaterializeCollectionInvocation(syntaxGenerator, selectInvocation, targetListType); @@ -284,42 +344,6 @@ public SyntaxNode CreateMappingLambda(string lambdaParameterName, ITypeSymbol so return syntaxGenerator.ValueReturningLambdaExpression(lambdaParameterName, listElementMappingStm.Expression); } - private static string CreateLambdaParameterName(SyntaxNode sourceList) - { - var originalName = sourceList.ToFullString(); - var localVariableName = ToLocalVariableName(originalName); - var finalName = ToSingularLocalVariableName(localVariableName); - if (originalName == finalName) - { - return $"{finalName}Element"; - } - return finalName; - } - - private static readonly char[] ForbiddenSigns = new[] {'.', '[', ']', '(', ')'}; - - private static string ToLocalVariableName(string proposalLocalName) - { - var withoutForbiddenSigns = string.Join("",proposalLocalName.Trim().Split(ForbiddenSigns).Where(x=> string.IsNullOrWhiteSpace(x) == false).Select(x=> - { - var cleanElement = x.Trim(); - return $"{cleanElement.Substring(0, 1).ToUpper()}{cleanElement.Substring(1)}"; - })); - return $"{withoutForbiddenSigns.Substring(0, 1).ToLower()}{withoutForbiddenSigns.Substring(1)}"; - } - - private static string ToSingularLocalVariableName(string proposalLocalName) - { - if (proposalLocalName.EndsWith("s")) - { - return Pluralizer.Singularize(proposalLocalName); - } - - return proposalLocalName; - } - - private static Pluralizer Pluralizer = new Pluralizer(); - private static SyntaxNode AddMaterializeCollectionInvocation(SyntaxGenerator generator, SyntaxNode sourceAccess, ITypeSymbol targetListType) { var materializeFunction = targetListType.Kind == SymbolKind.ArrayType? "ToArray": "ToList"; diff --git a/MappingGenerator/MappingGenerator/MappingGenerator/ObjectMembersMappingSourceFinder.cs b/MappingGenerator/MappingGenerator/MappingGenerator/ObjectMembersMappingSourceFinder.cs index 5af1835..a8e1ea7 100644 --- a/MappingGenerator/MappingGenerator/MappingGenerator/ObjectMembersMappingSourceFinder.cs +++ b/MappingGenerator/MappingGenerator/MappingGenerator/ObjectMembersMappingSourceFinder.cs @@ -19,12 +19,14 @@ public class ObjectMembersMappingSourceFinder : IMappingSourceFinder private readonly SyntaxGenerator generator; private readonly Lazy> sourceProperties; private readonly Lazy> sourceMethods; + private readonly string potentialPrefix; public ObjectMembersMappingSourceFinder(ITypeSymbol sourceType, SyntaxNode sourceGlobalAccessor, SyntaxGenerator generator) { this.sourceType = sourceType; this.sourceGlobalAccessor = sourceGlobalAccessor; this.generator = generator; + this.potentialPrefix = NameHelper.ToLocalVariableName(sourceGlobalAccessor.ToFullString()); this.sourceProperties = new Lazy>(() => ObjectHelper.GetPublicPropertySymbols(sourceType) .Where(property => property.GetMethod!=null) .ToList()); @@ -40,7 +42,7 @@ public MappingElement FindMappingSource(string targetName, ITypeSymbol targetTyp private MappingElement FindSource(string targetName) { //Direct 1-1 mapping - var matchedSourceProperty = sourceProperties.Value.FirstOrDefault(x => x.Name.Equals(targetName, StringComparison.OrdinalIgnoreCase)); + var matchedSourceProperty = sourceProperties.Value.FirstOrDefault(x => x.Name.Equals(targetName, StringComparison.OrdinalIgnoreCase) || $"{potentialPrefix}{x.Name}".Equals(targetName, StringComparison.OrdinalIgnoreCase)); if (matchedSourceProperty != null) { return new MappingElement()