Add support for base (proxy) class (#29)
This commit is contained in:
@@ -1,12 +1,5 @@
|
||||
namespace ProxyInterfaceConsumer
|
||||
namespace ProxyInterfaceConsumer
|
||||
{
|
||||
[ProxyInterfaceGenerator.Proxy(typeof(ProxyInterfaceConsumer.PersonT<,>))]
|
||||
public partial interface IPersonT<T1, T2>
|
||||
where T1 : struct
|
||||
where T2 : class, new()
|
||||
{
|
||||
}
|
||||
|
||||
[ProxyInterfaceGenerator.Proxy(typeof(ProxyInterfaceConsumer.PersonTT<,>))]
|
||||
public partial interface IPersonTT<T1, T2>
|
||||
where T1 : struct
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace ProxyInterfaceConsumer
|
||||
namespace ProxyInterfaceConsumer
|
||||
{
|
||||
public class PersonT<T> where T: struct
|
||||
public class PersonT<T> where T : struct
|
||||
{
|
||||
public T TVal { get; set; }
|
||||
|
||||
@@ -8,5 +8,10 @@
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
public PersonT<T> Call2(int x, PersonT<T> pt)
|
||||
{
|
||||
return new PersonT<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,5 @@
|
||||
namespace ProxyInterfaceConsumer
|
||||
namespace ProxyInterfaceConsumer
|
||||
{
|
||||
public class PersonT<T1, T2>
|
||||
where T1 : struct
|
||||
where T2 : class, new()
|
||||
{
|
||||
public T1 TVal1 { get; set; }
|
||||
|
||||
public T2 TVal2 { get; set; }
|
||||
|
||||
public void Call(int x, T1 t1, T2 t2)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class PersonTT<T1, T2>
|
||||
where T1 : struct
|
||||
where T2 : class, new()
|
||||
|
||||
@@ -15,10 +15,12 @@ namespace ProxyInterfaceConsumer
|
||||
|
||||
public static void Main()
|
||||
{
|
||||
//IPersonT<int> pT = new PersonTProxy<int>(new PersonT<int>());
|
||||
//pT.TVal = 1;
|
||||
//Console.WriteLine(JsonSerializer.Serialize(pT, JsonSerializerOptions));
|
||||
//Console.WriteLine(new string('-', 80));
|
||||
var t = new TestProxy(new Test());
|
||||
|
||||
IPersonT<int> pT = new PersonTProxy<int>(new PersonT<int>());
|
||||
pT.TVal = 1;
|
||||
Console.WriteLine(JsonSerializer.Serialize(pT, JsonSerializerOptions));
|
||||
Console.WriteLine(new string('-', 80));
|
||||
|
||||
//IPersonTT<int, Program> pTT = new PersonTTProxy<int, Program>(new PersonTT<int, Program>());
|
||||
//pTT.TVal1 = 42;
|
||||
@@ -43,7 +45,8 @@ namespace ProxyInterfaceConsumer
|
||||
Console.WriteLine(JsonSerializer.Serialize(p, JsonSerializerOptions));
|
||||
}
|
||||
}
|
||||
public struct Test
|
||||
|
||||
public class Test
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
@@ -51,10 +54,20 @@ namespace ProxyInterfaceConsumer
|
||||
|
||||
public IList<Clazz> Cs { get; set; }
|
||||
|
||||
public int Add(string s)
|
||||
public int AddString(string s)
|
||||
{
|
||||
return 600;
|
||||
}
|
||||
|
||||
public Test AddTest(Test t)
|
||||
{
|
||||
return new Test();
|
||||
}
|
||||
|
||||
public Clazz AddClazz(Clazz c)
|
||||
{
|
||||
return new Clazz();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Clazz
|
||||
@@ -62,88 +75,13 @@ namespace ProxyInterfaceConsumer
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public interface ITest
|
||||
[ProxyInterfaceGenerator.Proxy(typeof(Test))]
|
||||
public partial interface ITest
|
||||
{
|
||||
int Id { get; set; }
|
||||
|
||||
IClazz C { get; }
|
||||
|
||||
IList<IClazz> Cs { get; set; }
|
||||
|
||||
int Add(string s);
|
||||
}
|
||||
|
||||
public interface IClazz
|
||||
[ProxyInterfaceGenerator.Proxy(typeof(Clazz))]
|
||||
public partial interface IClazz
|
||||
{
|
||||
string Name { get; set; }
|
||||
}
|
||||
|
||||
public class TestProxy : ITest
|
||||
{
|
||||
private Test _instance;
|
||||
|
||||
private IClazz _clazz;
|
||||
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public TestProxy(Test instance)
|
||||
{
|
||||
_instance = instance;
|
||||
|
||||
// _clazz = new ClazzProxy(_instance.C);
|
||||
|
||||
_mapper = new MapperConfiguration(cfg =>
|
||||
{
|
||||
//cfg.CreateMap<Clazz, ClazzProxy>();
|
||||
//cfg.CreateMap<ClazzProxy, Clazz>();
|
||||
|
||||
cfg.CreateMap<Clazz, IClazz>();
|
||||
cfg.CreateMap<IClazz, Clazz>();
|
||||
}).CreateMapper();
|
||||
}
|
||||
|
||||
public int Id
|
||||
{
|
||||
get => _instance.Id;
|
||||
set => _instance.Id = value;
|
||||
}
|
||||
|
||||
public IClazz C => _clazz;
|
||||
|
||||
public IList<IClazz> Cs2
|
||||
{
|
||||
get
|
||||
{
|
||||
//return null; // TinyMapper.Map<IList<IClazz>>(_instance.Cs); //(IList<IClazz>)_instance.Cs.Select(x => new ClazzProxy(x));
|
||||
return _mapper.Map<IList<IClazz>>(_instance.Cs); //(IList<IClazz>)_instance.Cs.Select(x => new ClazzProxy(x));
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_instance.Cs = _mapper.Map<IList<Clazz>>(value);
|
||||
//_instance.Cs = TinyMapper.Map<IList<Clazz>>(value);
|
||||
}
|
||||
}
|
||||
|
||||
public IList<IClazz> Cs
|
||||
{
|
||||
get => _mapper.Map<IList<IClazz>>(_instance.Cs);
|
||||
|
||||
set => _instance.Cs = _mapper.Map<IList<Clazz>>(value);
|
||||
}
|
||||
|
||||
public int Add(string s) => _instance.Add(s);
|
||||
}
|
||||
|
||||
public class ClazzProxy : IClazz
|
||||
{
|
||||
private Clazz _instance;
|
||||
|
||||
public ClazzProxy(Clazz instance)
|
||||
{
|
||||
_instance = instance;
|
||||
}
|
||||
|
||||
public string Name { get => _instance.Name; set => _instance.Name = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="IPersonT.cs" />
|
||||
<Compile Remove="IPersonTT.cs" />
|
||||
<Compile Remove="PersonT.cs" />
|
||||
<Compile Remove="PersonTT.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -71,4 +71,11 @@ internal static class NamedTypeSymbolExtensions
|
||||
$"{namedTypeSymbol.Name}Proxy" :
|
||||
$"{namedTypeSymbol.Name}Proxy<{string.Join(", ", namedTypeSymbol.TypeArguments.Select(ta => ta.Name))}>";
|
||||
}
|
||||
|
||||
public static string ResolveFullProxyClassName(this INamedTypeSymbol namedTypeSymbol)
|
||||
{
|
||||
return !namedTypeSymbol.IsGenericType ?
|
||||
$"{namedTypeSymbol}Proxy" :
|
||||
$"{namedTypeSymbol}Proxy<{string.Join(", ", namedTypeSymbol.TypeArguments.Select(ta => ta.Name))}>";
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
using ProxyInterfaceSourceGenerator.Model;
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions;
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions;
|
||||
|
||||
internal static class StringExtensions
|
||||
{
|
||||
// See https://andrewlock.net/why-is-string-gethashcode-different-each-time-i-run-my-program-in-net-core/
|
||||
public static string GetDeterministicHashCodeAsString(this string str)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hash1 = (5381 << 16) + 5381;
|
||||
int hash2 = hash1;
|
||||
|
||||
for (int i = 0; i < str.Length; i += 2)
|
||||
{
|
||||
hash1 = ((hash1 << 5) + hash1) ^ str[i];
|
||||
if (i == str.Length - 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
|
||||
}
|
||||
|
||||
int result = hash1 + hash2 * 1566083941;
|
||||
|
||||
return result.ToString().Replace('-', '_');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,9 @@ internal static class TypeSymbolExtensions
|
||||
return TypeEnum.Complex;
|
||||
}
|
||||
|
||||
public static bool IsString(this ITypeSymbol ts)
|
||||
{
|
||||
return ts.ToString() == "string" || ts.ToString() == "string?";
|
||||
}
|
||||
public static bool IsString(this ITypeSymbol ts) =>
|
||||
ts.ToString() == "string" || ts.ToString() == "string?";
|
||||
|
||||
internal static bool IsClass(this ITypeSymbol ts) =>
|
||||
ts.IsReferenceType && ts.TypeKind == TypeKind.Class;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Extensions;
|
||||
using ProxyInterfaceSourceGenerator.Model;
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
|
||||
@@ -36,11 +37,11 @@ internal abstract class BaseGenerator
|
||||
{
|
||||
if (!Context.ReplacedTypes.ContainsKey(typeSymbolAsString))
|
||||
{
|
||||
Context.ReplacedTypes.Add(typeSymbolAsString, existing.InterfaceName);
|
||||
Context.ReplacedTypes.Add(typeSymbolAsString, existing.FullInterfaceName);
|
||||
}
|
||||
|
||||
isReplaced = true;
|
||||
return existing.InterfaceName;
|
||||
return existing.FullInterfaceName;
|
||||
}
|
||||
|
||||
if (typeSymbol is INamedTypeSymbol namedTypedSymbol)
|
||||
@@ -56,10 +57,10 @@ internal abstract class BaseGenerator
|
||||
|
||||
if (!Context.ReplacedTypes.ContainsKey(typeArgumentAsString))
|
||||
{
|
||||
Context.ReplacedTypes.Add(typeArgumentAsString, exist.InterfaceName);
|
||||
Context.ReplacedTypes.Add(typeArgumentAsString, exist.FullInterfaceName);
|
||||
}
|
||||
|
||||
propertyTypeAsStringToBeModified = propertyTypeAsStringToBeModified.Replace(typeArgumentAsString, exist.InterfaceName);
|
||||
propertyTypeAsStringToBeModified = propertyTypeAsStringToBeModified.Replace(typeArgumentAsString, exist.FullInterfaceName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,27 +70,28 @@ internal abstract class BaseGenerator
|
||||
return typeSymbolAsString;
|
||||
}
|
||||
|
||||
protected ClassSymbol GetNamedTypeSymbolByFullName(string name, IEnumerable<string>? usings = null)
|
||||
protected bool TryGetNamedTypeSymbolByFullName(TypeKind kind, string name, IEnumerable<string> usings, [NotNullWhen(true)] out ClassSymbol? classSymbol)
|
||||
{
|
||||
classSymbol = default;
|
||||
|
||||
// The GetTypeByMetadataName method returns null if no type matches the full name or if 2 or more types (in different assemblies) match the full name.
|
||||
var symbol = Context.GeneratorExecutionContext.Compilation.GetTypeByMetadataName(name);
|
||||
if (symbol is not null)
|
||||
if (symbol is not null && symbol.TypeKind == kind)
|
||||
{
|
||||
return new ClassSymbol(symbol, symbol.GetBaseTypes(), symbol.AllInterfaces.ToList());
|
||||
classSymbol = new ClassSymbol(symbol, symbol.GetBaseTypes(), symbol.AllInterfaces.ToList());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (usings is not null)
|
||||
foreach (var @using in usings)
|
||||
{
|
||||
foreach (var @using in usings)
|
||||
symbol = Context.GeneratorExecutionContext.Compilation.GetTypeByMetadataName($"{@using}.{name}");
|
||||
if (symbol is not null && symbol.TypeKind == kind)
|
||||
{
|
||||
symbol = Context.GeneratorExecutionContext.Compilation.GetTypeByMetadataName($"{@using}.{name}");
|
||||
if (symbol is not null)
|
||||
{
|
||||
return new ClassSymbol(symbol, symbol.GetBaseTypes(), symbol.AllInterfaces.ToList());
|
||||
}
|
||||
classSymbol = new ClassSymbol(symbol, symbol.GetBaseTypes(), symbol.AllInterfaces.ToList());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception($"The type '{name}' is not found.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
|
||||
internal record FileData(string FileName, string Text);
|
||||
@@ -1,3 +1,5 @@
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
|
||||
internal interface IFileGenerator
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
|
||||
internal interface IFilesGenerator
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
using ProxyInterfaceSourceGenerator.Extensions;
|
||||
using ProxyInterfaceSourceGenerator.Model;
|
||||
using ProxyInterfaceSourceGenerator.SyntaxReceiver;
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
using ProxyInterfaceSourceGenerator.Utils;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
@@ -19,22 +20,35 @@ internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
|
||||
{
|
||||
foreach (var ci in Context.CandidateInterfaces)
|
||||
{
|
||||
yield return GenerateFile(ci.Key, ci.Value);
|
||||
if (TryGenerateFile(ci.Key, ci.Value, out var file))
|
||||
{
|
||||
yield return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FileData GenerateFile(InterfaceDeclarationSyntax ci, ProxyData pd)
|
||||
private bool TryGenerateFile(InterfaceDeclarationSyntax ci, ProxyData pd, [NotNullWhen(true)] out FileData? fileData)
|
||||
{
|
||||
var sourceInterfaceSymbol = GetNamedTypeSymbolByFullName(ci.Identifier.ToString(), pd.Usings);
|
||||
var targetClassSymbol = GetNamedTypeSymbolByFullName(pd.TypeName, pd.Usings);
|
||||
var interfaceName = targetClassSymbol.Symbol.ResolveInterfaceNameWithOptionalTypeConstraints(pd.InterfaceName);
|
||||
fileData = default;
|
||||
|
||||
var file = new FileData(
|
||||
if (!TryGetNamedTypeSymbolByFullName(TypeKind.Interface, ci.Identifier.ToString(), pd.Usings, out var sourceInterfaceSymbol))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TryGetNamedTypeSymbolByFullName(TypeKind.Class, pd.TypeName, pd.Usings, out var targetClassSymbol))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var interfaceName = targetClassSymbol.Symbol.ResolveInterfaceNameWithOptionalTypeConstraints(pd.ShortInterfaceName);
|
||||
|
||||
fileData = new FileData(
|
||||
$"{sourceInterfaceSymbol.Symbol.GetFileName()}.g.cs",
|
||||
CreatePartialInterfaceCode(pd.Namespace, targetClassSymbol, interfaceName, pd.ProxyBaseClasses)
|
||||
);
|
||||
|
||||
return file;
|
||||
return true;
|
||||
}
|
||||
|
||||
private string CreatePartialInterfaceCode(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
|
||||
internal class ProxyAttributeGenerator : IFileGenerator
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
using ProxyInterfaceSourceGenerator.Extensions;
|
||||
using ProxyInterfaceSourceGenerator.Model;
|
||||
using ProxyInterfaceSourceGenerator.SyntaxReceiver;
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
using ProxyInterfaceSourceGenerator.Utils;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
|
||||
internal class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
{
|
||||
public ProxyClassesGenerator(Context context, bool supportsNullable) : base(context, supportsNullable)
|
||||
{
|
||||
@@ -19,32 +18,72 @@ internal class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
{
|
||||
foreach (var ci in Context.CandidateInterfaces)
|
||||
{
|
||||
yield return GenerateFile(ci.Value, Context.CandidateInterfaces);
|
||||
if (TryGenerateFile(ci.Value, out var file))
|
||||
{
|
||||
yield return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FileData GenerateFile(ProxyData pd, IDictionary<InterfaceDeclarationSyntax, ProxyData> candidateInterfaces)
|
||||
[SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1024:Compare symbols correctly", Justification = "<Pending>")]
|
||||
private bool TryGenerateFile(ProxyData pd, [NotNullWhen(true)] out FileData? fileData)
|
||||
{
|
||||
var targetClassSymbol = GetNamedTypeSymbolByFullName(pd.TypeName, pd.Usings);
|
||||
var interfaceName = targetClassSymbol.Symbol.ResolveInterfaceNameWithOptionalTypeConstraints(pd.InterfaceName);
|
||||
fileData = default;
|
||||
|
||||
if (!TryGetNamedTypeSymbolByFullName(TypeKind.Class, pd.TypeName, pd.Usings, out var targetClassSymbol))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var interfaceName = targetClassSymbol.Symbol.ResolveInterfaceNameWithOptionalTypeConstraints(pd.ShortInterfaceName);
|
||||
var className = targetClassSymbol.Symbol.ResolveProxyClassName();
|
||||
var constructorName = $"{targetClassSymbol.Symbol.Name}Proxy";
|
||||
|
||||
var file = new FileData(
|
||||
var extendsProxyClasses = targetClassSymbol.BaseTypes
|
||||
.Join(
|
||||
Context.CandidateInterfaces.Values.Select(v => v.RawTypeName),
|
||||
bt => bt.ToString(),
|
||||
ci => ci, (bt, _) => bt
|
||||
).ToList();
|
||||
|
||||
fileData = new FileData(
|
||||
$"{targetClassSymbol.Symbol.GetFileName()}Proxy.g.cs",
|
||||
CreateProxyClassCode(pd.Namespace, targetClassSymbol, pd.ProxyBaseClasses, interfaceName, className, constructorName)
|
||||
CreateProxyClassCode(pd, targetClassSymbol, extendsProxyClasses, interfaceName, className, constructorName)
|
||||
);
|
||||
|
||||
return file;
|
||||
return true;
|
||||
}
|
||||
|
||||
private string CreateProxyClassCode(
|
||||
string ns,
|
||||
ProxyData pd,
|
||||
ClassSymbol targetClassSymbol,
|
||||
bool proxyBaseClasses,
|
||||
List<INamedTypeSymbol> extendsProxyClasses,
|
||||
string interfaceName,
|
||||
string className,
|
||||
string constructorName) => $@"//----------------------------------------------------------------------------------------
|
||||
string constructorName)
|
||||
{
|
||||
var extendsFullNames = extendsProxyClasses.Select(e => e.ResolveFullProxyClassName()).ToList();
|
||||
var extends = extendsProxyClasses.Any() ? $"{string.Join(", ", extendsFullNames)}, " : string.Empty;
|
||||
var @base = extendsProxyClasses.Any() ? " : base(instance)" : string.Empty;
|
||||
var @new = extendsProxyClasses.Any() ? "new " : string.Empty;
|
||||
var instanceBaseDefinition = extendsProxyClasses.Any() ? $"public {extendsProxyClasses.First()} _InstanceBase {{ get; }}\r\n" : string.Empty;
|
||||
var instanceBaseSet = extendsProxyClasses.Any() ? "_InstanceBase = instance;" : string.Empty;
|
||||
|
||||
var properties = GeneratePublicProperties(targetClassSymbol, pd.ProxyBaseClasses);
|
||||
var methods = GeneratePublicMethods(targetClassSymbol, pd.ProxyBaseClasses);
|
||||
var events = GenerateEvents(targetClassSymbol, pd.ProxyBaseClasses);
|
||||
|
||||
var configurationForAutoMapper = string.Empty;
|
||||
var privateAutoMapper = string.Empty;
|
||||
var usingAutoMapper = string.Empty;
|
||||
if (Context.ReplacedTypes.Any())
|
||||
{
|
||||
configurationForAutoMapper = GenerateMapperConfigurationForAutoMapper();
|
||||
privateAutoMapper = GeneratePrivateAutoMapper();
|
||||
usingAutoMapper = "using AutoMapper;";
|
||||
}
|
||||
|
||||
return $@"//----------------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator.
|
||||
//
|
||||
@@ -55,52 +94,52 @@ internal class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
|
||||
{(SupportsNullable ? "#nullable enable" : string.Empty)}
|
||||
using System;
|
||||
using AutoMapper;
|
||||
{usingAutoMapper}
|
||||
|
||||
namespace {ns}
|
||||
namespace {pd.Namespace}
|
||||
{{
|
||||
public partial class {className} : {interfaceName}
|
||||
public partial class {className} : {extends}{interfaceName}
|
||||
{{
|
||||
public {targetClassSymbol.Symbol} _Instance {{ get; }}
|
||||
public {@new}{targetClassSymbol.Symbol} _Instance {{ get; }}
|
||||
{instanceBaseDefinition}
|
||||
|
||||
{GeneratePublicProperties(targetClassSymbol, proxyBaseClasses)}
|
||||
{properties}
|
||||
|
||||
{GeneratePublicMethods(targetClassSymbol, proxyBaseClasses)}
|
||||
{methods}
|
||||
|
||||
{GenerateEvents(targetClassSymbol, proxyBaseClasses)}
|
||||
{events}
|
||||
|
||||
public {constructorName}({targetClassSymbol} instance)
|
||||
public {constructorName}({targetClassSymbol} instance){@base}
|
||||
{{
|
||||
_Instance = instance;
|
||||
{instanceBaseSet}
|
||||
|
||||
{GenerateMapperConfigurationForAutoMapper()}
|
||||
{configurationForAutoMapper}
|
||||
}}
|
||||
|
||||
{GeneratePrivateAutoMapper()}
|
||||
{privateAutoMapper}
|
||||
}}
|
||||
}}
|
||||
{(SupportsNullable ? "#nullable disable" : string.Empty)}";
|
||||
}
|
||||
|
||||
private string GeneratePrivateAutoMapper()
|
||||
private static string GeneratePrivateAutoMapper()
|
||||
{
|
||||
return Context.ReplacedTypes.Count == 0 ? string.Empty : " private readonly IMapper _mapper;";
|
||||
return " private readonly IMapper _mapper;";
|
||||
}
|
||||
|
||||
private string GenerateMapperConfigurationForAutoMapper()
|
||||
{
|
||||
if (Context.ReplacedTypes.Count == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var str = new StringBuilder();
|
||||
|
||||
str.AppendLine(" _mapper = new MapperConfiguration(cfg =>");
|
||||
str.AppendLine(" {");
|
||||
foreach (var replacedType in Context.ReplacedTypes)
|
||||
{
|
||||
str.AppendLine($" cfg.CreateMap<{replacedType.Key}, {replacedType.Value}>();");
|
||||
str.AppendLine($" cfg.CreateMap<{replacedType.Value}, {replacedType.Key}>();");
|
||||
var proxy = $"{replacedType.Key}Proxy";
|
||||
|
||||
str.AppendLine($" cfg.CreateMap<{replacedType.Key}, {replacedType.Value}>().ConstructUsing(instance => new {proxy}(instance));");
|
||||
str.AppendLine($" cfg.CreateMap<{replacedType.Value}, {replacedType.Key}>().ConstructUsing(proxy => (({proxy}) proxy)._Instance);");
|
||||
}
|
||||
str.AppendLine(" }).CreateMapper();");
|
||||
|
||||
@@ -167,11 +206,8 @@ namespace {ns}
|
||||
str.AppendLine($" {ps.Type} {ps.GetSanitizedName()}_{normalOrMap};");
|
||||
}
|
||||
|
||||
#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)}";
|
||||
var methodName = method.GetMethodNameWithOptionalTypeParameters();
|
||||
var alternateReturnVariableName = $"result_{methodName.GetDeterministicHashCodeAsString()}";
|
||||
|
||||
string instance = !method.IsStatic ?
|
||||
"_Instance" :
|
||||
@@ -179,11 +215,11 @@ namespace {ns}
|
||||
|
||||
if (returnTypeAsString == "void")
|
||||
{
|
||||
str.AppendLine($" {instance}.{method.GetMethodNameWithOptionalTypeParameters()}({string.Join(", ", invokeParameters)});");
|
||||
str.AppendLine($" {instance}.{methodName}({string.Join(", ", invokeParameters)});");
|
||||
}
|
||||
else
|
||||
{
|
||||
str.AppendLine($" var {alternateReturnVariableName} = {instance}.{method.GetMethodNameWithOptionalTypeParameters()}({string.Join(", ", invokeParameters)});");
|
||||
str.AppendLine($" var {alternateReturnVariableName} = {instance}.{methodName}({string.Join(", ", invokeParameters)});");
|
||||
}
|
||||
|
||||
foreach (var ps in method.Parameters.Where(p => p.RefKind == RefKind.Out))
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Model;
|
||||
namespace ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
internal record ClassSymbol(INamedTypeSymbol Symbol, List<INamedTypeSymbol> BaseTypes, List<INamedTypeSymbol> Interfaces)
|
||||
{
|
||||
+14
-15
@@ -1,16 +1,15 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using ProxyInterfaceSourceGenerator.SyntaxReceiver;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator;
|
||||
|
||||
internal record Context
|
||||
{
|
||||
public GeneratorExecutionContext GeneratorExecutionContext { get; init; }
|
||||
|
||||
// public List<ContextData> GeneratedData { get; } = new List<ContextData>();
|
||||
|
||||
public IDictionary<InterfaceDeclarationSyntax, ProxyData> CandidateInterfaces { get; init; } = default!;
|
||||
|
||||
public Dictionary<string, string> ReplacedTypes { get; } = new Dictionary<string, string>();
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
internal record Context
|
||||
{
|
||||
public GeneratorExecutionContext GeneratorExecutionContext { get; init; }
|
||||
|
||||
// public List<ContextData> GeneratedData { get; } = new List<ContextData>();
|
||||
|
||||
public IDictionary<InterfaceDeclarationSyntax, ProxyData> CandidateInterfaces { get; init; } = default!;
|
||||
|
||||
public Dictionary<string, string> ReplacedTypes { get; } = new Dictionary<string, string>();
|
||||
}
|
||||
+9
-11
@@ -1,12 +1,10 @@
|
||||
using ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator;
|
||||
|
||||
internal record ContextData
|
||||
{
|
||||
public string? InterfaceName { get; init; }
|
||||
|
||||
public string? ClassName { get; init; }
|
||||
|
||||
public FileData FileData { get; init; } = default!;
|
||||
namespace ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
internal record ContextData
|
||||
{
|
||||
public string? InterfaceName { get; init; }
|
||||
|
||||
public string? ClassName { get; init; }
|
||||
|
||||
public FileData FileData { get; init; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
internal record FileData(string FileName, string Text);
|
||||
+11
-10
@@ -1,11 +1,12 @@
|
||||
namespace ProxyInterfaceSourceGenerator.SyntaxReceiver;
|
||||
|
||||
internal record ProxyData
|
||||
(
|
||||
string Namespace,
|
||||
string InterfaceName,
|
||||
string RawTypeName,
|
||||
string TypeName,
|
||||
List<string> Usings,
|
||||
bool ProxyBaseClasses
|
||||
namespace ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
internal record ProxyData
|
||||
(
|
||||
string Namespace,
|
||||
string ShortInterfaceName,
|
||||
string FullInterfaceName,
|
||||
string RawTypeName,
|
||||
string TypeName,
|
||||
List<string> Usings,
|
||||
bool ProxyBaseClasses
|
||||
);
|
||||
@@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
using ProxyInterfaceSourceGenerator.SyntaxReceiver;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator;
|
||||
@@ -10,7 +11,7 @@ namespace ProxyInterfaceSourceGenerator;
|
||||
[Generator]
|
||||
internal class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
{
|
||||
private readonly ProxyAttributeGenerator _proxyAttributeGenerator = new ProxyAttributeGenerator();
|
||||
private readonly ProxyAttributeGenerator _proxyAttributeGenerator = new ();
|
||||
|
||||
public void Initialize(GeneratorInitializationContext context)
|
||||
{
|
||||
@@ -24,21 +25,21 @@ internal class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
|
||||
public void Execute(GeneratorExecutionContext context)
|
||||
{
|
||||
if (context.ParseOptions is not CSharpParseOptions csharpParseOptions)
|
||||
{
|
||||
throw new NotSupportedException("Only C# is supported.");
|
||||
}
|
||||
|
||||
if (context.SyntaxReceiver is not ProxySyntaxReceiver receiver)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// https://github.com/reactiveui/refit/blob/main/InterfaceStubGenerator.Core/InterfaceStubGenerator.cs
|
||||
var supportsNullable = csharpParseOptions.LanguageVersion >= LanguageVersion.CSharp8;
|
||||
|
||||
try
|
||||
{
|
||||
if (context.ParseOptions is not CSharpParseOptions csharpParseOptions)
|
||||
{
|
||||
throw new NotSupportedException("Only C# is supported.");
|
||||
}
|
||||
|
||||
if (context.SyntaxReceiver is not ProxySyntaxReceiver receiver)
|
||||
{
|
||||
throw new NotSupportedException($"Only {nameof(ProxySyntaxReceiver)} is supported.");
|
||||
}
|
||||
|
||||
// https://github.com/reactiveui/refit/blob/main/InterfaceStubGenerator.Core/InterfaceStubGenerator.cs
|
||||
var supportsNullable = csharpParseOptions.LanguageVersion >= LanguageVersion.CSharp8;
|
||||
|
||||
GenerateProxyAttribute(context, receiver);
|
||||
GeneratePartialInterfaces(context, receiver, supportsNullable);
|
||||
GenerateProxyClasses(context, receiver, supportsNullable);
|
||||
@@ -51,7 +52,7 @@ internal class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
|
||||
private void GenerateError(GeneratorExecutionContext context, Exception exception)
|
||||
{
|
||||
var message = $"/*\r\n{nameof(ProxyInterfaceCodeGenerator)}\r\n\r\n{exception}\r\n\r\n{exception.StackTrace}*/";
|
||||
var message = $"/*\r\n{nameof(ProxyInterfaceCodeGenerator)}\r\n\r\n[Exception]\r\n{exception}\r\n\r\n[StackTrace]\r\n{exception.StackTrace}*/";
|
||||
context.AddSource("Error.g", SourceText.From(message, Encoding.UTF8));
|
||||
}
|
||||
|
||||
@@ -76,9 +77,9 @@ internal class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
};
|
||||
|
||||
var partialInterfacesGenerator = new PartialInterfacesGenerator(context, supportsNullable);
|
||||
foreach (var data in partialInterfacesGenerator.GenerateFiles())
|
||||
foreach (var (fileName, text) in partialInterfacesGenerator.GenerateFiles())
|
||||
{
|
||||
context.GeneratorExecutionContext.AddSource(data.FileName, SourceText.From(data.Text, Encoding.UTF8));
|
||||
context.GeneratorExecutionContext.AddSource(fileName, SourceText.From(text, Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,9 +92,9 @@ internal class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
};
|
||||
|
||||
var proxyClassesGenerator = new ProxyClassesGenerator(context, supportsNullable);
|
||||
foreach (var data in proxyClassesGenerator.GenerateFiles())
|
||||
foreach (var (fileName, text) in proxyClassesGenerator.GenerateFiles())
|
||||
{
|
||||
context.GeneratorExecutionContext.AddSource(data.FileName, SourceText.From(data.Text, Encoding.UTF8));
|
||||
context.GeneratorExecutionContext.AddSource(fileName, SourceText.From(text, Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="10.1.1" />
|
||||
<!--<PackageReference Include="AutoMapper" Version="10.1.1" />-->
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
@@ -46,11 +46,19 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="bin\Debug\netstandard2.0\\ProxyInterfaceGenerator.dll" />
|
||||
<None Remove="bin\Release\netstandard2.0\\ProxyInterfaceGenerator.dll" />
|
||||
<ProjectCapability Include="DynamicDependentFile" />
|
||||
<ProjectCapability Include="DynamicFileNesting" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="ProxyClassesGenerator.*.cs">
|
||||
<DependentUpon>ProxyClassesGenerator.cs</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="bin\Debug\netstandard2.0\\ProxyInterfaceGenerator.dll" />
|
||||
<None Remove="bin\Release\netstandard2.0\\ProxyInterfaceGenerator.dll" />
|
||||
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using ProxyInterfaceSourceGenerator.Extensions;
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.SyntaxReceiver;
|
||||
|
||||
@@ -44,13 +45,13 @@ internal class ProxySyntaxReceiver : ISyntaxReceiver
|
||||
var usings = new List<string>();
|
||||
|
||||
string ns = string.Empty;
|
||||
if (SyntaxNodeUtils.TryGetParentSyntax(interfaceDeclarationSyntax, out NamespaceDeclarationSyntax? namespaceDeclarationSyntax))
|
||||
if (interfaceDeclarationSyntax.TryGetParentSyntax(out NamespaceDeclarationSyntax? namespaceDeclarationSyntax))
|
||||
{
|
||||
ns = namespaceDeclarationSyntax.Name.ToString();
|
||||
usings.Add(ns);
|
||||
}
|
||||
|
||||
if (SyntaxNodeUtils.TryGetParentSyntax(interfaceDeclarationSyntax, out CompilationUnitSyntax? cc))
|
||||
if (interfaceDeclarationSyntax.TryGetParentSyntax(out CompilationUnitSyntax? cc))
|
||||
{
|
||||
foreach (var @using in cc.Usings)
|
||||
{
|
||||
@@ -58,7 +59,9 @@ internal class ProxySyntaxReceiver : ISyntaxReceiver
|
||||
}
|
||||
}
|
||||
|
||||
string rawTypeName = ((TypeOfExpressionSyntax)argumentList.Arguments[0].Expression).Type.ToString();
|
||||
var type = ((TypeOfExpressionSyntax)argumentList.Arguments[0].Expression).Type;
|
||||
|
||||
string rawTypeName = type.ToString();
|
||||
bool proxyAllClasses;
|
||||
try
|
||||
{
|
||||
@@ -73,6 +76,7 @@ internal class ProxySyntaxReceiver : ISyntaxReceiver
|
||||
(
|
||||
ns,
|
||||
interfaceDeclarationSyntax.Identifier.ToString(),
|
||||
$"{ns}.{interfaceDeclarationSyntax.Identifier}",
|
||||
rawTypeName,
|
||||
ConvertTypeName(rawTypeName),
|
||||
usings,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Model;
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Utils;
|
||||
|
||||
|
||||
+6
-2
@@ -9,16 +9,19 @@
|
||||
|
||||
#nullable enable
|
||||
using System;
|
||||
using AutoMapper;
|
||||
|
||||
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public class HumanProxy : IHuman
|
||||
public partial class HumanProxy : IHuman
|
||||
{
|
||||
public ProxyInterfaceSourceGeneratorTests.Source.Human _Instance { get; }
|
||||
|
||||
|
||||
public bool IsAlive { get => _Instance.IsAlive; set => _Instance.IsAlive = value; }
|
||||
|
||||
public string GetterOnly { get => _Instance.GetterOnly; }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +31,7 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
public HumanProxy(ProxyInterfaceSourceGeneratorTests.Source.Human instance)
|
||||
{
|
||||
_Instance = instance;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+2
@@ -16,6 +16,8 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
bool IsAlive { get; set; }
|
||||
|
||||
string GetterOnly { get; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
@@ -24,6 +24,8 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
|
||||
|
||||
|
||||
System.Collections.Generic.IList<ProxyInterfaceSourceGeneratorTests.Source.IHuman> AddHuman(ProxyInterfaceSourceGeneratorTests.Source.IHuman h);
|
||||
|
||||
void Void();
|
||||
|
||||
string HelloWorld(string name);
|
||||
|
||||
+2
@@ -26,6 +26,8 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
|
||||
bool IsAlive { get; set; }
|
||||
|
||||
string GetterOnly { get; }
|
||||
|
||||
|
||||
|
||||
string StaticMethod(int x, string y);
|
||||
|
||||
+21
-17
@@ -9,13 +9,14 @@
|
||||
|
||||
#nullable enable
|
||||
using System;
|
||||
using AutoMapper;
|
||||
|
||||
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
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; }
|
||||
|
||||
@@ -29,14 +30,16 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
|
||||
public bool IsAlive { get => _Instance.IsAlive; set => _Instance.IsAlive = value; }
|
||||
|
||||
public string GetterOnly { get => _Instance.GetterOnly; }
|
||||
|
||||
|
||||
|
||||
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;
|
||||
var result__1647028461 = ProxyInterfaceSourceGeneratorTests.Source.PersonExtends.StaticMethod(x_, y_);
|
||||
return result__1647028461;
|
||||
}
|
||||
|
||||
public void Void()
|
||||
@@ -47,8 +50,8 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
public string HelloWorld(string name)
|
||||
{
|
||||
string name_ = name;
|
||||
var result_6851397 = _Instance.HelloWorld(name_);
|
||||
return result_6851397;
|
||||
var result_282270798 = _Instance.HelloWorld(name_);
|
||||
return result_282270798;
|
||||
}
|
||||
|
||||
public void WithParams(params string[] values)
|
||||
@@ -61,15 +64,15 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
string s_ = s;
|
||||
string @string_ = @string;
|
||||
var result_6851397 = _Instance.Add(s_, @string_);
|
||||
return result_6851397;
|
||||
var result__1127157211 = _Instance.Add(s_, @string_);
|
||||
return result__1127157211;
|
||||
}
|
||||
|
||||
public int DefaultValue(int x = 100)
|
||||
{
|
||||
int x_ = x;
|
||||
var result_3873514 = _Instance.DefaultValue(x_);
|
||||
return result_3873514;
|
||||
var result__378509684 = _Instance.DefaultValue(x_);
|
||||
return result__378509684;
|
||||
}
|
||||
|
||||
public void In_Out_Ref1(in int a, out int b, ref int c)
|
||||
@@ -86,26 +89,26 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
int x_ = x;
|
||||
T1 t1_ = t1;
|
||||
T2 t2_ = t2;
|
||||
var result_14331071 = _Instance.Generic2<T1, T2>(x_, t1_, t2_);
|
||||
return result_14331071;
|
||||
var result_542538942 = _Instance.Generic2<T1, T2>(x_, t1_, t2_);
|
||||
return result_542538942;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task Method1Async()
|
||||
{
|
||||
var result_39535275 = _Instance.Method1Async();
|
||||
return result_39535275;
|
||||
var result__57678382 = _Instance.Method1Async();
|
||||
return result__57678382;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task<int> Method2Async()
|
||||
{
|
||||
var result_772784336 = _Instance.Method2Async();
|
||||
return result_772784336;
|
||||
var result__57677169 = _Instance.Method2Async();
|
||||
return result__57677169;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task<string?> Method3Async()
|
||||
{
|
||||
var result_769806453 = _Instance.Method3Async();
|
||||
return result_769806453;
|
||||
var result__57684656 = _Instance.Method3Async();
|
||||
return result__57684656;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +118,7 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
public PersonExtendsProxy(ProxyInterfaceSourceGeneratorTests.Source.PersonExtends instance)
|
||||
{
|
||||
_Instance = instance;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+33
-19
@@ -13,9 +13,11 @@ using AutoMapper;
|
||||
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public class PersonProxy : IPerson
|
||||
public partial class PersonProxy : ProxyInterfaceSourceGeneratorTests.Source.HumanProxy, IPerson
|
||||
{
|
||||
public ProxyInterfaceSourceGeneratorTests.Source.Person _Instance { get; }
|
||||
public new ProxyInterfaceSourceGeneratorTests.Source.Person _Instance { get; }
|
||||
public ProxyInterfaceSourceGeneratorTests.Source.Human _InstanceBase { get; }
|
||||
|
||||
|
||||
public string Name { get => _Instance.Name; set => _Instance.Name = value; }
|
||||
|
||||
@@ -27,6 +29,13 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
|
||||
|
||||
|
||||
public System.Collections.Generic.IList<ProxyInterfaceSourceGeneratorTests.Source.IHuman> AddHuman(ProxyInterfaceSourceGeneratorTests.Source.IHuman h)
|
||||
{
|
||||
ProxyInterfaceSourceGeneratorTests.Source.Human h_ = _mapper.Map<ProxyInterfaceSourceGeneratorTests.Source.Human>(h);
|
||||
var result_907493286 = _Instance.AddHuman(h_);
|
||||
return _mapper.Map<System.Collections.Generic.IList<ProxyInterfaceSourceGeneratorTests.Source.IHuman>>(result_907493286);
|
||||
}
|
||||
|
||||
public void Void()
|
||||
{
|
||||
_Instance.Void();
|
||||
@@ -35,8 +44,8 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
public string HelloWorld(string name)
|
||||
{
|
||||
string name_ = name;
|
||||
var result_37309470 = _Instance.HelloWorld(name_);
|
||||
return result_37309470;
|
||||
var result_282270798 = _Instance.HelloWorld(name_);
|
||||
return result_282270798;
|
||||
}
|
||||
|
||||
public void WithParams(params string[] values)
|
||||
@@ -49,15 +58,15 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
string s_ = s;
|
||||
string @string_ = @string;
|
||||
var result_37309470 = _Instance.Add(s_, @string_);
|
||||
return result_37309470;
|
||||
var result__1127157211 = _Instance.Add(s_, @string_);
|
||||
return result__1127157211;
|
||||
}
|
||||
|
||||
public int DefaultValue(int x = 100)
|
||||
{
|
||||
int x_ = x;
|
||||
var result_24216618 = _Instance.DefaultValue(x_);
|
||||
return result_24216618;
|
||||
var result__378509684 = _Instance.DefaultValue(x_);
|
||||
return result__378509684;
|
||||
}
|
||||
|
||||
public void In_Out_Ref1(in int a, out int b, ref int c)
|
||||
@@ -74,41 +83,46 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
int x_ = x;
|
||||
T1 t1_ = t1;
|
||||
T2 t2_ = t2;
|
||||
var result_60333940 = _Instance.Generic2<T1, T2>(x_, t1_, t2_);
|
||||
return result_60333940;
|
||||
var result_542538942 = _Instance.Generic2<T1, T2>(x_, t1_, t2_);
|
||||
return result_542538942;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task Method1Async()
|
||||
{
|
||||
var result_2292327 = _Instance.Method1Async();
|
||||
return result_2292327;
|
||||
var result__57678382 = _Instance.Method1Async();
|
||||
return result__57678382;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task<int> Method2Async()
|
||||
{
|
||||
var result_1229624901 = _Instance.Method2Async();
|
||||
return result_1229624901;
|
||||
var result__57677169 = _Instance.Method2Async();
|
||||
return result__57677169;
|
||||
}
|
||||
|
||||
public System.Threading.Tasks.Task<string?> Method3Async()
|
||||
{
|
||||
var result_1242717753 = _Instance.Method3Async();
|
||||
return result_1242717753;
|
||||
var result__57684656 = _Instance.Method3Async();
|
||||
return result__57684656;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public PersonProxy(ProxyInterfaceSourceGeneratorTests.Source.Person instance)
|
||||
public PersonProxy(ProxyInterfaceSourceGeneratorTests.Source.Person instance) : base(instance)
|
||||
{
|
||||
_Instance = instance;
|
||||
_InstanceBase = instance;
|
||||
|
||||
_mapper = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<ProxyInterfaceSourceGeneratorTests.Source.Human, ProxyInterfaceSourceGeneratorTests.Source.IHuman>().ConstructUsing(instance => new ProxyInterfaceSourceGeneratorTests.Source.HumanProxy(instance));
|
||||
cfg.CreateMap<ProxyInterfaceSourceGeneratorTests.Source.IHuman, ProxyInterfaceSourceGeneratorTests.Source.Human>().ConstructUsing(proxy => ((ProxyInterfaceSourceGeneratorTests.Source.HumanProxy) proxy)._Instance);
|
||||
}).CreateMapper();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public bool IsAlive { get; set; }
|
||||
private readonly IMapper _mapper;
|
||||
}
|
||||
}
|
||||
#nullable disable
|
||||
@@ -1,13 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using AnyOfTypes;
|
||||
using CSharp.SourceGenerators.Extensions;
|
||||
using CSharp.SourceGenerators.Extensions.Models;
|
||||
using FluentAssertions;
|
||||
using ProxyInterfaceSourceGenerator;
|
||||
using ProxyInterfaceSourceGeneratorTests.Source;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace ProxyInterfaceSourceGeneratorTests
|
||||
{
|
||||
@@ -20,6 +17,36 @@ namespace ProxyInterfaceSourceGeneratorTests
|
||||
public ProxyInterfaceSourceGeneratorTest()
|
||||
{
|
||||
_sut = new ProxyInterfaceCodeGenerator();
|
||||
|
||||
var pp = new PersonProxy(new Person());
|
||||
|
||||
var h = pp.AddHuman(new HumanProxy(new Human()));
|
||||
|
||||
int x = 0;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GenerateFiles_ForStruct_Should_Not_GenerateProxyCode()
|
||||
{
|
||||
// Arrange
|
||||
var path = "./Source/IMyStruct.cs";
|
||||
var sourceFile = new SourceFile
|
||||
{
|
||||
Path = path,
|
||||
Text = File.ReadAllText(path),
|
||||
AttributeToAddToInterface = new ExtraAttribute
|
||||
{
|
||||
Name = "ProxyInterfaceGenerator.Proxy",
|
||||
ArgumentList = "typeof(ProxyInterfaceSourceGeneratorTests.Source.MyStruct)"
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = _sut.Execute(new[] { sourceFile });
|
||||
|
||||
// Assert
|
||||
result.Valid.Should().BeTrue();
|
||||
result.Files.Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -111,7 +138,7 @@ namespace ProxyInterfaceSourceGeneratorTests
|
||||
result.Valid.Should().BeTrue();
|
||||
result.Files.Should().HaveCount(5);
|
||||
|
||||
throw new Exception();
|
||||
// throw new Exception();
|
||||
|
||||
// Assert attribute
|
||||
var attribute = result.Files[0].SyntaxTree;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="10.1.1" />
|
||||
<PackageReference Include="FluentAssertions" Version="5.10.3" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
@@ -28,26 +29,10 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CSharp.SourceGenerators.Extensions" Version="0.0.6" />
|
||||
<!--<ProjectReference Include="..\..\..\FluentBuilder\src-extensions\CSharp.SourceGenerators.Extensions\CSharp.SourceGenerators.Extensions.csproj" />-->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Source\Human.cs">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Compile>
|
||||
<Compile Update="Source\IHuman.cs">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Compile>
|
||||
<Compile Update="Source\IPersonExtends.cs">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Compile>
|
||||
<Compile Update="Source\IPerson.cs">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Compile>
|
||||
<Compile Update="Source\PersonExtends.cs">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Compile>
|
||||
<Compile Update="Source\Person.cs">
|
||||
<Compile Update="Source\*.cs">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public class Human
|
||||
{
|
||||
public bool IsAlive { get; set; }
|
||||
|
||||
public string GetterOnly => "x";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public partial interface IMyStruct
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public struct MyStruct
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
{
|
||||
public class Person
|
||||
public class Person : Human
|
||||
{
|
||||
public IList<Human> AddHuman(Human h)
|
||||
{
|
||||
return new List<Human> { h, new Human { IsAlive = true } };
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string? StringNullable { get; set; }
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
|
||||
Reference in New Issue
Block a user