Merge branch 'main' of https://github.com/StefH/ProxyInterfaceSourceGenerator
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ProxyInterfaceSourceGenerator.Extensions;
|
||||
@@ -37,4 +38,54 @@ internal static class SyntaxNodeExtensions
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// determine the namespace the class/enum/struct is declared in, if any
|
||||
/// https://andrewlock.net/creating-a-source-generator-part-5-finding-a-type-declarations-namespace-and-type-hierarchy/
|
||||
/// </summary>
|
||||
/// <param name="syntaxNode"></param>
|
||||
/// <returns>NameSpace</returns>
|
||||
public static string GetNamespace(this SyntaxNode syntaxNode)
|
||||
{
|
||||
// If we don't have a namespace at all we'll return an empty string
|
||||
// This accounts for the "default namespace" case
|
||||
string nameSpace = string.Empty;
|
||||
|
||||
// Get the containing syntax node for the type declaration
|
||||
// (could be a nested type, for example)
|
||||
SyntaxNode? potentialNamespaceParent = syntaxNode.Parent;
|
||||
|
||||
// Keep moving "out" of nested classes etc until we get to a namespace
|
||||
// or until we run out of parents
|
||||
while (potentialNamespaceParent != null &&
|
||||
potentialNamespaceParent is not NamespaceDeclarationSyntax
|
||||
&& potentialNamespaceParent is not FileScopedNamespaceDeclarationSyntax)
|
||||
{
|
||||
potentialNamespaceParent = potentialNamespaceParent.Parent;
|
||||
}
|
||||
|
||||
// Build up the final namespace by looping until we no longer have a namespace declaration
|
||||
if (potentialNamespaceParent is BaseNamespaceDeclarationSyntax namespaceParent)
|
||||
{
|
||||
// We have a namespace. Use that as the type
|
||||
nameSpace = namespaceParent.Name.ToString();
|
||||
|
||||
// Keep moving "out" of the namespace declarations until we
|
||||
// run out of nested namespace declarations
|
||||
while (true)
|
||||
{
|
||||
if (namespaceParent.Parent is not NamespaceDeclarationSyntax parent)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the outer namespace as a prefix to the final namespace
|
||||
nameSpace = $"{namespaceParent.Name}.{nameSpace}";
|
||||
namespaceParent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
// return the final namespace
|
||||
return nameSpace;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
namespace ProxyInterfaceSourceGenerator.Models;
|
||||
|
||||
internal record ProxyData
|
||||
(
|
||||
string Namespace,
|
||||
string ShortInterfaceName,
|
||||
string FullInterfaceName,
|
||||
string FullRawTypeName,
|
||||
string ShortTypeName,
|
||||
string FullTypeName,
|
||||
List<string> Usings,
|
||||
bool ProxyBaseClasses
|
||||
);
|
||||
internal class ProxyData
|
||||
{
|
||||
public string Namespace { get; init; }
|
||||
public string ShortInterfaceName { get; init; }
|
||||
public string FullInterfaceName { get; init; }
|
||||
public string FullRawTypeName { get; init; }
|
||||
public string ShortTypeName { get; init; }
|
||||
public string FullTypeName { get; init; }
|
||||
public List<string> Usings { get; init; }
|
||||
public bool ProxyBaseClasses { get; init; }
|
||||
}
|
||||
@@ -15,10 +15,12 @@ internal class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
|
||||
public void Initialize(GeneratorInitializationContext context)
|
||||
{
|
||||
//if (!System.Diagnostics.Debugger.IsAttached)
|
||||
//{
|
||||
// System.Diagnostics.Debugger.Launch();
|
||||
//}
|
||||
#if DEBUGATTACH
|
||||
if (!System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
System.Diagnostics.Debugger.Launch();
|
||||
}
|
||||
#endif
|
||||
|
||||
context.RegisterForSyntaxNotifications(() => new ProxySyntaxReceiver());
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)Generated</CompilerGeneratedFilesOutputPath>
|
||||
<DevelopmentDependency>true</DevelopmentDependency>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Configurations>Debug;Release;DebugAttach</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
@@ -37,12 +38,12 @@
|
||||
|
||||
<ItemGroup>
|
||||
<!--<PackageReference Include="AutoMapper" Version="10.1.1" />-->
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
|
||||
<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.Common" Version="3.10.0" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" PrivateAssets="all" />
|
||||
<!--<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.10.0" PrivateAssets="all" />-->
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -57,8 +58,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="bin\Debug\netstandard2.0\\ProxyInterfaceGenerator.dll" />
|
||||
<None Remove="bin\Release\netstandard2.0\\ProxyInterfaceGenerator.dll" />
|
||||
<None Remove="bin\Release\netstandard2.0\\ProxyInterfaceSourceGenerator.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -46,10 +46,9 @@ internal class ProxySyntaxReceiver : ISyntaxReceiver
|
||||
|
||||
var usings = new List<string>();
|
||||
|
||||
string ns = string.Empty;
|
||||
if (interfaceDeclarationSyntax.TryGetParentSyntax(out NamespaceDeclarationSyntax? namespaceDeclarationSyntax))
|
||||
string ns = interfaceDeclarationSyntax.GetNamespace();
|
||||
if (!string.IsNullOrEmpty(ns))
|
||||
{
|
||||
ns = namespaceDeclarationSyntax.Name.ToString();
|
||||
usings.Add(ns);
|
||||
}
|
||||
|
||||
@@ -73,18 +72,18 @@ internal class ProxySyntaxReceiver : ISyntaxReceiver
|
||||
{
|
||||
proxyAllClasses = false;
|
||||
}
|
||||
|
||||
data = new
|
||||
(
|
||||
ns,
|
||||
interfaceDeclarationSyntax.Identifier.ToString(),
|
||||
$"{ns}.{interfaceDeclarationSyntax.Identifier}",
|
||||
rawTypeName,
|
||||
ConvertTypeName(rawTypeName).Split('.').Last(), // ShortTypeName
|
||||
ConvertTypeName(rawTypeName), // FullTypeName
|
||||
usings,
|
||||
proxyAllClasses
|
||||
);
|
||||
|
||||
data = new ProxyData
|
||||
{
|
||||
Namespace = ns,
|
||||
ShortInterfaceName = interfaceDeclarationSyntax.Identifier.ToString(),
|
||||
FullInterfaceName = CreateFullBuilderClassName(ns, interfaceDeclarationSyntax), // $"{ns}.{interfaceDeclarationSyntax.Identifier}",
|
||||
FullRawTypeName = rawTypeName,
|
||||
ShortTypeName = ConvertTypeName(rawTypeName).Split('.').Last(),
|
||||
FullTypeName = ConvertTypeName(rawTypeName),
|
||||
Usings = usings,
|
||||
ProxyBaseClasses = proxyAllClasses
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -95,4 +94,9 @@ internal class ProxySyntaxReceiver : ISyntaxReceiver
|
||||
typeName :
|
||||
$"{typeName.Replace("<", string.Empty).Replace(">", string.Empty).Replace(",", string.Empty).Trim()}`{typeName.Count(c => c == ',') + 1}";
|
||||
}
|
||||
|
||||
private static string CreateFullBuilderClassName(string ns, BaseTypeDeclarationSyntax classDeclarationSyntax)
|
||||
{
|
||||
return !string.IsNullOrEmpty(ns) ? $"{ns}.{classDeclarationSyntax.Identifier}" : classDeclarationSyntax.Identifier.ToString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user