Add support for static properties and methods (#28)
* x * Add support for static properties and methods.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
using ProxyInterfaceSourceGenerator.Model;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions;
|
||||
|
||||
@@ -18,18 +19,26 @@ internal static class PropertySymbolExtensions
|
||||
return $"{type} {property.GetSanitizedName()} {{ {get}{set}}}";
|
||||
}
|
||||
|
||||
public static string ToPropertyTextForClass(this IPropertySymbol property)
|
||||
public static string ToPropertyTextForClass(this IPropertySymbol property, ClassSymbol targetClassSymbol)
|
||||
{
|
||||
var get = property.GetMethod != null ? $"get => _Instance.{property.GetSanitizedName()}; " : string.Empty;
|
||||
var set = property.SetMethod != null ? $"set => _Instance.{property.GetSanitizedName()} = value; " : string.Empty;
|
||||
string instance = !property.IsStatic ?
|
||||
"_Instance" :
|
||||
$"{targetClassSymbol.Symbol}";
|
||||
|
||||
var get = property.GetMethod != null ? $"get => {instance}.{property.GetSanitizedName()}; " : string.Empty;
|
||||
var set = property.SetMethod != null ? $"set => {instance}.{property.GetSanitizedName()} = value; " : string.Empty;
|
||||
|
||||
return $"{property.Type} {property.GetSanitizedName()} {{ {get}{set}}}";
|
||||
}
|
||||
|
||||
public static string ToPropertyTextForClass(this IPropertySymbol property, string overrideType)
|
||||
public static string ToPropertyTextForClass(this IPropertySymbol property, ClassSymbol targetClassSymbol, string overrideType)
|
||||
{
|
||||
var get = property.GetMethod != null ? $"get => _mapper.Map<{overrideType}>(_Instance.{property.GetSanitizedName()}); " : string.Empty;
|
||||
var set = property.SetMethod != null ? $"set => _Instance.{property.GetSanitizedName()} = _mapper.Map<{property.Type}>(value); " : string.Empty;
|
||||
string instance = !property.IsStatic ?
|
||||
"_Instance" :
|
||||
$"{targetClassSymbol.Symbol}";
|
||||
|
||||
var get = property.GetMethod != null ? $"get => _mapper.Map<{overrideType}>({instance}.{property.GetSanitizedName()}); " : string.Empty;
|
||||
var set = property.SetMethod != null ? $"set => {instance}.{property.GetSanitizedName()} = _mapper.Map<{property.Type}>(value); " : string.Empty;
|
||||
|
||||
return $"{overrideType} {property.GetSanitizedName()} {{ {get}{set}}}";
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ internal abstract class BaseGenerator
|
||||
var symbol = Context.GeneratorExecutionContext.Compilation.GetTypeByMetadataName(name);
|
||||
if (symbol is not null)
|
||||
{
|
||||
return new ClassSymbol(symbol, symbol.GetBaseTypes());
|
||||
return new ClassSymbol(symbol, symbol.GetBaseTypes(), symbol.AllInterfaces.ToList());
|
||||
}
|
||||
|
||||
if (usings is not null)
|
||||
@@ -85,7 +85,7 @@ internal abstract class BaseGenerator
|
||||
symbol = Context.GeneratorExecutionContext.Compilation.GetTypeByMetadataName($"{@using}.{name}");
|
||||
if (symbol is not null)
|
||||
{
|
||||
return new ClassSymbol(symbol, symbol.GetBaseTypes());
|
||||
return new ClassSymbol(symbol, symbol.GetBaseTypes(), symbol.AllInterfaces.ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
using ProxyInterfaceSourceGenerator.Extensions;
|
||||
using ProxyInterfaceSourceGenerator.Model;
|
||||
@@ -18,11 +19,11 @@ internal class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
{
|
||||
foreach (var ci in Context.CandidateInterfaces)
|
||||
{
|
||||
yield return GenerateFile(ci.Value);
|
||||
yield return GenerateFile(ci.Value, Context.CandidateInterfaces);
|
||||
}
|
||||
}
|
||||
|
||||
private FileData GenerateFile(ProxyData pd)
|
||||
private FileData GenerateFile(ProxyData pd, IDictionary<InterfaceDeclarationSyntax, ProxyData> candidateInterfaces)
|
||||
{
|
||||
var targetClassSymbol = GetNamedTypeSymbolByFullName(pd.TypeName, pd.Usings);
|
||||
var interfaceName = targetClassSymbol.Symbol.ResolveInterfaceNameWithOptionalTypeConstraints(pd.InterfaceName);
|
||||
@@ -58,7 +59,7 @@ using AutoMapper;
|
||||
|
||||
namespace {ns}
|
||||
{{
|
||||
public class {className} : {interfaceName}
|
||||
public partial class {className} : {interfaceName}
|
||||
{{
|
||||
public {targetClassSymbol.Symbol} _Instance {{ get; }}
|
||||
|
||||
@@ -79,6 +80,7 @@ namespace {ns}
|
||||
}}
|
||||
}}
|
||||
{(SupportsNullable ? "#nullable disable" : string.Empty)}";
|
||||
|
||||
private string GeneratePrivateAutoMapper()
|
||||
{
|
||||
return Context.ReplacedTypes.Count == 0 ? string.Empty : " private readonly IMapper _mapper;";
|
||||
@@ -114,11 +116,11 @@ namespace {ns}
|
||||
var type = GetPropertyType(property, out var isReplaced);
|
||||
if (isReplaced)
|
||||
{
|
||||
str.AppendLine($" public {property.ToPropertyTextForClass(type)}");
|
||||
str.AppendLine($" public {property.ToPropertyTextForClass(targetClassSymbol, type)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
str.AppendLine($" public {property.ToPropertyTextForClass()}");
|
||||
str.AppendLine($" public {property.ToPropertyTextForClass(targetClassSymbol)}");
|
||||
}
|
||||
str.AppendLine();
|
||||
}
|
||||
@@ -168,15 +170,20 @@ namespace {ns}
|
||||
#pragma warning disable RS1024 // Compare symbols correctly
|
||||
int hash = method.ReturnType.GetHashCode();
|
||||
#pragma warning restore RS1024 // Compare symbols correctly
|
||||
|
||||
var alternateReturnVariableName = $"result_{Math.Abs(hash)}";
|
||||
|
||||
string instance = !method.IsStatic ?
|
||||
"_Instance" :
|
||||
$"{targetClassSymbol.Symbol}";
|
||||
|
||||
if (returnTypeAsString == "void")
|
||||
{
|
||||
str.AppendLine($" _Instance.{method.GetMethodNameWithOptionalTypeParameters()}({string.Join(", ", invokeParameters)});");
|
||||
str.AppendLine($" {instance}.{method.GetMethodNameWithOptionalTypeParameters()}({string.Join(", ", invokeParameters)});");
|
||||
}
|
||||
else
|
||||
{
|
||||
str.AppendLine($" var {alternateReturnVariableName} = _Instance.{method.GetMethodNameWithOptionalTypeParameters()}({string.Join(", ", invokeParameters)});");
|
||||
str.AppendLine($" var {alternateReturnVariableName} = {instance}.{method.GetMethodNameWithOptionalTypeParameters()}({string.Join(", ", invokeParameters)});");
|
||||
}
|
||||
|
||||
foreach (var ps in method.Parameters.Where(p => p.RefKind == RefKind.Out))
|
||||
|
||||
@@ -2,7 +2,7 @@ using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Model;
|
||||
|
||||
internal record ClassSymbol(INamedTypeSymbol Symbol, List<INamedTypeSymbol> BaseTypes)
|
||||
internal record ClassSymbol(INamedTypeSymbol Symbol, List<INamedTypeSymbol> BaseTypes, List<INamedTypeSymbol> Interfaces)
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
|
||||
+3
-1
@@ -14,6 +14,8 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public partial interface IPersonExtends
|
||||
{
|
||||
string StaticString { get; set; }
|
||||
|
||||
string Name { get; set; }
|
||||
|
||||
string? StringNullable { get; set; }
|
||||
@@ -24,9 +26,9 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
|
||||
bool IsAlive { get; set; }
|
||||
|
||||
bool X { get; set; }
|
||||
|
||||
|
||||
string StaticMethod(int x, string y);
|
||||
|
||||
void Void();
|
||||
|
||||
|
||||
+24
-16
@@ -13,10 +13,12 @@ using AutoMapper;
|
||||
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public class PersonExtendsProxy : IPersonExtends
|
||||
public partial class PersonExtendsProxy : IPersonExtends
|
||||
{
|
||||
public ProxyInterfaceSourceGeneratorTests.Source.PersonExtends _Instance { get; }
|
||||
|
||||
public string StaticString { get => ProxyInterfaceSourceGeneratorTests.Source.PersonExtends.StaticString; set => ProxyInterfaceSourceGeneratorTests.Source.PersonExtends.StaticString = value; }
|
||||
|
||||
public string Name { get => _Instance.Name; set => _Instance.Name = value; }
|
||||
|
||||
public string? StringNullable { get => _Instance.StringNullable; set => _Instance.StringNullable = value; }
|
||||
@@ -27,9 +29,15 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
|
||||
public bool IsAlive { get => _Instance.IsAlive; set => _Instance.IsAlive = value; }
|
||||
|
||||
public bool X { get => _Instance.X; set => _Instance.X = value; }
|
||||
|
||||
|
||||
public string StaticMethod(int x, string y)
|
||||
{
|
||||
int x_ = x;
|
||||
string y_ = y;
|
||||
var result_6851397 = ProxyInterfaceSourceGeneratorTests.Source.PersonExtends.StaticMethod(x_, y_);
|
||||
return result_6851397;
|
||||
}
|
||||
|
||||
public void Void()
|
||||
{
|
||||
@@ -39,8 +47,8 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
public string HelloWorld(string name)
|
||||
{
|
||||
string name_ = name;
|
||||
var result_58477331 = _Instance.HelloWorld(name_);
|
||||
return result_58477331;
|
||||
var result_6851397 = _Instance.HelloWorld(name_);
|
||||
return result_6851397;
|
||||
}
|
||||
|
||||
public void WithParams(params string[] values)
|
||||
@@ -53,15 +61,15 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
string s_ = s;
|
||||
string @string_ = @string;
|
||||
var result_58477331 = _Instance.Add(s_, @string_);
|
||||
return result_58477331;
|
||||
var result_6851397 = _Instance.Add(s_, @string_);
|
||||
return result_6851397;
|
||||
}
|
||||
|
||||
public int DefaultValue(int x = 100)
|
||||
{
|
||||
int x_ = x;
|
||||
var result_42930144 = _Instance.DefaultValue(x_);
|
||||
return result_42930144;
|
||||
var result_3873514 = _Instance.DefaultValue(x_);
|
||||
return result_3873514;
|
||||
}
|
||||
|
||||
public void In_Out_Ref1(in int a, out int b, ref int c)
|
||||
@@ -78,26 +86,26 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
int x_ = x;
|
||||
T1 t1_ = t1;
|
||||
T2 t2_ = t2;
|
||||
var result_38995950 = _Instance.Generic2<T1, T2>(x_, t1_, t2_);
|
||||
return result_38995950;
|
||||
var result_14331071 = _Instance.Generic2<T1, T2>(x_, t1_, t2_);
|
||||
return result_14331071;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task Method1Async()
|
||||
{
|
||||
var result_51708797 = _Instance.Method1Async();
|
||||
return result_51708797;
|
||||
var result_39535275 = _Instance.Method1Async();
|
||||
return result_39535275;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task<int> Method2Async()
|
||||
{
|
||||
var result_1620952573 = _Instance.Method2Async();
|
||||
return result_1620952573;
|
||||
var result_772784336 = _Instance.Method2Async();
|
||||
return result_772784336;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task<string?> Method3Async()
|
||||
{
|
||||
var result_1636499760 = _Instance.Method3Async();
|
||||
return result_1636499760;
|
||||
var result_769806453 = _Instance.Method3Async();
|
||||
return result_769806453;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+15
-14
@@ -35,8 +35,8 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
public string HelloWorld(string name)
|
||||
{
|
||||
string name_ = name;
|
||||
var result_56365455 = _Instance.HelloWorld(name_);
|
||||
return result_56365455;
|
||||
var result_37309470 = _Instance.HelloWorld(name_);
|
||||
return result_37309470;
|
||||
}
|
||||
|
||||
public void WithParams(params string[] values)
|
||||
@@ -49,15 +49,15 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
string s_ = s;
|
||||
string @string_ = @string;
|
||||
var result_56365455 = _Instance.Add(s_, @string_);
|
||||
return result_56365455;
|
||||
var result_37309470 = _Instance.Add(s_, @string_);
|
||||
return result_37309470;
|
||||
}
|
||||
|
||||
public int DefaultValue(int x = 100)
|
||||
{
|
||||
int x_ = x;
|
||||
var result_39875940 = _Instance.DefaultValue(x_);
|
||||
return result_39875940;
|
||||
var result_24216618 = _Instance.DefaultValue(x_);
|
||||
return result_24216618;
|
||||
}
|
||||
|
||||
public void In_Out_Ref1(in int a, out int b, ref int c)
|
||||
@@ -74,26 +74,26 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
int x_ = x;
|
||||
T1 t1_ = t1;
|
||||
T2 t2_ = t2;
|
||||
var result_41799290 = _Instance.Generic2<T1, T2>(x_, t1_, t2_);
|
||||
return result_41799290;
|
||||
var result_60333940 = _Instance.Generic2<T1, T2>(x_, t1_, t2_);
|
||||
return result_60333940;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task Method1Async()
|
||||
{
|
||||
var result_32599313 = _Instance.Method1Async();
|
||||
return result_32599313;
|
||||
var result_2292327 = _Instance.Method1Async();
|
||||
return result_2292327;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task<int> Method2Async()
|
||||
{
|
||||
var result_1620495907 = _Instance.Method2Async();
|
||||
return result_1620495907;
|
||||
var result_1229624901 = _Instance.Method2Async();
|
||||
return result_1229624901;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task<string?> Method3Async()
|
||||
{
|
||||
var result_1604006392 = _Instance.Method3Async();
|
||||
return result_1604006392;
|
||||
var result_1242717753 = _Instance.Method3Async();
|
||||
return result_1242717753;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
}
|
||||
|
||||
|
||||
public bool IsAlive { get; set; }
|
||||
}
|
||||
}
|
||||
#nullable disable
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using AnyOfTypes;
|
||||
@@ -6,6 +7,7 @@ using CSharp.SourceGenerators.Extensions.Models;
|
||||
using FluentAssertions;
|
||||
using ProxyInterfaceSourceGenerator;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace ProxyInterfaceSourceGeneratorTests
|
||||
{
|
||||
@@ -109,6 +111,8 @@ namespace ProxyInterfaceSourceGeneratorTests
|
||||
result.Valid.Should().BeTrue();
|
||||
result.Files.Should().HaveCount(5);
|
||||
|
||||
throw new Exception();
|
||||
|
||||
// Assert attribute
|
||||
var attribute = result.Files[0].SyntaxTree;
|
||||
attribute.FilePath.Should().EndWith(attributeFilename);
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public class Human : Animal
|
||||
public class Human
|
||||
{
|
||||
public bool IsAlive { get; set; }
|
||||
}
|
||||
|
||||
public class Animal
|
||||
{
|
||||
public bool X { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public partial interface IPerson
|
||||
public partial interface IPerson : IHuman
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,13 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public class PersonExtends : Human
|
||||
{
|
||||
public static string StaticMethod(int x, string y)
|
||||
{
|
||||
return "test";
|
||||
}
|
||||
|
||||
public static string StaticString { get; set; } = "500";
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string? StringNullable { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user