@@ -26,13 +26,35 @@ namespace ProxyInterfaceGenerator
|
||||
{{
|
||||
public Type Type {{ get; }}
|
||||
public bool ProxyBaseClasses {{ get; }}
|
||||
public ProxyClassAccessibility Accessibility {{ get; }}
|
||||
|
||||
public {ClassName}(Type type, bool proxyBaseClasses = false)
|
||||
public {ClassName}(Type type) : this(type, false, ProxyClassAccessibility.Public)
|
||||
{{
|
||||
}}
|
||||
|
||||
public {ClassName}(Type type, bool proxyBaseClasses) : this(type, proxyBaseClasses, ProxyClassAccessibility.Public)
|
||||
{{
|
||||
}}
|
||||
|
||||
public {ClassName}(Type type, ProxyClassAccessibility accessibility) : this(type, false, accessibility)
|
||||
{{
|
||||
}}
|
||||
|
||||
public {ClassName}(Type type, bool proxyBaseClasses, ProxyClassAccessibility accessibility)
|
||||
{{
|
||||
Type = type;
|
||||
ProxyBaseClasses = proxyBaseClasses;
|
||||
Accessibility = accessibility;
|
||||
}}
|
||||
}}
|
||||
|
||||
[Flags]
|
||||
internal enum ProxyClassAccessibility
|
||||
{{
|
||||
Public = 0,
|
||||
|
||||
Internal = 1
|
||||
}}
|
||||
}}");
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using ProxyInterfaceSourceGenerator.Builders;
|
||||
using ProxyInterfaceSourceGenerator.Enums;
|
||||
using ProxyInterfaceSourceGenerator.Extensions;
|
||||
using ProxyInterfaceSourceGenerator.Models;
|
||||
using ProxyInterfaceSourceGenerator.Types;
|
||||
using ProxyInterfaceSourceGenerator.Utils;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.FileGenerators;
|
||||
@@ -88,6 +89,8 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
|
||||
var (namespaceStart, namespaceEnd) = NamespaceBuilder.Build(pd.Namespace);
|
||||
|
||||
var accessibility = pd.Accessibility == ProxyClassAccessibility.Internal ? "internal" : "public";
|
||||
|
||||
return $@"//----------------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator.
|
||||
@@ -101,7 +104,7 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
using System;
|
||||
|
||||
{namespaceStart}
|
||||
public {@abstract}partial class {className} : {extends}{interfaceName}
|
||||
{accessibility} {@abstract}partial class {className} : {extends}{interfaceName}
|
||||
{{
|
||||
public {@new}{targetClassSymbol.Symbol} _Instance {{ get; }}
|
||||
{instanceBaseDefinition}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using ProxyInterfaceSourceGenerator.Types;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
internal class ProxyData
|
||||
@@ -17,4 +19,6 @@ internal class ProxyData
|
||||
public List<string> Usings { get; init; }
|
||||
|
||||
public bool ProxyBaseClasses { get; init; }
|
||||
|
||||
public ProxyClassAccessibility Accessibility { get; init; }
|
||||
}
|
||||
@@ -37,14 +37,18 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="IsExternalInit" Version="1.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" PrivateAssets="all" />
|
||||
<PackageReference Include="Polyfill.NET" Version="1.0.12">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PackageReference Include="Nullable" Version="1.3.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -59,10 +63,6 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<!--<ItemGroup>
|
||||
<None Remove="bin\Debug\netstandard2.0\ProxyInterfaceSourceGenerator.dll" />
|
||||
</ItemGroup>-->
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using ProxyInterfaceSourceGenerator.Types;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.SyntaxReceiver;
|
||||
|
||||
internal static class AttributeArgumentListParser
|
||||
{
|
||||
public static ProxyInterfaceGeneratorAttributeArguments ParseAttributeArguments(AttributeArgumentListSyntax? argumentList)
|
||||
{
|
||||
if (argumentList is null || argumentList.Arguments.Count is < 1 or > 3)
|
||||
{
|
||||
throw new ArgumentException("The ProxyAttribute requires 1, 2 or 3 arguments.");
|
||||
}
|
||||
|
||||
ProxyInterfaceGeneratorAttributeArguments result;
|
||||
if (TryParseAsType(argumentList.Arguments[0].Expression, out var rawTypeValue))
|
||||
{
|
||||
result = new ProxyInterfaceGeneratorAttributeArguments(rawTypeValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("The first argument from the ProxyAttribute should be a Type.");
|
||||
}
|
||||
|
||||
foreach (var argument in argumentList.Arguments.Skip(1))
|
||||
{
|
||||
if (TryParseAsBoolean(argument.Expression, out var proxyBaseClasses))
|
||||
{
|
||||
result = result with { ProxyBaseClasses = proxyBaseClasses };
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TryParseAsEnum<ProxyClassAccessibility>(argument.Expression, out var accessibility))
|
||||
{
|
||||
result = result with { Accessibility = accessibility };
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool TryParseAsBoolean(ExpressionSyntax expressionSyntax, out bool value)
|
||||
{
|
||||
value = default;
|
||||
|
||||
if (expressionSyntax is LiteralExpressionSyntax literalExpressionSyntax)
|
||||
{
|
||||
value = literalExpressionSyntax.Kind() == SyntaxKind.TrueLiteralExpression;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryParseAsType(ExpressionSyntax expressionSyntax, [NotNullWhen(true)] out string? rawTypeName)
|
||||
{
|
||||
rawTypeName = null;
|
||||
|
||||
if (expressionSyntax is TypeOfExpressionSyntax typeOfExpressionSyntax)
|
||||
{
|
||||
rawTypeName = typeOfExpressionSyntax.Type.ToString();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryParseAsEnum<TEnum>(ExpressionSyntax expressionSyntax, out TEnum value)
|
||||
where TEnum : struct
|
||||
{
|
||||
var enumAsString = expressionSyntax.ToString();
|
||||
if (enumAsString.Length > typeof(TEnum).Name.Length && Enum.TryParse(expressionSyntax.ToString().Substring(typeof(TEnum).Name.Length + 1), out value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -31,19 +31,14 @@ internal class ProxySyntaxReceiver : ISyntaxReceiver
|
||||
return false;
|
||||
}
|
||||
|
||||
var attributeLists = interfaceDeclarationSyntax.AttributeLists.FirstOrDefault(x => x.Attributes.Any(a => GenerateProxyAttributes.Contains(a.Name.ToString())));
|
||||
if (attributeLists is null)
|
||||
var attributeList = interfaceDeclarationSyntax.AttributeLists.FirstOrDefault(x => x.Attributes.Any(a => GenerateProxyAttributes.Contains(a.Name.ToString())));
|
||||
if (attributeList is null)
|
||||
{
|
||||
// InterfaceDeclarationSyntax should have the correct attribute
|
||||
return false;
|
||||
}
|
||||
|
||||
var argumentList = attributeLists.Attributes.FirstOrDefault()?.ArgumentList;
|
||||
if (argumentList is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var usings = new List<string>();
|
||||
|
||||
string ns = interfaceDeclarationSyntax.GetNamespace();
|
||||
@@ -60,29 +55,21 @@ internal class ProxySyntaxReceiver : ISyntaxReceiver
|
||||
}
|
||||
}
|
||||
|
||||
var typeSyntax = ((TypeOfExpressionSyntax)argumentList.Arguments[0].Expression).Type;
|
||||
string rawTypeName = typeSyntax.ToString();
|
||||
|
||||
bool proxyBaseClasses;
|
||||
try
|
||||
{
|
||||
proxyBaseClasses = bool.Parse(((LiteralExpressionSyntax)argumentList.Arguments[1].Expression).ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
proxyBaseClasses = false;
|
||||
}
|
||||
var fluentBuilderAttributeArguments = AttributeArgumentListParser.ParseAttributeArguments(attributeList.Attributes.FirstOrDefault()?.ArgumentList);
|
||||
|
||||
var rawTypeNameAsString = fluentBuilderAttributeArguments.RawTypeName;
|
||||
|
||||
data = new ProxyData
|
||||
{
|
||||
Namespace = ns,
|
||||
ShortInterfaceName = interfaceDeclarationSyntax.Identifier.ToString(),
|
||||
FullInterfaceName = CreateFullInterfaceName(ns, interfaceDeclarationSyntax), // $"{ns}.{interfaceDeclarationSyntax.Identifier}",
|
||||
FullRawTypeName = rawTypeName,
|
||||
ShortTypeName = ConvertTypeName(rawTypeName).Split('.').Last(),
|
||||
FullTypeName = ConvertTypeName(rawTypeName),
|
||||
FullRawTypeName = rawTypeNameAsString,
|
||||
ShortTypeName = ConvertTypeName(rawTypeNameAsString).Split('.').Last(),
|
||||
FullTypeName = ConvertTypeName(rawTypeNameAsString),
|
||||
Usings = usings,
|
||||
ProxyBaseClasses = proxyBaseClasses
|
||||
ProxyBaseClasses = fluentBuilderAttributeArguments.ProxyBaseClasses,
|
||||
Accessibility = fluentBuilderAttributeArguments.Accessibility
|
||||
};
|
||||
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace ProxyInterfaceSourceGenerator.Types;
|
||||
|
||||
internal record ProxyInterfaceGeneratorAttributeArguments(string RawTypeName)
|
||||
{
|
||||
public bool ProxyBaseClasses { get; set; }
|
||||
|
||||
public ProxyClassAccessibility Accessibility { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace ProxyInterfaceSourceGenerator.Types;
|
||||
|
||||
[Flags]
|
||||
internal enum ProxyClassAccessibility
|
||||
{
|
||||
Public = 0,
|
||||
|
||||
Internal = 1
|
||||
}
|
||||
Reference in New Issue
Block a user