From 541477b545ea591ac07024221cc7c683f50bf4b2 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Sat, 31 Jul 2021 10:21:12 +0200 Subject: [PATCH] Add support for reserved keywords like @object and @string (#18) --- src-examples/ProxyInterfaceConsumer/Person.cs | 6 +- .../Class1pp.cs | 86 ------------- .../ProxyInterfaceConsumerViaNuGet/Person.cs | 36 +++++- .../PersonProxy2.cs | 119 ++++++++++++++++++ .../Extensions/SymbolExtensions.cs | 25 ++-- .../PartialInterfacesGenerator.cs | 2 +- .../FileGenerators/ProxyClassesGenerator.cs | 74 ++--------- .../Utils/MemberHelper.cs | 5 +- 8 files changed, 188 insertions(+), 165 deletions(-) delete mode 100644 src-examples/ProxyInterfaceConsumerViaNuGet/Class1pp.cs create mode 100644 src-examples/ProxyInterfaceConsumerViaNuGet/PersonProxy2.cs diff --git a/src-examples/ProxyInterfaceConsumer/Person.cs b/src-examples/ProxyInterfaceConsumer/Person.cs index 858ee7c..0738937 100644 --- a/src-examples/ProxyInterfaceConsumer/Person.cs +++ b/src-examples/ProxyInterfaceConsumer/Person.cs @@ -8,6 +8,8 @@ namespace ProxyInterfaceConsumer private int PrivateId { get; } public int Id { get; } + public object @object { get; set; } + public long? NullableLong { get; } public string Name { get; set; } @@ -25,9 +27,9 @@ namespace ProxyInterfaceConsumer public IMyInterface MyInterface { get; set; } - public int Add(string s) + public string Add(string s, string @string) { - return 600; + return s + @string; } public void AddWithParams(params string[] values) diff --git a/src-examples/ProxyInterfaceConsumerViaNuGet/Class1pp.cs b/src-examples/ProxyInterfaceConsumerViaNuGet/Class1pp.cs deleted file mode 100644 index 5d05d7e..0000000 --- a/src-examples/ProxyInterfaceConsumerViaNuGet/Class1pp.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using AutoMapper; - -namespace ProxyInterfaceConsumer -{ - public class PersonProxy2 - { - public ProxyInterfaceConsumer.Person _Instance { get; } - - public int Id { get => _Instance.Id; } - - public long? NullableLong { get => _Instance.NullableLong; } - - public string Name { get => _Instance.Name; set => _Instance.Name = value; } - - - public IAddress Address { get => _mapper.Map(_Instance.Address); set => _Instance.Address = _mapper.Map(value); } - - public System.Collections.Generic.List AddressesLIst { get => _mapper.Map>(_Instance.AddressesLIst); set => _Instance.AddressesLIst = _mapper.Map>(value); } - - public System.Collections.Generic.Dictionary AddressesDict { get => _mapper.Map>(_Instance.AddressesDict); set => _Instance.AddressesDict = _mapper.Map>(value); } - - public ProxyInterfaceConsumer.E E { get => _Instance.E; set => _Instance.E = value; } - - public ProxyInterfaceConsumer.IMyInterface MyInterface { get => _Instance.MyInterface; set => _Instance.MyInterface = value; } - - - - public int Add(string s) - { - string s_dbccfd45ed944f58b12d83a4f907aa6c = s; - var result_caf8bee7109d4b77891b141c495b63ff = _Instance.Add(s_dbccfd45ed944f58b12d83a4f907aa6c); - return result_caf8bee7109d4b77891b141c495b63ff; - } - - - - public IAddress AddAddress(IAddress a) - { - ProxyInterfaceConsumer.Address a_23d6262793aa4c90b77bb7a9d46710b2 = _mapper.Map(a); - var result_cd3011159452417bb585e0acfaeefddc = _Instance.AddAddress(a_23d6262793aa4c90b77bb7a9d46710b2); - return _mapper.Map(result_cd3011159452417bb585e0acfaeefddc); - } - - public void In_Out_Ref1(in int a, out int b, ref int c) - { - int a_88b067399c9641d69ebd8f795ddfa7ee = a; - int b_9a4c5b7b7e4c427dbb4779f658602356; - int c_49084012db6e47f0b03626886b8b7848 = c; - _Instance.In_Out_Ref1(in a_88b067399c9641d69ebd8f795ddfa7ee, out b_9a4c5b7b7e4c427dbb4779f658602356, ref c_49084012db6e47f0b03626886b8b7848); - b = b_9a4c5b7b7e4c427dbb4779f658602356; - } - - public void In_Out_Ref2(in IAddress a, out IAddress b, ref IAddress c) - { - ProxyInterfaceConsumer.Address a_e5af7467b9d24729a95a861a8cc87f27 = _mapper.Map(a); - ProxyInterfaceConsumer.Address b_3a7ae9dbab3344bc9f9736b113198331; - ProxyInterfaceConsumer.Address c_afcd2b8abb1a4b7eae2a10656744c28a = _mapper.Map(c); - _Instance.In_Out_Ref2(in a_e5af7467b9d24729a95a861a8cc87f27, out b_3a7ae9dbab3344bc9f9736b113198331, ref c_afcd2b8abb1a4b7eae2a10656744c28a); - b = _mapper.Map(b_3a7ae9dbab3344bc9f9736b113198331); - } - - public void Void() - { - _Instance.Void(); - } - - - - - - public PersonProxy2(ProxyInterfaceConsumer.Person instance) - { - _Instance = instance; - - _mapper = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - cfg.CreateMap(); - }).CreateMapper(); - - } - - private readonly IMapper _mapper; - } -} \ No newline at end of file diff --git a/src-examples/ProxyInterfaceConsumerViaNuGet/Person.cs b/src-examples/ProxyInterfaceConsumerViaNuGet/Person.cs index 4e95d53..b21a785 100644 --- a/src-examples/ProxyInterfaceConsumerViaNuGet/Person.cs +++ b/src-examples/ProxyInterfaceConsumerViaNuGet/Person.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; namespace ProxyInterfaceConsumer { @@ -7,23 +8,32 @@ namespace ProxyInterfaceConsumer private int PrivateId { get; } public int Id { get; } + public object @object { get; set; } + public long? NullableLong { get; } public string Name { get; set; } + public string? StringNullable { get; set; } + public Address Address { get; set; } public List
AddressesLIst { get; set; } public Dictionary AddressesDict { get; set; } = new Dictionary(); + public Dictionary AddressesDict2 { get; set; } = new Dictionary(); public E E { get; set; } public IMyInterface MyInterface { get; set; } - public int Add(string s) + public string Add(string s, string @string) + { + return s + @string; + } + + public void AddWithParams(params string[] values) { - return 600; } public Address AddAddress(Address a) @@ -33,19 +43,39 @@ namespace ProxyInterfaceConsumer return a; } + public void AddAddresses(params Address[] addresses) + { + } + public void In_Out_Ref1(in int a, out int b, ref int c) { b = 1; } - public void In_Out_Ref2(in Address a, out Address b, ref Address c) + public int In_Out_Ref2(in Address a, out Address b, ref Address c) { b = new Address(); + return 404; } public void Void() { } + + public Task Method1Async() + { + return Task.CompletedTask; + } + + public Task Method2Async() + { + return Task.FromResult(1); + } + + public Task Method3Async() + { + return Task.FromResult((string?)""); + } } public enum E diff --git a/src-examples/ProxyInterfaceConsumerViaNuGet/PersonProxy2.cs b/src-examples/ProxyInterfaceConsumerViaNuGet/PersonProxy2.cs new file mode 100644 index 0000000..017ad30 --- /dev/null +++ b/src-examples/ProxyInterfaceConsumerViaNuGet/PersonProxy2.cs @@ -0,0 +1,119 @@ +using System; +using AutoMapper; + +namespace ProxyInterfaceConsumer +{ + public class PersonProxy2 : IPerson + { + public ProxyInterfaceConsumer.Person _Instance { get; } + + public int Id { get => _Instance.Id; } + + public object @object { get => _Instance.@object; set => _Instance.@object = value; } + + public long? NullableLong { get => _Instance.NullableLong; } + + public string Name { get => _Instance.Name; set => _Instance.Name = value; } + + public string? StringNullable { get => _Instance.StringNullable; set => _Instance.StringNullable = value; } + + public IAddress Address { get => _mapper.Map(_Instance.Address); set => _Instance.Address = _mapper.Map(value); } + + public System.Collections.Generic.List AddressesLIst { get => _mapper.Map>(_Instance.AddressesLIst); set => _Instance.AddressesLIst = _mapper.Map>(value); } + + public System.Collections.Generic.Dictionary AddressesDict { get => _mapper.Map>(_Instance.AddressesDict); set => _Instance.AddressesDict = _mapper.Map>(value); } + + public System.Collections.Generic.Dictionary AddressesDict2 { get => _mapper.Map>(_Instance.AddressesDict2); set => _Instance.AddressesDict2 = _mapper.Map>(value); } + + public ProxyInterfaceConsumer.E E { get => _Instance.E; set => _Instance.E = value; } + + public ProxyInterfaceConsumer.IMyInterface MyInterface { get => _Instance.MyInterface; set => _Instance.MyInterface = value; } + + + + public string Add(string s, string @string) + { + string s_ = s; + string @string_ = @string; + var result_33785274 = _Instance.Add(s_, @string_); + return result_33785274; + } + + public void AddWithParams(params string[] values) + { + string[] values_ = values; + _Instance.AddWithParams(values_); + } + + public IAddress AddAddress(IAddress a) + { + ProxyInterfaceConsumer.Address a_ = _mapper.Map(a); + var result_9487824 = _Instance.AddAddress(a_); + return _mapper.Map(result_9487824); + } + + public void AddAddresses(params ProxyInterfaceConsumer.Address[] addresses) + { + ProxyInterfaceConsumer.Address[] addresses_ = addresses; + _Instance.AddAddresses(addresses_); + } + + public void In_Out_Ref1(in int a, out int b, ref int c) + { + int a_ = a; + int b_; + int c_ = c; + _Instance.In_Out_Ref1(in a_, out b_, ref c_); + b = b_; + } + + public int In_Out_Ref2(in IAddress a, out IAddress b, ref IAddress c) + { + ProxyInterfaceConsumer.Address a_ = _mapper.Map(a); + ProxyInterfaceConsumer.Address b_; + ProxyInterfaceConsumer.Address c_ = _mapper.Map(c); + var result_30316242 = _Instance.In_Out_Ref2(in a_, out b_, ref c_); + b = _mapper.Map(_b); + return result_30316242; + } + + public void Void() + { + _Instance.Void(); + } + + public System.Threading.Tasks.Task Method1Async() + { + var result_19162058 = _Instance.Method1Async(); + return result_19162058; + } + + public System.Threading.Tasks.Task Method2Async() + { + var result_1349218716 = _Instance.Method2Async(); + return result_1349218716; + } + + public System.Threading.Tasks.Task Method3Async() + { + var result_1352687748 = _Instance.Method3Async(); + return result_1352687748; + } + + + + public PersonProxy2(ProxyInterfaceConsumer.Person instance) + { + _Instance = instance; + + _mapper = new MapperConfiguration(cfg => + { + cfg.CreateMap(); + cfg.CreateMap(); + }).CreateMapper(); + + } + + private readonly IMapper _mapper; +} +} \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs b/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs index 55123da..5a98df3 100644 --- a/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs +++ b/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs @@ -1,10 +1,21 @@ using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using ProxyInterfaceSourceGenerator.Enums; namespace ProxyInterfaceSourceGenerator.Extensions { internal static class SymbolExtensions { + public static bool IsKeywordOrReserved(this ISymbol symbol) + { + return SyntaxFacts.GetKeywordKind(symbol.Name) != SyntaxKind.None || SyntaxFacts.GetContextualKeywordKind(symbol.Name) != SyntaxKind.None; + } + + public static string SanitizedName(this ISymbol symbol) + { + return symbol.IsKeywordOrReserved() ? $"@{symbol.Name}" : symbol.Name; + } + public static string GetRefPrefix(this IParameterSymbol ps) { switch (ps.RefKind) @@ -65,23 +76,23 @@ namespace ProxyInterfaceSourceGenerator.Extensions var type = !string.IsNullOrEmpty(overrideType) ? overrideType : $"{property.Type}"; - return $"{type} {property.Name} {{ {get}{set}}}"; + return $"{type} {property.SanitizedName()} {{ {get}{set}}}"; } public static string ToPropertyTextForClass(this IPropertySymbol property) { - var get = property.GetMethod != null ? $"get => _Instance.{property.Name}; " : string.Empty; - var set = property.SetMethod != null ? $"set => _Instance.{property.Name} = value; " : string.Empty; + var get = property.GetMethod != null ? $"get => _Instance.{property.SanitizedName()}; " : string.Empty; + var set = property.SetMethod != null ? $"set => _Instance.{property.SanitizedName()} = value; " : string.Empty; - return $"{property.Type} {property.Name} {{ {get}{set}}}"; + return $"{property.Type} {property.SanitizedName()} {{ {get}{set}}}"; } public static string ToPropertyTextForClass(this IPropertySymbol property, string overrideType) { - var get = property.GetMethod != null ? $"get => _mapper.Map<{overrideType}>(_Instance.{property.Name}); " : string.Empty; - var set = property.SetMethod != null ? $"set => _Instance.{property.Name} = _mapper.Map<{property.Type}>(value); " : string.Empty; + var get = property.GetMethod != null ? $"get => _mapper.Map<{overrideType}>(_Instance.{property.SanitizedName()}); " : string.Empty; + var set = property.SetMethod != null ? $"set => _Instance.{property.SanitizedName()} = _mapper.Map<{property.Type}>(value); " : string.Empty; - return $"{overrideType} {property.Name} {{ {get}{set}}}"; + return $"{overrideType} {property.SanitizedName()} {{ {get}{set}}}"; } } } diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs index 4dcd612..69f7092 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs @@ -89,7 +89,7 @@ namespace {ns} foreach (var ps in method.Parameters) { var type = ps.GetTypeEnum() == TypeEnum.Complex ? GetParameterType(ps, out _) : ps.Type.ToString(); - methodParameters.Add($"{ps.GetParamsPrefix()}{ps.GetRefPrefix()}{type} {ps.Name}"); + methodParameters.Add($"{ps.GetParamsPrefix()}{ps.GetRefPrefix()}{type} {ps.SanitizedName()}"); } str.AppendLine($" {GetReplacedType(method.ReturnType, out _)} {method.Name}({string.Join(", ", methodParameters)});"); diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs index 3436132..8130d98 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs @@ -131,15 +131,15 @@ namespace {ns} { if (ps.GetTypeEnum() == TypeEnum.Complex) { - var type = GetParameterType(ps, out var isReplaced); - methodParameters.Add($"{ps.GetParamsPrefix()}{ps.GetRefPrefix()}{type} {ps.Name}"); + var type = GetParameterType(ps, out _); + methodParameters.Add($"{ps.GetParamsPrefix()}{ps.GetRefPrefix()}{type} {ps.SanitizedName()}"); } else { - methodParameters.Add($"{ps.GetParamsPrefix()}{ps.GetRefPrefix()}{ps.Type} {ps.Name}"); + methodParameters.Add($"{ps.GetParamsPrefix()}{ps.GetRefPrefix()}{ps.Type} {ps.SanitizedName()}"); } - invokeParameters.Add($"{ps.GetRefPrefix()}_{ps.Name}"); + invokeParameters.Add($"{ps.GetRefPrefix()}{ps.SanitizedName()}_"); } string returnTypeAsString = GetReplacedType(method.ReturnType, out var returnIsReplaced); @@ -148,7 +148,7 @@ namespace {ns} str.AppendLine(" {"); foreach (var ps in method.Parameters) { - string normalOrMap = $" = {ps.Name}"; + string normalOrMap = $" = {ps.SanitizedName()}"; if (ps.RefKind == RefKind.Out) { normalOrMap = string.Empty; @@ -158,11 +158,11 @@ namespace {ns} var type = GetParameterType(ps, out var isReplaced); if (isReplaced) { - normalOrMap = $" = _mapper.Map<{ps.Type}>({ps.Name})"; + normalOrMap = $" = _mapper.Map<{ps.Type}>({ps.SanitizedName()})"; } } - str.AppendLine($" {ps.Type} _{ps.Name}{normalOrMap};"); + str.AppendLine($" {ps.Type} {ps.SanitizedName()}_{normalOrMap};"); } #pragma warning disable RS1024 // Compare symbols correctly @@ -181,17 +181,17 @@ namespace {ns} foreach (var ps in method.Parameters.Where(p => p.RefKind == RefKind.Out)) { - string normalOrMap = $" = _{ps.Name}"; + string normalOrMap = $" = {ps.SanitizedName()}_"; if (ps.GetTypeEnum() == TypeEnum.Complex) { var type = GetParameterType(ps, out var isReplaced); if (isReplaced) { - normalOrMap = $" = _mapper.Map<{type}>(_{ps.Name})"; + normalOrMap = $" = _mapper.Map<{type}>({ps.SanitizedName()}_)"; } } - str.AppendLine($" {ps.Name}{normalOrMap};"); + str.AppendLine($" {ps.SanitizedName()}{normalOrMap};"); } if (returnTypeAsString != "void") @@ -212,59 +212,5 @@ namespace {ns} return str.ToString(); } - - private string GeneratePublicMethodsOld(INamedTypeSymbol symbol) - { - var str = new StringBuilder(); - foreach (var method in MemberHelper.GetPublicMethods(symbol)) - { - var methodParameters = new List(); - var invokeParameters = new List(); - - foreach (var ps in method.Parameters) - { - if (ps.GetTypeEnum() == TypeEnum.Complex) - { - var type = GetParameterType(ps, out var isReplaced); - methodParameters.Add($"{ps.GetParamsPrefix()}{ps.GetRefPrefix()}{type} {ps.Name}"); - - if (isReplaced) - { - invokeParameters.Add($"_mapper.Map<{ps.Type}>({ps.Name})"); - } - else - { - invokeParameters.Add($"{ps.GetRefPrefix()}{ps.Name}"); - } - } - else - { - methodParameters.Add($"{ps.GetParamsPrefix()}{ps.GetRefPrefix()}{ps.Type} {ps.Name}"); - - invokeParameters.Add($"{ps.GetRefPrefix()}{ps.Name}"); - } - } - - string returnTypeAsString; - string call = $"_Instance.{method.Name}({string.Join(", ", invokeParameters)})"; - if (method.ReturnType.GetTypeEnum() == TypeEnum.Complex) - { - returnTypeAsString = GetReplacedType(method.ReturnType, out var isReplaced); - if (isReplaced) - { - call = $"_mapper.Map<{returnTypeAsString}>(_Instance.{method.Name}({string.Join(", ", invokeParameters)}))"; - } - } - else - { - returnTypeAsString = method.ReturnType.ToString(); - } - - str.AppendLine($" public {returnTypeAsString} {method.Name}({string.Join(", ", methodParameters)}) => {call};"); - str.AppendLine(); - } - - return str.ToString(); - } } } \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/Utils/MemberHelper.cs b/src/ProxyInterfaceSourceGenerator/Utils/MemberHelper.cs index 73ec85b..e9701fe 100644 --- a/src/ProxyInterfaceSourceGenerator/Utils/MemberHelper.cs +++ b/src/ProxyInterfaceSourceGenerator/Utils/MemberHelper.cs @@ -1,7 +1,7 @@ -using System; +using Microsoft.CodeAnalysis; +using System; using System.Collections.Generic; using System.Linq; -using Microsoft.CodeAnalysis; namespace ProxyInterfaceSourceGenerator.Utils { @@ -31,6 +31,7 @@ namespace ProxyInterfaceSourceGenerator.Utils filter); } + // TODO : do we need also to check for "SanitizedName()" here? private static IEnumerable GetPublicMembers(INamedTypeSymbol classSymbol, params Func[] filters) where T : ISymbol { var membersQuery = classSymbol.GetMembers().OfType()