ICSharpCode декомпилятор получить из TypeReferenceExpression для TypeDeclaration?

Я использую ICSharpCode.Decompiler.Ast.AstBuilder (который используется SharpDevelop, NRefactory и ILSpy под капотом; оттуда тоже черпал вдохновение) из кода для построения абстрактного синтаксического дерева из сборки.NET Common Intermediate Language.

var assembly = AssemblyDefinition.ReadAssembly(assemblyPath);
var astBuilder = new AstBuilder(new DecompilerContext(assembly.MainModule));
astBuilder.AddAssembly(assembly);
// astBuilder.SyntaxTree ...

Дерево синтаксиса содержит TypeReferenceExpressionS всякий раз, когда строка, как Math.Abs() есть. Как я могу получить TypeDeclaration ссылочного типа, когда он также существует в том же синтаксическом дереве?

Самое близкое, что у меня есть, это TypeReferenceExpression.Type.ToTypeReference().Resolve() но это очень тяжело организовать, и у меня уже есть (я полагаю) вся информация в синтаксическом дереве. Я также попробовал поиск вручную, используя пространства имен и идентификаторы, но я думаю, что должен быть лучший способ.

1 ответ

Решение

Ты можешь использовать SyntaxTree.GetTypes() перечислить все декомпилированные типы. Поскольку это довольно тяжело, я бы создал поиск по ссылке на объявление, например:

var assembly = AssemblyDefinition.ReadAssembly(assemblyPath);
var astBuilder = new AstBuilder(new DecompilerContext(assembly.MainModule));

astBuilder.AddAssembly(assembly);

var ast = astBuilder.SyntaxTree;

var lookup = ast.GetTypes(true)
                .ToDictionary(d => (TypeReference)d.Annotation<TypeDefinition>());

Затем вы можете получить TypeReference от твоего TypeReferenceExpression и использовать его, чтобы найти объявление типа в поиске:

TypeReferenceExpression e = /* ... */;
TypeDeclaration declaration;

if (lookup.TryGetValue(e.Type.Annotation<TypeReference>(), out declaration))
    Console.WriteLine(declaration.GetText());  // do whatever
Другие вопросы по тегам