81 lines
2.7 KiB
C#
81 lines
2.7 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Microsoft.CodeAnalysis;
|
|
|
|
namespace Polonium.Generators;
|
|
|
|
public abstract class AssetProcessGenerator : ISourceGenerator
|
|
{
|
|
public void Initialize(GeneratorInitializationContext context)
|
|
{
|
|
context.RegisterForSyntaxNotifications(() => new ClassSyntaxReceiver());
|
|
}
|
|
|
|
public abstract void Execute(GeneratorExecutionContext context);
|
|
|
|
protected IEnumerable<AssetInfo> GetAssetsOfType(GeneratorExecutionContext context, INamedTypeSymbol? t)
|
|
{
|
|
if (!(context.SyntaxReceiver is ClassSyntaxReceiver receiver))
|
|
yield break;
|
|
Compilation compilation = context.Compilation;
|
|
foreach (var derivedClassDeclaration in receiver.Classes)
|
|
{
|
|
SemanticModel model = compilation.GetSemanticModel(derivedClassDeclaration.SyntaxTree);
|
|
INamedTypeSymbol? derivedClassSymbol = model.GetDeclaredSymbol(derivedClassDeclaration) as INamedTypeSymbol;
|
|
string filePath = derivedClassDeclaration.SyntaxTree.FilePath;
|
|
string className = Path.GetFileNameWithoutExtension(filePath);
|
|
if(derivedClassSymbol == null || !filePath.Contains("Assets"))
|
|
continue;
|
|
AssetInfo res = new AssetInfo
|
|
{
|
|
DeclarationSyntax = derivedClassDeclaration,
|
|
ClassName = className,
|
|
ClassFullName = derivedClassSymbol.ToDisplayString(),
|
|
Path = filePath,
|
|
Symbol = derivedClassSymbol
|
|
};
|
|
if (IsDerivedFrom(derivedClassSymbol, t))
|
|
{
|
|
yield return res;
|
|
continue;
|
|
}
|
|
foreach (INamedTypeSymbol interfaceSymbol in derivedClassSymbol.AllInterfaces)
|
|
{
|
|
if (SymbolEqualityComparer.Default.Equals(interfaceSymbol, t))
|
|
{
|
|
yield return res;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
protected IEnumerable<AssetInfo> GetAssetsOfType(GeneratorExecutionContext context, string t)
|
|
{
|
|
|
|
Compilation compilation = context.Compilation;
|
|
INamedTypeSymbol? specificType = compilation.GetTypeByMetadataName(t);
|
|
return GetAssetsOfType(context, specificType);
|
|
}
|
|
protected static bool IsDerivedFrom(INamedTypeSymbol? symbol, INamedTypeSymbol? baseType)
|
|
{
|
|
if (symbol == null)
|
|
return false;
|
|
if (baseType == null)
|
|
return true;
|
|
INamedTypeSymbol? current = symbol.BaseType;
|
|
|
|
while (current != null)
|
|
{
|
|
if (SymbolEqualityComparer.Default.Equals(current, baseType))
|
|
return true;
|
|
current = current.BaseType;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
}
|