From afe1710816fa6bb321eb7cb8070c636e1983429f Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Sat, 24 Jul 2021 09:23:02 +0200 Subject: [PATCH] Fix InterfaceName + update Properties, add private Fields --- src-examples/ProxyInterfaceConsumer/Person.cs | 2 +- .../ProxyInterfaceConsumer/Program.cs | 8 ++- .../Extensions/SymbolExtensions.cs | 2 +- .../FileGenerators/{Data.cs => FileData.cs} | 2 +- .../FileGenerators/IFileGenerator.cs | 2 +- .../FileGenerators/IFilesGenerator.cs | 2 +- .../PartialInterfacesGenerator.cs | 47 +++++-------- .../FileGenerators/ProxyAttributeGenerator.cs | 4 +- .../FileGenerators/ProxyClassesGenerator.cs | 67 ++++++++++++++++--- .../ProxyInterfaceCodeGenerator.cs | 8 +-- .../SyntaxReceiver/ProxyData.cs | 7 +- .../SyntaxReceiver/ProxySyntaxReceiver.cs | 3 +- 12 files changed, 98 insertions(+), 56 deletions(-) rename src/ProxyInterfaceSourceGenerator/FileGenerators/{Data.cs => FileData.cs} (55%) diff --git a/src-examples/ProxyInterfaceConsumer/Person.cs b/src-examples/ProxyInterfaceConsumer/Person.cs index 6954a2f..b4524cc 100644 --- a/src-examples/ProxyInterfaceConsumer/Person.cs +++ b/src-examples/ProxyInterfaceConsumer/Person.cs @@ -26,7 +26,7 @@ namespace SourceGeneratorInterface // } - public Compilation Compilation { get; } + public Compilation Compilation { get; set; } public INamedTypeSymbol MyNamedTypeSymbol { get;set; } } diff --git a/src-examples/ProxyInterfaceConsumer/Program.cs b/src-examples/ProxyInterfaceConsumer/Program.cs index 5950cba..d7576d3 100644 --- a/src-examples/ProxyInterfaceConsumer/Program.cs +++ b/src-examples/ProxyInterfaceConsumer/Program.cs @@ -6,10 +6,12 @@ namespace SourceGeneratorInterface { public static void Main() { - PersonProxy p = new PersonProxy(new Person()); + IPerson p = new PersonProxy(new Person()); p.Name = "test"; - p.Add("x"); - p.Void(); + p.MyNamedTypeSymbol = null; + p.Compilation = null; + //p.Add("x"); + //p.Void(); Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(p)); } } diff --git a/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs b/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs index adbf524..60cc630 100644 --- a/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs +++ b/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs @@ -5,7 +5,7 @@ namespace ProxyInterfaceSourceGenerator.Extensions { internal static class SymbolExtensions { - public static string ToPropertyTextForInterface(this IPropertySymbol property) + public static string ToPropertyText(this IPropertySymbol property) { string get = property.GetMethod != null ? "get; " : string.Empty; string set = property.SetMethod != null ? "set; " : string.Empty; diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/Data.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/FileData.cs similarity index 55% rename from src/ProxyInterfaceSourceGenerator/FileGenerators/Data.cs rename to src/ProxyInterfaceSourceGenerator/FileGenerators/FileData.cs index 502713d..387e286 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/Data.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/FileData.cs @@ -1,6 +1,6 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators { - internal record Data(string FileName, string Text) + internal record FileData(string FileName, string Text) { } } \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/IFileGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/IFileGenerator.cs index 37c084a..d719b8f 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/IFileGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/IFileGenerator.cs @@ -2,6 +2,6 @@ { internal interface IFileGenerator { - Data GenerateFile(); + FileData GenerateFile(); } } \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/IFilesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/IFilesGenerator.cs index 78a52fc..b41a808 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/IFilesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/IFilesGenerator.cs @@ -4,6 +4,6 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators { internal interface IFilesGenerator { - IEnumerable GenerateFiles(); + IEnumerable GenerateFiles(); } } \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs index 0aa4059..ebee7f1 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs @@ -21,7 +21,7 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators _candidateInterfaces = candidateInterfaces; } - public IEnumerable GenerateFiles() + public IEnumerable GenerateFiles() { foreach (var ci in _candidateInterfaces) { @@ -31,9 +31,10 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators throw new Exception($"The type '{ci.Value.TypeName}' is not found."); } - string interfaceName = $"I{ci.Value.TypeName.Split('.').Last()}"; - - yield return new Data($"I{interfaceName}.cs", CreatePartialInterfaceCode(symbol, interfaceName, ci.Value.ProxyAll)); + yield return new FileData( + $"{ci.Value.InterfaceName}.cs", + CreatePartialInterfaceCode(symbol, ci.Value.InterfaceName, ci.Value.ProxyAll) + ); } } @@ -43,46 +44,35 @@ namespace {symbol.ContainingNamespace} {{ public partial interface {interfaceName} {{ -{GenerateSimpleProperties(symbol)} - -{GenerateInterfaceProperties(symbol)} - -{GenerateComplexProperties(symbol, proxyAll)} +{GenerateProperties(symbol, proxyAll)} {GenerateMethods(symbol)} }} }}"; - private string GenerateSimpleProperties(INamedTypeSymbol symbol) + private string GenerateProperties(INamedTypeSymbol symbol, bool proxyAll) { var str = new StringBuilder(); + + // SimpleProperties foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.Type.IsValueType || p.Type.ToString() == "string")) { - str.AppendLine($" {property.ToPropertyTextForInterface()}"); + str.AppendLine($" {property.ToPropertyText()}"); str.AppendLine(); } - return str.ToString(); - } - - private string GenerateInterfaceProperties(INamedTypeSymbol symbol) - { - var str = new StringBuilder(); + // InterfaceProperties foreach (var property in MemberHelper.GetPublicProperties(symbol, p => !(p.Type.IsValueType || p.Type.ToString() == "string"), p => p.Type.TypeKind == TypeKind.Interface) ) { - str.AppendLine($" {property.ToPropertyTextForInterface()}"); + str.AppendLine($" {property.ToPropertyText()}"); str.AppendLine(); } - return "// GenerateInterfaceProperties";// str.ToString(); - } - - private string GenerateComplexProperties(INamedTypeSymbol symbol, bool proxyAll) - { - var filters = new List> + // ComplexProperties + var complexFilters = new List> { p => !(p.Type.IsValueType || p.Type.ToString() == "string"), p => p.Type.TypeKind != TypeKind.Interface @@ -93,14 +83,13 @@ namespace {symbol.ContainingNamespace} } - var str = new StringBuilder(); - foreach (var property in MemberHelper.GetPublicProperties(symbol, filters.ToArray())) + foreach (var property in MemberHelper.GetPublicProperties(symbol, complexFilters.ToArray())) { - str.AppendLine($" {property.ToPropertyTextForInterface()}"); + str.AppendLine($" {property.ToPropertyText()}"); str.AppendLine(); } - return "// GenerateComplexProperties";// str.ToString(); + return str.ToString(); } private string GenerateMethods(INamedTypeSymbol symbol) @@ -112,7 +101,7 @@ namespace {symbol.ContainingNamespace} str.AppendLine(); } - return str.ToString(); + return "// Methods"; // str.ToString(); } } } \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyAttributeGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyAttributeGenerator.cs index ccc27b7..520ec42 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyAttributeGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyAttributeGenerator.cs @@ -4,9 +4,9 @@ { private const string ClassName = "ProxyAttribute"; - public Data GenerateFile() + public FileData GenerateFile() { - return new Data($"{ClassName}.cs", $@"using System; + return new FileData($"{ClassName}.cs", $@"using System; namespace ProxyInterfaceGenerator {{ diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs index 4ba1f0e..a591966 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -21,7 +20,7 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators _candidateInterfaces = candidateInterfaces; } - public IEnumerable GenerateFiles() + public IEnumerable GenerateFiles() { foreach (var ci in _candidateInterfaces) { @@ -31,43 +30,91 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators throw new Exception($"The type '{ci.Value.TypeName}' is not found."); } - string className = $"{ci.Value.TypeName.Split('.').Last()}"; - - yield return new Data($"{className}Proxy.cs", CreateProxyClassCode(symbol, className)); + yield return new FileData( + $"{ci.Value.ClassName}Proxy.cs", + CreateProxyClassCode(symbol, ci.Value.InterfaceName, ci.Value.ClassName, ci.Value.ProxyAll) + ); } } - private string CreateProxyClassCode(INamedTypeSymbol symbol, string className) => $@"using System; + private string CreateProxyClassCode(INamedTypeSymbol symbol, string interfaceName, string className, bool proxyAll) => $@"using System; namespace {symbol.ContainingNamespace} {{ - public class {className}Proxy : I{className} + public class {className}Proxy : {interfaceName} {{ private {className} _instance; +{GenerateComplexFields(symbol,proxyAll)} public {className}Proxy({className} instance) {{ _instance = instance; }} -{GenerateSimpleProperties(symbol)} +{GenerateProperties(symbol, proxyAll)} {GenerateMethods(symbol)} }} }}"; - - private string GenerateSimpleProperties(INamedTypeSymbol symbol) + private string GenerateComplexFields(INamedTypeSymbol symbol, bool proxyAll) { var str = new StringBuilder(); + + foreach (var property in GetComplexProperties(symbol, proxyAll)) + { + str.AppendLine($" private {property.Type} _{property.Name};"); + } + + return str.ToString(); + } + + private string GenerateProperties(INamedTypeSymbol symbol, bool proxyAll) + { + var str = new StringBuilder(); + + // SimpleProperties foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.Type.IsValueType || p.Type.ToString() == "string")) { str.AppendLine($" public {property.ToPropertyTextForClass()}"); str.AppendLine(); } + // InterfaceProperties + foreach (var property in MemberHelper.GetPublicProperties(symbol, + p => !(p.Type.IsValueType || p.Type.ToString() == "string"), + p => p.Type.TypeKind == TypeKind.Interface) + ) + { + str.AppendLine($" public {property.ToPropertyTextForClass()}"); + str.AppendLine(); + } + + // ComplexProperties + foreach (var property in GetComplexProperties(symbol, proxyAll)) + { + str.AppendLine($" public {property.ToPropertyTextForClass()}"); + str.AppendLine(); + } + return str.ToString(); } + private IEnumerable GetComplexProperties(INamedTypeSymbol symbol, bool proxyAll) + { + var complexFilters = new List> + { + p => !(p.Type.IsValueType || p.Type.ToString() == "string"), + p => p.Type.TypeKind != TypeKind.Interface + }; + + if (proxyAll) + { + + } + + return MemberHelper.GetPublicProperties(symbol, complexFilters.ToArray()); + } + private string GenerateMethods(INamedTypeSymbol symbol) { var str = new StringBuilder(); diff --git a/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs b/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs index b8bb66c..1f5a1e2 100644 --- a/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs @@ -13,10 +13,10 @@ namespace ProxyInterfaceSourceGenerator public void Initialize(GeneratorInitializationContext context) { - if (!System.Diagnostics.Debugger.IsAttached) - { - System.Diagnostics.Debugger.Launch(); - } + //if (!System.Diagnostics.Debugger.IsAttached) + //{ + // System.Diagnostics.Debugger.Launch(); + //} context.RegisterForSyntaxNotifications(() => new ProxySyntaxReceiver()); } diff --git a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs index d2a7545..8a1cbca 100644 --- a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs +++ b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs @@ -1,6 +1,9 @@ -namespace ProxyInterfaceSourceGenerator.SyntaxReceiver +using System.Linq; + +namespace ProxyInterfaceSourceGenerator.SyntaxReceiver { - internal record ProxyData(string TypeName, bool ProxyAll) + internal record ProxyData(string InterfaceName, string TypeName, bool ProxyAll) { + public string ClassName => TypeName.Split('.').Last(); } } \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs index e391636..8456907 100644 --- a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs +++ b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs @@ -19,7 +19,7 @@ namespace ProxyInterfaceSourceGenerator.SyntaxReceiver private static bool TryGet(InterfaceDeclarationSyntax interfaceDeclarationSyntax, out ProxyData data) { - data = new(string.Empty, false); + data = new(string.Empty, string.Empty, false); // TODO : how to check if the InterfaceDeclarationSyntax has 'partial' ? var attributeLists = interfaceDeclarationSyntax.AttributeLists.FirstOrDefault(x => x.Attributes.Any(a => a.Name.ToString().Equals("ProxyInterfaceGenerator.Proxy"))); @@ -36,6 +36,7 @@ namespace ProxyInterfaceSourceGenerator.SyntaxReceiver data = new ( + interfaceDeclarationSyntax.Identifier.ToString(), argumentList.Arguments[0].Expression.ChildNodes().First().GetText().ToString(), bool.Parse(argumentList.Arguments[1].Expression.GetText().ToString()) );