diff --git a/src-examples/ProxyInterfaceConsumer/IAddress.cs b/src-examples/ProxyInterfaceConsumer/IAddress.cs new file mode 100644 index 0000000..ee6b033 --- /dev/null +++ b/src-examples/ProxyInterfaceConsumer/IAddress.cs @@ -0,0 +1,7 @@ +namespace SourceGeneratorInterface +{ + [ProxyInterfaceGenerator.Proxy(typeof(SourceGeneratorInterface.Address))] + public partial interface IAddress + { + } +} \ No newline at end of file diff --git a/src-examples/ProxyInterfaceConsumer/IPerson.cs b/src-examples/ProxyInterfaceConsumer/IPerson.cs index 4c75259..08336e2 100644 --- a/src-examples/ProxyInterfaceConsumer/IPerson.cs +++ b/src-examples/ProxyInterfaceConsumer/IPerson.cs @@ -1,6 +1,6 @@ namespace SourceGeneratorInterface { - [ProxyInterfaceGenerator.Proxy(typeof(SourceGeneratorInterface.Person), true)] + [ProxyInterfaceGenerator.Proxy(typeof(SourceGeneratorInterface.Person))] public partial interface IPerson { } diff --git a/src/ProxyInterfaceSourceGenerator/Context.cs b/src/ProxyInterfaceSourceGenerator/Context.cs index ab242c1..585042c 100644 --- a/src/ProxyInterfaceSourceGenerator/Context.cs +++ b/src/ProxyInterfaceSourceGenerator/Context.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using ProxyInterfaceSourceGenerator.SyntaxReceiver; namespace ProxyInterfaceSourceGenerator { @@ -8,5 +10,7 @@ namespace ProxyInterfaceSourceGenerator public GeneratorExecutionContext GeneratorExecutionContext { get; init; } public List GeneratedData { get; } = new List(); + + public IDictionary CandidateInterfaces { get; init; } } } \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/Enums/TypeEnum.cs b/src/ProxyInterfaceSourceGenerator/Enums/TypeEnum.cs new file mode 100644 index 0000000..3ca55a9 --- /dev/null +++ b/src/ProxyInterfaceSourceGenerator/Enums/TypeEnum.cs @@ -0,0 +1,11 @@ +namespace ProxyInterfaceSourceGenerator.Enums +{ + internal enum TypeEnum + { + ValueTypeOrString, + + Interface, + + Complex + } +} \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs b/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs index f0ff14e..3509a83 100644 --- a/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs +++ b/src/ProxyInterfaceSourceGenerator/Extensions/SymbolExtensions.cs @@ -1,10 +1,26 @@ using System.Collections.Generic; using Microsoft.CodeAnalysis; +using ProxyInterfaceSourceGenerator.Enums; namespace ProxyInterfaceSourceGenerator.Extensions { internal static class SymbolExtensions { + public static TypeEnum GetTypeEnum(this IPropertySymbol p) + { + if (p.Type.IsValueType || p.Type.ToString() == "string") + { + return TypeEnum.ValueTypeOrString; + } + + if (p.Type.TypeKind == TypeKind.Interface) + { + return TypeEnum.Interface; + } + + return TypeEnum.Complex; + } + public static string ToPropertyText(this IPropertySymbol property, string? overrideType = null) { var get = property.GetMethod != null ? "get; " : string.Empty; @@ -17,13 +33,13 @@ namespace ProxyInterfaceSourceGenerator.Extensions 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.Name}; " : string.Empty; + var set = property.SetMethod != null ? $"set => _Instance.{property.Name} = value; " : string.Empty; return $"{property.Type} {property.Name} {{ {get}{set}}}"; } - public static string ToMethodTextForInterface(this IMethodSymbol method) + public static string ToMethodText(this IMethodSymbol method) { var parameters = new List(); foreach (var ps in method.Parameters) @@ -42,7 +58,7 @@ namespace ProxyInterfaceSourceGenerator.Extensions parameters.Add($"{ps.Name}"); } - return $"{method.ToMethodTextForInterface()} => _instance.{method.Name}({string.Join(", ", parameters)});"; + return $"{method.ToMethodText()} => _Instance.{method.Name}({string.Join(", ", parameters)});"; } } } diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs index 933517d..9b80fb4 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs @@ -1,20 +1,15 @@ using System; -using System.Collections.Generic; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using ProxyInterfaceSourceGenerator.SyntaxReceiver; namespace ProxyInterfaceSourceGenerator.FileGenerators { internal abstract class BaseGenerator { protected readonly Context _context; - protected readonly IDictionary _candidateInterfaces; - public BaseGenerator(Context context, IDictionary candidateInterfaces) + public BaseGenerator(Context context) { _context = context; - _candidateInterfaces = candidateInterfaces; } protected INamedTypeSymbol GetType(string name) diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs index 8c1b61f..203f3d5 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs @@ -1,11 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using System.Text; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; +using ProxyInterfaceSourceGenerator.Enums; using ProxyInterfaceSourceGenerator.Extensions; -using ProxyInterfaceSourceGenerator.SyntaxReceiver; using ProxyInterfaceSourceGenerator.Utils; namespace ProxyInterfaceSourceGenerator.FileGenerators @@ -14,14 +11,14 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators { private readonly List files = new List(); - public PartialInterfacesGenerator(Context context, IDictionary candidateInterfaces) : - base(context, candidateInterfaces) + public PartialInterfacesGenerator(Context context) : + base(context) { } public IEnumerable GenerateFiles() { - foreach (var ci in _candidateInterfaces) + foreach (var ci in _context.CandidateInterfaces) { var file = GenerateFile(ci.Value.InterfaceName, ci.Value.TypeName, ci.Value.ProxyAll); files.Add(file); @@ -61,52 +58,42 @@ namespace {symbol.ContainingNamespace} var str = new StringBuilder(); // SimpleProperties - foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.Type.IsValueType || p.Type.ToString() == "string")) + foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.GetTypeEnum() == TypeEnum.ValueTypeOrString)) { str.AppendLine($" {property.ToPropertyText()}"); str.AppendLine(); } // InterfaceProperties - foreach (var property in MemberHelper.GetPublicProperties(symbol, - p => !(p.Type.IsValueType || p.Type.ToString() == "string"), - p => p.Type.TypeKind == TypeKind.Interface) - ) + foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.GetTypeEnum() == TypeEnum.Interface)) { str.AppendLine($" {property.ToPropertyText()}"); str.AppendLine(); } // ComplexProperties - var complexFilters = new List> + foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.GetTypeEnum() == TypeEnum.Complex)) { - p => !(p.Type.IsValueType || p.Type.ToString() == "string"), - p => p.Type.TypeKind != TypeKind.Interface - }; + //if (proxyAll) + //{ + // var existing = _context.GeneratedData + // .FirstOrDefault(x => x.ClassName == $"{property.Name}Proxy" || x.InterfaceName == $"I{property.Name}"); - foreach (var property in MemberHelper.GetPublicProperties(symbol, complexFilters.ToArray())) - { - if (proxyAll) - { - var existing = _context.GeneratedData - .FirstOrDefault(x => x.ClassName == $"{property.Name}Proxy" || x.InterfaceName == $"I{property.Name}"); - - if (existing is not null) - { - str.AppendLine($" {property.ToPropertyText(existing.InterfaceName)}"); - } - else - { - // Create new - var typeName = $"{property.Type}"; - var file = GenerateFile($"I{property.Name}", typeName, false); - str.AppendLine($" // {property.ToPropertyText($"I{property.Name}")}"); - } - } - else - { - str.AppendLine($" {property.ToPropertyText()}"); - } + // if (existing is not null) + // { + // str.AppendLine($" {property.ToPropertyText(existing.InterfaceName)}"); + // } + // else + // { + // // Create new + // var typeName = $"{property.Type}"; + // var file = GenerateFile($"I{property.Name}", typeName, false); + // str.AppendLine($" // {property.ToPropertyText($"I{property.Name}")}"); + // } + //} + //else + + str.AppendLine($" {property.ToPropertyText()}"); str.AppendLine(); } @@ -118,11 +105,11 @@ namespace {symbol.ContainingNamespace} var str = new StringBuilder(); foreach (var method in MemberHelper.GetPublicMethods(symbol)) { - str.AppendLine($" {method.ToMethodTextForInterface()};"); + str.AppendLine($" {method.ToMethodText()};"); str.AppendLine(); } - return "// Methods"; // str.ToString(); + return str.ToString(); } } } \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyAttributeGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyAttributeGenerator.cs index 520ec42..fd10040 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyAttributeGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyAttributeGenerator.cs @@ -16,7 +16,7 @@ namespace ProxyInterfaceGenerator public Type Type {{ get; }} public bool ProxyAll {{ get; }} - public {ClassName}(Type type, bool proxyAll = true) + public {ClassName}(Type type, bool proxyAll = false) {{ Type = type; ProxyAll = proxyAll; diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs index 5d606cb..67cc09a 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs @@ -1,32 +1,44 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Text; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; +using ProxyInterfaceSourceGenerator.Enums; using ProxyInterfaceSourceGenerator.Extensions; -using ProxyInterfaceSourceGenerator.SyntaxReceiver; using ProxyInterfaceSourceGenerator.Utils; namespace ProxyInterfaceSourceGenerator.FileGenerators { internal class ProxyClassesGenerator : BaseGenerator, IFilesGenerator { - public ProxyClassesGenerator(Context context, IDictionary candidateInterfaces) : - base(context, candidateInterfaces) + private readonly List files = new List(); + + public ProxyClassesGenerator(Context context) : + base(context) { } public IEnumerable GenerateFiles() { - foreach (var ci in _candidateInterfaces) + foreach (var ci in _context.CandidateInterfaces) { - var symbol = GetType(ci.Value.TypeName); - - yield return new FileData( - $"{ci.Value.ClassName}Proxy.cs", - CreateProxyClassCode(symbol, ci.Value.InterfaceName, ci.Value.ClassName, ci.Value.ProxyAll) - ); + var file = GenerateFile(ci.Value.InterfaceName, ci.Value.ClassName, ci.Value.TypeName, ci.Value.ProxyAll); + files.Add(file); } + + return files; + } + + private FileData GenerateFile(string interfaceName, string className, string typeName, bool proxyAll) + { + var symbol = GetType(typeName); + + var file = new FileData( + $"{className}Proxy.cs", + CreateProxyClassCode(symbol, interfaceName, className, proxyAll) + ); + + _context.GeneratedData.Add(new() { InterfaceName = interfaceName, ClassName = className, FileData = file }); + + return file; } private string CreateProxyClassCode(INamedTypeSymbol symbol, string interfaceName, string className, bool proxyAll) => $@"using System; @@ -35,12 +47,11 @@ namespace {symbol.ContainingNamespace} {{ public class {className}Proxy : {interfaceName} {{ - private {className} _instance; -{GeneratePrivateComplexInterfaceFields(symbol,proxyAll)} + public {className} _Instance {{ get; }} public {className}Proxy({className} instance) {{ - _instance = instance; + _Instance = instance; }} {GeneratePublicProperties(symbol, proxyAll)} @@ -48,46 +59,27 @@ namespace {symbol.ContainingNamespace} {GeneratePublicMethods(symbol)} }} }}"; - private string GeneratePrivateComplexInterfaceFields(INamedTypeSymbol symbol, bool proxyAll) - { - if (!proxyAll) - { - return string.Empty; - } - - var str = new StringBuilder(); - - foreach (var property in GetComplexProperties(symbol, proxyAll)) - { - str.AppendLine($" private {property.Type} _{property.Name};"); - } - - return str.ToString(); - } private string GeneratePublicProperties(INamedTypeSymbol symbol, bool proxyAll) { var str = new StringBuilder(); // SimpleProperties - foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.Type.IsValueType || p.Type.ToString() == "string")) + foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.GetTypeEnum() == TypeEnum.ValueTypeOrString)) { 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) - ) + foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.GetTypeEnum() == TypeEnum.Interface)) { str.AppendLine($" public {property.ToPropertyTextForClass()}"); str.AppendLine(); } // ComplexProperties - foreach (var property in GetComplexProperties(symbol, proxyAll)) + foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.GetTypeEnum() == TypeEnum.Complex)) { str.AppendLine($" public {property.ToPropertyTextForClass()}"); str.AppendLine(); @@ -96,22 +88,6 @@ namespace {symbol.ContainingNamespace} 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 GeneratePublicMethods(INamedTypeSymbol symbol) { var str = new StringBuilder(); diff --git a/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs b/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs index ec66569..17dffc6 100644 --- a/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs @@ -23,26 +23,27 @@ namespace ProxyInterfaceSourceGenerator public void Execute(GeneratorExecutionContext ctx) { - var context = new Context - { - GeneratorExecutionContext = ctx - }; - var attributeData = _proxyAttributeGenerator.GenerateFile(); - context.GeneratorExecutionContext.AddSource(attributeData.FileName, SourceText.From(attributeData.Text, Encoding.UTF8)); + ctx.AddSource(attributeData.FileName, SourceText.From(attributeData.Text, Encoding.UTF8)); - if (context.GeneratorExecutionContext.SyntaxReceiver is not ProxySyntaxReceiver receiver) + if (ctx.SyntaxReceiver is not ProxySyntaxReceiver receiver) { return; } - var partialInterfacesGenerator = new PartialInterfacesGenerator(context, receiver.CandidateInterfaces); + var context = new Context + { + GeneratorExecutionContext = ctx, + CandidateInterfaces = receiver.CandidateInterfaces + }; + + var partialInterfacesGenerator = new PartialInterfacesGenerator(context); foreach (var data in partialInterfacesGenerator.GenerateFiles()) { context.GeneratorExecutionContext.AddSource(data.FileName, SourceText.From(data.Text, Encoding.UTF8)); } - var classesGenerator = new ProxyClassesGenerator(context, receiver.CandidateInterfaces); + var classesGenerator = new ProxyClassesGenerator(context); foreach (var data in classesGenerator.GenerateFiles()) { context.GeneratorExecutionContext.AddSource(data.FileName, SourceText.From(data.Text, Encoding.UTF8)); diff --git a/src/ProxyInterfaceSourceGenerator/ProxyInterfaceSourceGenerator.csproj b/src/ProxyInterfaceSourceGenerator/ProxyInterfaceSourceGenerator.csproj index 5f89e13..baa9718 100644 --- a/src/ProxyInterfaceSourceGenerator/ProxyInterfaceSourceGenerator.csproj +++ b/src/ProxyInterfaceSourceGenerator/ProxyInterfaceSourceGenerator.csproj @@ -1,6 +1,7 @@  + 0.0.1 netstandard2.0 9 enable diff --git a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs index 8456907..77a0e99 100644 --- a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs +++ b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxySyntaxReceiver.cs @@ -38,7 +38,7 @@ namespace ProxyInterfaceSourceGenerator.SyntaxReceiver ( interfaceDeclarationSyntax.Identifier.ToString(), argumentList.Arguments[0].Expression.ChildNodes().First().GetText().ToString(), - bool.Parse(argumentList.Arguments[1].Expression.GetText().ToString()) + false //bool.Parse(argumentList.Arguments[1].Expression.GetText().ToString()) ); return true;