using Microsoft.CodeAnalysis;
using System.Collections.Generic;
using System.Linq;
namespace Fantasy.SourceGenerator.Common
{
///
/// Roslyn 相关的扩展方法
///
internal static class RoslynExtensions
{
///
/// 检查类型是否实现了指定的接口(通过完全限定名)
///
public static bool ImplementsInterface(this INamedTypeSymbol typeSymbol, string interfaceFullName)
{
return typeSymbol.AllInterfaces.Any(i => i.ToDisplayString() == interfaceFullName);
}
///
/// 检查类型是否继承自指定的基类(通过完全限定名)
///
public static bool InheritsFrom(this INamedTypeSymbol typeSymbol, string baseTypeFullName)
{
var current = typeSymbol.BaseType;
while (current != null)
{
if (current.ToDisplayString() == baseTypeFullName)
{
return true;
}
current = current.BaseType;
}
return false;
}
///
/// 获取类型的完全限定名(包括命名空间)
///
public static string GetFullName(this ITypeSymbol typeSymbol, bool includeGlobal = true)
{
var displayString = typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
return includeGlobal ? displayString : displayString.Replace("global::", "");
}
///
/// 检查类型是否可以被实例化(非抽象、非接口、非泛型定义)
///
public static bool IsInstantiable(this INamedTypeSymbol typeSymbol)
{
// 允许:具体的类(非抽象、非静态)
// 排除:抽象类、静态类、接口、开放泛型类型(如 MyClass where T 未指定)
return typeSymbol is { IsAbstract: false, IsStatic: false, TypeKind: TypeKind.Class };
}
///
/// 获取所有实现指定接口的类型
///
public static IEnumerable GetTypesImplementingInterface(
this Compilation compilation,
string interfaceFullName)
{
var visitor = new InterfaceImplementationVisitor(interfaceFullName);
visitor.Visit(compilation.GlobalNamespace);
return visitor.ImplementingTypes;
}
///
/// 转换为驼峰命名
///
public static string ToCamelCase(this string name)
{
if (string.IsNullOrEmpty(name) || char.IsLower(name[0]))
{
return name;
}
return char.ToLowerInvariant(name[0]) + name.Substring(1);
}
///
/// 访问器:查找实现特定接口的所有类型
///
private class InterfaceImplementationVisitor : SymbolVisitor
{
private readonly string _interfaceFullName;
private readonly List _implementingTypes = new List();
public IReadOnlyList ImplementingTypes => _implementingTypes;
public InterfaceImplementationVisitor(string interfaceFullName)
{
_interfaceFullName = interfaceFullName;
}
public override void VisitNamespace(INamespaceSymbol symbol)
{
foreach (var member in symbol.GetMembers())
{
member.Accept(this);
}
}
public override void VisitNamedType(INamedTypeSymbol symbol)
{
if (symbol.IsInstantiable() && symbol.ImplementsInterface(_interfaceFullName))
{
_implementingTypes.Add(symbol);
}
// 递归访问嵌套类型
foreach (var nestedType in symbol.GetTypeMembers())
{
nestedType.Accept(this);
}
}
}
///
/// 尝试获取泛型接口的类型参数
/// 例如:IAwakeSystem<PlayerEntity> 返回 PlayerEntity
///
public static ITypeSymbol? GetGenericInterfaceTypeArgument(
this INamedTypeSymbol typeSymbol,
string genericInterfaceName)
{
var matchingInterface = typeSymbol.AllInterfaces.FirstOrDefault(i =>
i.IsGenericType &&
i.ConstructedFrom.ToDisplayString() == genericInterfaceName);
return matchingInterface?.TypeArguments.FirstOrDefault();
}
}
}