.editor config + fix line endings
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// https://bartwullems.blogspot.com/2021/01/c-9use-record-types-in-net-standard-20.html
|
||||
#if NETSTANDARD2_0
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
public class IsExternalInit { }
|
||||
}
|
||||
// https://bartwullems.blogspot.com/2021/01/c-9use-record-types-in-net-standard-20.html
|
||||
#if NETSTANDARD2_0
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
public class IsExternalInit { }
|
||||
}
|
||||
#endif
|
||||
@@ -1,18 +1,18 @@
|
||||
using System.Collections.Generic;
|
||||
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; }
|
||||
|
||||
public Dictionary<string, string> ReplacedTypes { get; } = new Dictionary<string, string>();
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
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; }
|
||||
|
||||
public Dictionary<string, string> ReplacedTypes { get; } = new Dictionary<string, string>();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
using ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator
|
||||
{
|
||||
internal record ContextData
|
||||
{
|
||||
public string? InterfaceName { get; init; }
|
||||
|
||||
public string? ClassName { get; init; }
|
||||
|
||||
public FileData FileData { get; init; }
|
||||
}
|
||||
using ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator
|
||||
{
|
||||
internal record ContextData
|
||||
{
|
||||
public string? InterfaceName { get; init; }
|
||||
|
||||
public string? ClassName { get; init; }
|
||||
|
||||
public FileData FileData { get; init; }
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class MethodSymbolExtensions
|
||||
{
|
||||
public static string GetMethodNameWithOptionalTypeParameters(this IMethodSymbol method) =>
|
||||
!method.IsGenericMethod ? method.Name : $"{method.Name}<{string.Join(", ", method.TypeParameters.Select(tp => tp.Name))}>";
|
||||
|
||||
public static string GetWhereStatement(this IMethodSymbol method) =>
|
||||
!method.IsGenericMethod ? string.Empty : string.Join("", method.TypeParameters.Select(tp => tp.GetWhereStatement()));
|
||||
}
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class MethodSymbolExtensions
|
||||
{
|
||||
public static string GetMethodNameWithOptionalTypeParameters(this IMethodSymbol method) =>
|
||||
!method.IsGenericMethod ? method.Name : $"{method.Name}<{string.Join(", ", method.TypeParameters.Select(tp => tp.Name))}>";
|
||||
|
||||
public static string GetWhereStatement(this IMethodSymbol method) =>
|
||||
!method.IsGenericMethod ? string.Empty : string.Join("", method.TypeParameters.Select(tp => tp.GetWhereStatement()));
|
||||
}
|
||||
}
|
||||
@@ -1,52 +1,51 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class NamedTypeSymbolExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// See https://www.codeproject.com/Articles/861548/Roslyn-Code-Analysis-in-Easy-Samples-Part
|
||||
/// </summary>
|
||||
public static string GetFullTypeString(this INamedTypeSymbol namedTypeSymbol)
|
||||
{
|
||||
var str = new StringBuilder(namedTypeSymbol.Name);
|
||||
|
||||
if (namedTypeSymbol.TypeArguments.Count() > 0)
|
||||
{
|
||||
str.AppendFormat("<{0}>", string.Join(", ", namedTypeSymbol.TypeArguments.OfType<INamedTypeSymbol>().Select(typeArg => typeArg.GetFullTypeString())));
|
||||
}
|
||||
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
public static string ResolveInterfaceNameWithOptionalTypeConstraints(this INamedTypeSymbol namedTypeSymbol, string interfaceName)
|
||||
{
|
||||
if (!namedTypeSymbol.IsGenericType)
|
||||
{
|
||||
return interfaceName;
|
||||
}
|
||||
|
||||
var str = new StringBuilder($"{interfaceName}<{string.Join(", ", namedTypeSymbol.TypeArguments.Select(ta => ta.Name))}>");
|
||||
|
||||
foreach (var typeParameterSymbol in namedTypeSymbol.TypeArguments.OfType<ITypeParameterSymbol>())
|
||||
{
|
||||
str.Append(typeParameterSymbol.GetWhereStatement());
|
||||
}
|
||||
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See https://stackoverflow.com/questions/24157101/roslyns-gettypebymetadataname-and-generic-types
|
||||
/// </summary>
|
||||
public static string ResolveProxyClassName(this INamedTypeSymbol namedTypeSymbol)
|
||||
{
|
||||
return !namedTypeSymbol.IsGenericType ?
|
||||
$"{namedTypeSymbol.Name}Proxy" :
|
||||
$"{namedTypeSymbol.Name}Proxy<{string.Join(", ", namedTypeSymbol.TypeArguments.Select(ta => ta.Name))}>";
|
||||
}
|
||||
}
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class NamedTypeSymbolExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// See https://www.codeproject.com/Articles/861548/Roslyn-Code-Analysis-in-Easy-Samples-Part
|
||||
/// </summary>
|
||||
public static string GetFullTypeString(this INamedTypeSymbol namedTypeSymbol)
|
||||
{
|
||||
var str = new StringBuilder(namedTypeSymbol.Name);
|
||||
|
||||
if (namedTypeSymbol.TypeArguments.Count() > 0)
|
||||
{
|
||||
str.AppendFormat("<{0}>", string.Join(", ", namedTypeSymbol.TypeArguments.OfType<INamedTypeSymbol>().Select(typeArg => typeArg.GetFullTypeString())));
|
||||
}
|
||||
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
public static string ResolveInterfaceNameWithOptionalTypeConstraints(this INamedTypeSymbol namedTypeSymbol, string interfaceName)
|
||||
{
|
||||
if (!namedTypeSymbol.IsGenericType)
|
||||
{
|
||||
return interfaceName;
|
||||
}
|
||||
|
||||
var str = new StringBuilder($"{interfaceName}<{string.Join(", ", namedTypeSymbol.TypeArguments.Select(ta => ta.Name))}>");
|
||||
|
||||
foreach (var typeParameterSymbol in namedTypeSymbol.TypeArguments.OfType<ITypeParameterSymbol>())
|
||||
{
|
||||
str.Append(typeParameterSymbol.GetWhereStatement());
|
||||
}
|
||||
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See https://stackoverflow.com/questions/24157101/roslyns-gettypebymetadataname-and-generic-types
|
||||
/// </summary>
|
||||
public static string ResolveProxyClassName(this INamedTypeSymbol namedTypeSymbol)
|
||||
{
|
||||
return !namedTypeSymbol.IsGenericType ?
|
||||
$"{namedTypeSymbol.Name}Proxy" :
|
||||
$"{namedTypeSymbol.Name}Proxy<{string.Join(", ", namedTypeSymbol.TypeArguments.Select(ta => ta.Name))}>";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,35 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class ParameterSymbolExtensions
|
||||
{
|
||||
public static string GetRefPrefix(this IParameterSymbol ps)
|
||||
{
|
||||
switch (ps.RefKind)
|
||||
{
|
||||
case RefKind.In:
|
||||
return "in ";
|
||||
|
||||
case RefKind.Out:
|
||||
return "out ";
|
||||
|
||||
case RefKind.Ref:
|
||||
return "ref ";
|
||||
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetParamsPrefix(this IParameterSymbol ps) =>
|
||||
ps.IsParams ? "params " : string.Empty;
|
||||
|
||||
public static string GetDefaultValue(this IParameterSymbol ps) =>
|
||||
ps.HasExplicitDefaultValue ? $" = {ps.ExplicitDefaultValue}" : string.Empty;
|
||||
|
||||
public static TypeEnum GetTypeEnum(this IParameterSymbol p) =>
|
||||
p.Type.GetTypeEnum();
|
||||
}
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class ParameterSymbolExtensions
|
||||
{
|
||||
public static string GetRefPrefix(this IParameterSymbol ps)
|
||||
{
|
||||
switch (ps.RefKind)
|
||||
{
|
||||
case RefKind.In:
|
||||
return "in ";
|
||||
|
||||
case RefKind.Out:
|
||||
return "out ";
|
||||
|
||||
case RefKind.Ref:
|
||||
return "ref ";
|
||||
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetParamsPrefix(this IParameterSymbol ps) =>
|
||||
ps.IsParams ? "params " : string.Empty;
|
||||
|
||||
public static string GetDefaultValue(this IParameterSymbol ps) =>
|
||||
ps.HasExplicitDefaultValue ? $" = {ps.ExplicitDefaultValue}" : string.Empty;
|
||||
|
||||
public static TypeEnum GetTypeEnum(this IParameterSymbol p) =>
|
||||
p.Type.GetTypeEnum();
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,37 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class PropertySymbolExtensions
|
||||
{
|
||||
public static TypeEnum GetTypeEnum(this IPropertySymbol p) =>
|
||||
p.Type.GetTypeEnum();
|
||||
|
||||
public static string ToPropertyText(this IPropertySymbol property, string? overrideType = null)
|
||||
{
|
||||
var get = property.GetMethod != null ? "get; " : string.Empty;
|
||||
var set = property.SetMethod != null ? "set; " : string.Empty;
|
||||
|
||||
var type = !string.IsNullOrEmpty(overrideType) ? overrideType : $"{property.Type}";
|
||||
|
||||
return $"{type} {property.GetSanitizedName()} {{ {get}{set}}}";
|
||||
}
|
||||
|
||||
public static string ToPropertyTextForClass(this IPropertySymbol property)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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}}}";
|
||||
}
|
||||
}
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class PropertySymbolExtensions
|
||||
{
|
||||
public static TypeEnum GetTypeEnum(this IPropertySymbol p) =>
|
||||
p.Type.GetTypeEnum();
|
||||
|
||||
public static string ToPropertyText(this IPropertySymbol property, string? overrideType = null)
|
||||
{
|
||||
var get = property.GetMethod != null ? "get; " : string.Empty;
|
||||
var set = property.SetMethod != null ? "set; " : string.Empty;
|
||||
|
||||
var type = !string.IsNullOrEmpty(overrideType) ? overrideType : $"{property.Type}";
|
||||
|
||||
return $"{type} {property.GetSanitizedName()} {{ {get}{set}}}";
|
||||
}
|
||||
|
||||
public static string ToPropertyTextForClass(this IPropertySymbol property)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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}}}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class SymbolExtensions
|
||||
{
|
||||
public static bool IsKeywordOrReserved(this ISymbol symbol) =>
|
||||
SyntaxFacts.GetKeywordKind(symbol.Name) != SyntaxKind.None || SyntaxFacts.GetContextualKeywordKind(symbol.Name) != SyntaxKind.None;
|
||||
|
||||
public static string GetSanitizedName(this ISymbol symbol) =>
|
||||
symbol.IsKeywordOrReserved() ? $"@{symbol.Name}" : symbol.Name;
|
||||
}
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class SymbolExtensions
|
||||
{
|
||||
public static bool IsKeywordOrReserved(this ISymbol symbol) =>
|
||||
SyntaxFacts.GetKeywordKind(symbol.Name) != SyntaxKind.None || SyntaxFacts.GetContextualKeywordKind(symbol.Name) != SyntaxKind.None;
|
||||
|
||||
public static string GetSanitizedName(this ISymbol symbol) =>
|
||||
symbol.IsKeywordOrReserved() ? $"@{symbol.Name}" : symbol.Name;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +1,41 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class SyntaxNodeUtils
|
||||
{
|
||||
// https://stackoverflow.com/questions/20458457/getting-class-fullname-including-namespace-from-roslyn-classdeclarationsyntax
|
||||
public static bool TryGetParentSyntax<T>(this SyntaxNode? syntaxNode, [NotNullWhen(true)] out T? result) where T : SyntaxNode
|
||||
{
|
||||
result = null;
|
||||
|
||||
if (syntaxNode is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
syntaxNode = syntaxNode.Parent;
|
||||
|
||||
if (syntaxNode is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (syntaxNode.GetType() == typeof(T))
|
||||
{
|
||||
result = (T)syntaxNode;
|
||||
return true;
|
||||
}
|
||||
|
||||
return TryGetParentSyntax(syntaxNode, out result);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class SyntaxNodeUtils
|
||||
{
|
||||
// https://stackoverflow.com/questions/20458457/getting-class-fullname-including-namespace-from-roslyn-classdeclarationsyntax
|
||||
public static bool TryGetParentSyntax<T>(this SyntaxNode? syntaxNode, [NotNullWhen(true)] out T? result) where T : SyntaxNode
|
||||
{
|
||||
result = null;
|
||||
|
||||
if (syntaxNode is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
syntaxNode = syntaxNode.Parent;
|
||||
|
||||
if (syntaxNode is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (syntaxNode.GetType() == typeof(T))
|
||||
{
|
||||
result = (T)syntaxNode;
|
||||
return true;
|
||||
}
|
||||
|
||||
return TryGetParentSyntax(syntaxNode, out result);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,40 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class TypeParameterSymbolExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// https://www.codeproject.com/Articles/871704/Roslyn-Code-Analysis-in-Easy-Samples-Part-2
|
||||
/// </summary>
|
||||
public static string GetWhereStatement(this ITypeParameterSymbol typeParameterSymbol)
|
||||
{
|
||||
var constraints = new List<string>();
|
||||
if (typeParameterSymbol.HasReferenceTypeConstraint)
|
||||
{
|
||||
constraints.Add("class");
|
||||
}
|
||||
|
||||
if (typeParameterSymbol.HasValueTypeConstraint)
|
||||
{
|
||||
constraints.Add("struct");
|
||||
}
|
||||
|
||||
if (typeParameterSymbol.HasConstructorConstraint)
|
||||
{
|
||||
constraints.Add("new()");
|
||||
}
|
||||
|
||||
constraints.AddRange(typeParameterSymbol.ConstraintTypes.OfType<INamedTypeSymbol>().Select(contstraintType => contstraintType.GetFullTypeString()));
|
||||
|
||||
if (!constraints.Any())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return $" where {typeParameterSymbol.Name} : {string.Join(", ", constraints)}";
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class TypeParameterSymbolExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// https://www.codeproject.com/Articles/871704/Roslyn-Code-Analysis-in-Easy-Samples-Part-2
|
||||
/// </summary>
|
||||
public static string GetWhereStatement(this ITypeParameterSymbol typeParameterSymbol)
|
||||
{
|
||||
var constraints = new List<string>();
|
||||
if (typeParameterSymbol.HasReferenceTypeConstraint)
|
||||
{
|
||||
constraints.Add("class");
|
||||
}
|
||||
|
||||
if (typeParameterSymbol.HasValueTypeConstraint)
|
||||
{
|
||||
constraints.Add("struct");
|
||||
}
|
||||
|
||||
if (typeParameterSymbol.HasConstructorConstraint)
|
||||
{
|
||||
constraints.Add("new()");
|
||||
}
|
||||
|
||||
constraints.AddRange(typeParameterSymbol.ConstraintTypes.OfType<INamedTypeSymbol>().Select(contstraintType => contstraintType.GetFullTypeString()));
|
||||
|
||||
if (!constraints.Any())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return $" where {typeParameterSymbol.Name} : {string.Join(", ", constraints)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,28 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class TypeSymbolExtensions
|
||||
{
|
||||
public static TypeEnum GetTypeEnum(this ITypeSymbol ts)
|
||||
{
|
||||
if (ts.IsValueType || ts.IsString())
|
||||
{
|
||||
return TypeEnum.ValueTypeOrString;
|
||||
}
|
||||
|
||||
if (ts.TypeKind == TypeKind.Interface)
|
||||
{
|
||||
return TypeEnum.Interface;
|
||||
}
|
||||
|
||||
return TypeEnum.Complex;
|
||||
}
|
||||
|
||||
public static bool IsString(this ITypeSymbol ts)
|
||||
{
|
||||
return ts.ToString() == "string" || ts.ToString() == "string?";
|
||||
}
|
||||
}
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions
|
||||
{
|
||||
internal static class TypeSymbolExtensions
|
||||
{
|
||||
public static TypeEnum GetTypeEnum(this ITypeSymbol ts)
|
||||
{
|
||||
if (ts.IsValueType || ts.IsString())
|
||||
{
|
||||
return TypeEnum.ValueTypeOrString;
|
||||
}
|
||||
|
||||
if (ts.TypeKind == TypeKind.Interface)
|
||||
{
|
||||
return TypeEnum.Interface;
|
||||
}
|
||||
|
||||
return TypeEnum.Complex;
|
||||
}
|
||||
|
||||
public static bool IsString(this ITypeSymbol ts)
|
||||
{
|
||||
return ts.ToString() == "string" || ts.ToString() == "string?";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +1,77 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators
|
||||
{
|
||||
internal abstract class BaseGenerator
|
||||
{
|
||||
protected readonly Context _context;
|
||||
|
||||
public BaseGenerator(Context context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
protected string GetPropertyType(IPropertySymbol property, out bool isReplaced)
|
||||
{
|
||||
return GetReplacedType(property.Type, out isReplaced);
|
||||
}
|
||||
|
||||
protected string GetParameterType(IParameterSymbol property, out bool isReplaced)
|
||||
{
|
||||
return GetReplacedType(property.Type, out isReplaced);
|
||||
}
|
||||
|
||||
protected string GetReplacedType(ITypeSymbol typeSymbol, out bool isReplaced)
|
||||
{
|
||||
isReplaced = false;
|
||||
|
||||
var typeSymbolAsString = typeSymbol.ToString();
|
||||
|
||||
var existing = _context.CandidateInterfaces.Values.FirstOrDefault(x => x.RawTypeName == typeSymbolAsString);
|
||||
if (existing is not null)
|
||||
{
|
||||
if (!_context.ReplacedTypes.ContainsKey(typeSymbolAsString))
|
||||
{
|
||||
_context.ReplacedTypes.Add(typeSymbolAsString, existing.InterfaceName);
|
||||
}
|
||||
|
||||
isReplaced = true;
|
||||
return existing.InterfaceName;
|
||||
}
|
||||
|
||||
if (typeSymbol is INamedTypeSymbol namedTypedSymbol)
|
||||
{
|
||||
var propertyTypeAsStringToBeModified = typeSymbolAsString;
|
||||
foreach (var typeArgument in namedTypedSymbol.TypeArguments)
|
||||
{
|
||||
var typeArgumentAsString = typeArgument.ToString();
|
||||
var exist = _context.CandidateInterfaces.Values.FirstOrDefault(x => x.RawTypeName == typeArgumentAsString);
|
||||
if (exist is not null)
|
||||
{
|
||||
isReplaced = true;
|
||||
|
||||
if (!_context.ReplacedTypes.ContainsKey(typeArgumentAsString))
|
||||
{
|
||||
_context.ReplacedTypes.Add(typeArgumentAsString, exist.InterfaceName);
|
||||
}
|
||||
|
||||
propertyTypeAsStringToBeModified = propertyTypeAsStringToBeModified.Replace(typeArgumentAsString, exist.InterfaceName);
|
||||
}
|
||||
}
|
||||
|
||||
return propertyTypeAsStringToBeModified;
|
||||
}
|
||||
|
||||
return typeSymbolAsString;
|
||||
}
|
||||
|
||||
protected INamedTypeSymbol GetNamedTypeSymbolByFullName(string name, IEnumerable<string>? usings = null)
|
||||
{
|
||||
// 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);
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators
|
||||
{
|
||||
internal abstract class BaseGenerator
|
||||
{
|
||||
protected readonly Context _context;
|
||||
|
||||
public BaseGenerator(Context context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
protected string GetPropertyType(IPropertySymbol property, out bool isReplaced)
|
||||
{
|
||||
return GetReplacedType(property.Type, out isReplaced);
|
||||
}
|
||||
|
||||
protected string GetParameterType(IParameterSymbol property, out bool isReplaced)
|
||||
{
|
||||
return GetReplacedType(property.Type, out isReplaced);
|
||||
}
|
||||
|
||||
protected string GetReplacedType(ITypeSymbol typeSymbol, out bool isReplaced)
|
||||
{
|
||||
isReplaced = false;
|
||||
|
||||
var typeSymbolAsString = typeSymbol.ToString();
|
||||
|
||||
var existing = _context.CandidateInterfaces.Values.FirstOrDefault(x => x.RawTypeName == typeSymbolAsString);
|
||||
if (existing is not null)
|
||||
{
|
||||
if (!_context.ReplacedTypes.ContainsKey(typeSymbolAsString))
|
||||
{
|
||||
_context.ReplacedTypes.Add(typeSymbolAsString, existing.InterfaceName);
|
||||
}
|
||||
|
||||
isReplaced = true;
|
||||
return existing.InterfaceName;
|
||||
}
|
||||
|
||||
if (typeSymbol is INamedTypeSymbol namedTypedSymbol)
|
||||
{
|
||||
var propertyTypeAsStringToBeModified = typeSymbolAsString;
|
||||
foreach (var typeArgument in namedTypedSymbol.TypeArguments)
|
||||
{
|
||||
var typeArgumentAsString = typeArgument.ToString();
|
||||
var exist = _context.CandidateInterfaces.Values.FirstOrDefault(x => x.RawTypeName == typeArgumentAsString);
|
||||
if (exist is not null)
|
||||
{
|
||||
isReplaced = true;
|
||||
|
||||
if (!_context.ReplacedTypes.ContainsKey(typeArgumentAsString))
|
||||
{
|
||||
_context.ReplacedTypes.Add(typeArgumentAsString, exist.InterfaceName);
|
||||
}
|
||||
|
||||
propertyTypeAsStringToBeModified = propertyTypeAsStringToBeModified.Replace(typeArgumentAsString, exist.InterfaceName);
|
||||
}
|
||||
}
|
||||
|
||||
return propertyTypeAsStringToBeModified;
|
||||
}
|
||||
|
||||
return typeSymbolAsString;
|
||||
}
|
||||
|
||||
protected INamedTypeSymbol GetNamedTypeSymbolByFullName(string name, IEnumerable<string>? usings = null)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
return symbol;
|
||||
@@ -86,10 +86,10 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators
|
||||
{
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception($"The type '{name}' is not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception($"The type '{name}' is not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators
|
||||
{
|
||||
internal record FileData(string FileName, string Text)
|
||||
{
|
||||
}
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators
|
||||
{
|
||||
internal record FileData(string FileName, string Text)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators
|
||||
{
|
||||
internal interface IFileGenerator
|
||||
{
|
||||
FileData GenerateFile();
|
||||
}
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators
|
||||
{
|
||||
internal interface IFileGenerator
|
||||
{
|
||||
FileData GenerateFile();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators
|
||||
{
|
||||
internal interface IFilesGenerator
|
||||
{
|
||||
IEnumerable<FileData> GenerateFiles();
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators
|
||||
{
|
||||
internal interface IFilesGenerator
|
||||
{
|
||||
IEnumerable<FileData> GenerateFiles();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
using ProxyInterfaceSourceGenerator.Extensions;
|
||||
using ProxyInterfaceSourceGenerator.SyntaxReceiver;
|
||||
using ProxyInterfaceSourceGenerator.Utils;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators
|
||||
{
|
||||
@@ -83,7 +82,7 @@ namespace {ns}
|
||||
var type = ps.GetTypeEnum() == TypeEnum.Complex ? GetParameterType(ps, out _) : ps.Type.ToString();
|
||||
methodParameters.Add($"{ps.GetParamsPrefix()}{ps.GetRefPrefix()}{type} {ps.GetSanitizedName()}{ps.GetDefaultValue()}");
|
||||
}
|
||||
|
||||
|
||||
str.AppendLine($" {GetReplacedType(method.ReturnType, out _)} {method.GetMethodNameWithOptionalTypeParameters()}({string.Join(", ", methodParameters)}){method.GetWhereStatement()};");
|
||||
str.AppendLine();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.SyntaxReceiver
|
||||
{
|
||||
internal record ProxyData(string Namespace, string InterfaceName, string RawTypeName, string TypeName, List<string> Usings, bool ProxyAll)
|
||||
{
|
||||
public string FileName => TypeName.Replace('.', '_').Replace('`', '_');
|
||||
}
|
||||
namespace ProxyInterfaceSourceGenerator.SyntaxReceiver
|
||||
{
|
||||
internal record ProxyData(string Namespace, string InterfaceName, string RawTypeName, string TypeName, List<string> Usings, bool ProxyAll)
|
||||
{
|
||||
public string FileName => TypeName.Replace('.', '_').Replace('`', '_');
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
@@ -51,7 +51,7 @@ namespace ProxyInterfaceSourceGenerator.SyntaxReceiver
|
||||
ns = namespaceDeclarationSyntax.Name.ToString();
|
||||
usings.Add(ns);
|
||||
}
|
||||
|
||||
|
||||
if (SyntaxNodeUtils.TryGetParentSyntax(interfaceDeclarationSyntax, out CompilationUnitSyntax? cc))
|
||||
{
|
||||
foreach (var @using in cc.Usings)
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Utils
|
||||
{
|
||||
internal static class MemberHelper
|
||||
{
|
||||
private static string[] _excludedMethods = new string[] { "ToString", "GetHashCode" };
|
||||
|
||||
public static IEnumerable<IPropertySymbol> GetPublicProperties(INamedTypeSymbol classSymbol, params Func<IPropertySymbol, bool>[] filters)
|
||||
{
|
||||
var allFilters = new List<Func<IPropertySymbol, bool>>(filters);
|
||||
allFilters.Add(p => p.Kind == SymbolKind.Property);
|
||||
|
||||
return GetPublicMembers(classSymbol, allFilters.ToArray());
|
||||
}
|
||||
|
||||
public static IEnumerable<IMethodSymbol> GetPublicMethods(INamedTypeSymbol classSymbol, Func<IMethodSymbol, bool>? filter = null)
|
||||
{
|
||||
if (filter is null)
|
||||
{
|
||||
filter = _ => true;
|
||||
}
|
||||
|
||||
return GetPublicMembers(classSymbol,
|
||||
m => m.Kind == SymbolKind.Method,
|
||||
m => m.MethodKind == MethodKind.Ordinary,
|
||||
m => !_excludedMethods.Contains(m.Name),
|
||||
filter);
|
||||
}
|
||||
|
||||
// TODO : do we need also to check for "SanitizedName()" here?
|
||||
private static IEnumerable<T> GetPublicMembers<T>(INamedTypeSymbol classSymbol, params Func<T, bool>[] filters) where T : ISymbol
|
||||
{
|
||||
var membersQuery = classSymbol.GetMembers().OfType<T>()
|
||||
.Where(m => m.DeclaredAccessibility == Accessibility.Public);
|
||||
|
||||
foreach (var filter in filters)
|
||||
{
|
||||
membersQuery = membersQuery.Where(filter);
|
||||
}
|
||||
|
||||
var members = membersQuery.ToList();
|
||||
|
||||
var propertyNames = membersQuery.Select(x => x.Name);
|
||||
|
||||
var baseType = classSymbol.BaseType;
|
||||
|
||||
while (baseType != null)
|
||||
{
|
||||
var baseMembers = baseType.GetMembers().OfType<T>()
|
||||
.Where(m => m.DeclaredAccessibility == Accessibility.Public)
|
||||
.Where(x => !propertyNames.Contains(x.Name));
|
||||
|
||||
foreach (var filter in filters)
|
||||
{
|
||||
baseMembers = baseMembers.Where(filter);
|
||||
}
|
||||
|
||||
members.AddRange(baseMembers);
|
||||
|
||||
baseType = baseType.BaseType;
|
||||
}
|
||||
|
||||
return membersQuery;
|
||||
}
|
||||
}
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Utils
|
||||
{
|
||||
internal static class MemberHelper
|
||||
{
|
||||
private static string[] _excludedMethods = new string[] { "ToString", "GetHashCode" };
|
||||
|
||||
public static IEnumerable<IPropertySymbol> GetPublicProperties(INamedTypeSymbol classSymbol, params Func<IPropertySymbol, bool>[] filters)
|
||||
{
|
||||
var allFilters = new List<Func<IPropertySymbol, bool>>(filters);
|
||||
allFilters.Add(p => p.Kind == SymbolKind.Property);
|
||||
|
||||
return GetPublicMembers(classSymbol, allFilters.ToArray());
|
||||
}
|
||||
|
||||
public static IEnumerable<IMethodSymbol> GetPublicMethods(INamedTypeSymbol classSymbol, Func<IMethodSymbol, bool>? filter = null)
|
||||
{
|
||||
if (filter is null)
|
||||
{
|
||||
filter = _ => true;
|
||||
}
|
||||
|
||||
return GetPublicMembers(classSymbol,
|
||||
m => m.Kind == SymbolKind.Method,
|
||||
m => m.MethodKind == MethodKind.Ordinary,
|
||||
m => !_excludedMethods.Contains(m.Name),
|
||||
filter);
|
||||
}
|
||||
|
||||
// TODO : do we need also to check for "SanitizedName()" here?
|
||||
private static IEnumerable<T> GetPublicMembers<T>(INamedTypeSymbol classSymbol, params Func<T, bool>[] filters) where T : ISymbol
|
||||
{
|
||||
var membersQuery = classSymbol.GetMembers().OfType<T>()
|
||||
.Where(m => m.DeclaredAccessibility == Accessibility.Public);
|
||||
|
||||
foreach (var filter in filters)
|
||||
{
|
||||
membersQuery = membersQuery.Where(filter);
|
||||
}
|
||||
|
||||
var members = membersQuery.ToList();
|
||||
|
||||
var propertyNames = membersQuery.Select(x => x.Name);
|
||||
|
||||
var baseType = classSymbol.BaseType;
|
||||
|
||||
while (baseType != null)
|
||||
{
|
||||
var baseMembers = baseType.GetMembers().OfType<T>()
|
||||
.Where(m => m.DeclaredAccessibility == Accessibility.Public)
|
||||
.Where(x => !propertyNames.Contains(x.Name));
|
||||
|
||||
foreach (var filter in filters)
|
||||
{
|
||||
baseMembers = baseMembers.Where(filter);
|
||||
}
|
||||
|
||||
members.AddRange(baseMembers);
|
||||
|
||||
baseType = baseType.BaseType;
|
||||
}
|
||||
|
||||
return membersQuery;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user