add methods

This commit is contained in:
Stef Heyenrath
2021-07-23 17:14:04 +02:00
parent ea99971400
commit 592f5df637
5 changed files with 134 additions and 19 deletions
@@ -1,11 +1,15 @@
namespace SourceGeneratorInterface
using System;
namespace SourceGeneratorInterface
{
public class Program
{
public static void Main()
{
IPerson ip = null;
//var i = ip.Id;
PersonProxy p = new PersonProxy(new Person());
p.Name = "test";
p.Add("x");
Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(p));
}
}
}
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Text;
using Microsoft.CodeAnalysis;
namespace ProxyInterfaceSourceGenerator.Extensions
@@ -13,6 +14,14 @@ namespace ProxyInterfaceSourceGenerator.Extensions
return $"{property.Type} {property.Name} {{ {get}{set}}}";
}
public static string ToProxyCode(this IPropertySymbol property)
{
string get = property.GetMethod != null ? $"get => _instance.{property.Name}; " : string.Empty;
string set = property.SetMethod != null ? $"set => _instance.{property.Name} = value; " : string.Empty;
return $"{property.Type} {property.Name} {{ {get}{set}}}";
}
public static string ToCode(this IMethodSymbol method)
{
var parameters = new List<string>();
@@ -21,7 +30,18 @@ namespace ProxyInterfaceSourceGenerator.Extensions
parameters.Add($"{ps.Type} {ps.Name}");
}
return $"{method.ReturnType} {method.Name}({string.Join(", ", parameters)});";
return $"{method.ReturnType} {method.Name}({string.Join(", ", parameters)})";
}
public static string ToProxyCode(this IMethodSymbol method)
{
var parameters = new List<string>();
foreach (var ps in method.Parameters)
{
parameters.Add($"{ps.Name}");
}
return $"{method.ToCode()} => _instance.{method.Name}({string.Join(", ", parameters)});";
}
}
}
@@ -22,13 +22,13 @@ namespace ClassLibrarySourceGen
public IEnumerable<Data> GenerateFiles()
{
foreach (var x in _candidateInterfaces)
foreach (var ci in _candidateInterfaces)
{
string interfaceName = $"I{x.Value.Split('.').Last()}";
string interfaceName = $"I{ci.Value.Split('.').Last()}";
yield return new Data
{
FileName = $"I{interfaceName}.cs",
Text = CreatePartialInterfaceCode(_context.Compilation.GetTypeByMetadataName(x.Value), interfaceName)
Text = CreatePartialInterfaceCode(_context.Compilation.GetTypeByMetadataName(ci.Value), interfaceName)
};
}
}
@@ -62,7 +62,7 @@ namespace {symbol.ContainingNamespace}
var str = new StringBuilder();
foreach (var method in MemberHelper.GetPublicMethods(symbol))
{
str.AppendLine($" {method.ToCode()}");
str.AppendLine($" {method.ToCode()};");
str.AppendLine();
}
@@ -0,0 +1,81 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using ProxyInterfaceSourceGenerator.Extensions;
using ProxyInterfaceSourceGenerator.FileGenerators;
using ProxyInterfaceSourceGenerator.Utils;
namespace ClassLibrarySourceGen
{
internal class ProxyClassesGenerator : IFilesGenerator
{
private readonly GeneratorExecutionContext _context;
private readonly IDictionary<InterfaceDeclarationSyntax, string> _candidateInterfaces;
public ProxyClassesGenerator(GeneratorExecutionContext context, IDictionary<InterfaceDeclarationSyntax, string> candidateInterfaces)
{
_context = context;
_candidateInterfaces = candidateInterfaces;
}
public IEnumerable<Data> GenerateFiles()
{
foreach (var ci in _candidateInterfaces)
{
string interfaceName = $"{ci.Value.Split('.').Last()}";
yield return new Data
{
FileName = $"{interfaceName}Proxy.cs",
Text = CreateProxyClassCode(_context.Compilation.GetTypeByMetadataName(ci.Value), interfaceName)
};
}
}
private string CreateProxyClassCode(INamedTypeSymbol symbol, string interfaceName) => $@"using System;
namespace {symbol.ContainingNamespace}
{{
public class {interfaceName}Proxy : I{interfaceName}
{{
private {interfaceName} _instance;
public {interfaceName}Proxy({interfaceName} instance)
{{
_instance = instance;
}}
{GenerateSimpleProperties(symbol)}
{GenerateMethods(symbol)}
}}
}}"; //{GenerateMethods(symbol)}
private string GenerateSimpleProperties(INamedTypeSymbol symbol)
{
var str = new StringBuilder();
foreach (var property in MemberHelper.GetPublicProperties(symbol, p => p.Type.IsValueType || p.Type.ToString() == "string"))
{
str.AppendLine($" public {property.ToProxyCode()}");
str.AppendLine();
}
return str.ToString();
}
private string GenerateMethods(INamedTypeSymbol symbol)
{
var str = new StringBuilder();
foreach (var method in MemberHelper.GetPublicMethods(symbol))
{
str.AppendLine($" public {method.ToProxyCode()}");
str.AppendLine();
}
return str.ToString();
}
}
}
@@ -15,10 +15,10 @@ namespace ProxyInterfaceSourceGenerator
public void Initialize(GeneratorInitializationContext context)
{
if (!Debugger.IsAttached)
{
Debugger.Launch();
}
//if (!Debugger.IsAttached)
//{
// Debugger.Launch();
//}
context.RegisterForSyntaxNotifications(() => new ProxySyntaxReceiver());
}
@@ -35,9 +35,14 @@ namespace ProxyInterfaceSourceGenerator
var p = context.Compilation.GetTypeByMetadataName("SourceGeneratorInterface.Person");
var ec = context.Compilation.GetTypeByMetadataName("Microsoft.CodeAnalysis.GeneratorExecutionContext");
var generator = new PartialInterfacesGenerator(context, receiver.CandidateInterfaces);
var partialInterfacesGenerator = new PartialInterfacesGenerator(context, receiver.CandidateInterfaces);
foreach (var data in partialInterfacesGenerator.GenerateFiles())
{
context.AddSource(data.FileName, SourceText.From(data.Text, Encoding.UTF8));
}
foreach (var data in generator.GenerateFiles())
var classesGenerator = new ProxyClassesGenerator(context, receiver.CandidateInterfaces);
foreach (var data in classesGenerator.GenerateFiles())
{
context.AddSource(data.FileName, SourceText.From(data.Text, Encoding.UTF8));
}
@@ -49,6 +54,11 @@ namespace ProxyInterfaceSourceGenerator
public int Id { get; set; }
public Clazz C { get; }
public int Add(string s)
{
return 600;
}
}
public sealed class Clazz
@@ -61,6 +71,8 @@ namespace ProxyInterfaceSourceGenerator
int Id { get; set; }
IClazz C { get; }
int Add(string s);
}
public interface IClazz
@@ -88,6 +100,8 @@ namespace ProxyInterfaceSourceGenerator
}
public IClazz C => _clazz;
public int Add(string s) => _instance.Add(s);
}
public class ClazzMock : IClazz
@@ -99,11 +113,7 @@ namespace ProxyInterfaceSourceGenerator
_instance = instance;
}
public string Name
{
get => _instance.Name;
set => _instance.Name = value;
}
public string Name { get => _instance.Name; set => _instance.Name = value; }
}
public interface IPrintable