我类似的任务的方法(我想重写方法和属性与特定的属性饰)是找到属性符号的所有用途,然后遍历引用并获得方法/属性声明语法:
var attributeSymbol = compilation.FindSymbol(typeof(<Your attribute type>));
var references = attributeSymbol.FindReferences(solution);
foreach (ReferencedSymbol referencedSymbol in references)
{
foreach (ReferenceLocation location in referencedSymbol.Locations)
{
var propertyDeclaration = location.Document.GetSyntaxRoot()
.FindToken(location.Location.SourceSpan.Start)
.Parent
.FirstAncestorOrSelf<PropertyDeclarationSyntax>();
}
}
我不得不写一些扩展方法,使生活更轻松:
public static class CompilationExtensions
{
public static INamedTypeSymbol FindSymbol(this CommonCompilation compilation, Type searchedType)
{
var splitFullName = searchedType.FullName.Split('.');
var namespaceNames = splitFullName.Take(splitFullName.Length - 1).ToArray();
var className = splitFullName.Last();
if (namespaceNames.Length == 0)
return compilation.GlobalNamespace.GetAllTypes(new CancellationToken()).First(n => n.Name == className);
var namespaces = compilation.GlobalNamespace.GetNamespaceMembers();
INamespaceSymbol namespaceContainingType = null;
foreach (var name in namespaceNames)
{
namespaceContainingType = namespaces.First(n => n.Name == name);
namespaces = namespaceContainingType.GetNamespaceMembers();
}
return namespaceContainingType.GetAllTypes(new CancellationToken()).First(n => n.Name == className);
}
}
public static class INamespaceSymbolExtension
{
public static IEnumerable<INamedTypeSymbol> GetAllTypes(this INamespaceSymbol @namespace, CancellationToken cancellationToken)
{
Queue<INamespaceOrTypeSymbol> symbols = new Queue<INamespaceOrTypeSymbol>();
symbols.Enqueue(@namespace);
while (symbols.Count > 0)
{
cancellationToken.ThrowIfCancellationRequested();
INamespaceOrTypeSymbol namespaceOrTypeSymbol = symbols.Dequeue();
INamespaceSymbol namespaceSymbol = namespaceOrTypeSymbol as INamespaceSymbol;
if (namespaceSymbol == null)
{
INamedTypeSymbol typeSymbol = (INamedTypeSymbol) namespaceOrTypeSymbol;
Array.ForEach(typeSymbol.GetTypeMembers().ToArray(), symbols.Enqueue);
yield return typeSymbol;
}
else
{
Array.ForEach(namespaceSymbol.GetMembers().ToArray(), symbols.Enqueue);
}
}
}
}
我无法得到它使用确切的语法,我不得不CH ange last line to following:&& m.GetAttributes()。Any(a => a.AttributeClass.MetadataName == attSymbol.MetadataName)); – epitka
:似乎当一个人得到“classSymbol”它不能被转换为“SourcePropertySymbol”来获得该属性的类型?我们是否从这里走过语法节点来查找类型?我必须做以下事情来获取属性member.DeclaringSyntaxNodes.First()的类型名称。ChildNodes()。OfType()。First()。GetFirstToken()。Value; –
epitka
那么,“SourcePropertySymbol”是一个内部类型,但你应该能够向公众“PropertySymbol”类型转换并获得属性的“类型”。 –