I'm using ICSharpCode.Decompiler.Ast.AstBuilder
(which is used by SharpDevelop, NRefactory and ILSpy under the hood; has taken inspiration from there too) from code to build an abstract syntax tree from a .NET Common Intermediate Language assembly.
var assembly = AssemblyDefinition.ReadAssembly(assemblyPath);
var astBuilder = new AstBuilder(new DecompilerContext(assembly.MainModule));
astBuilder.AddAssembly(assembly);
// astBuilder.SyntaxTree ...
The syntax tree contains TypeReferenceExpression
s whenever a line like Math.Abs()
is there. How can I retrieve the TypeDeclaration
of the referenced type when it also exists in the same syntax tree?
The closest I got is TypeReferenceExpression.Type.ToTypeReference().Resolve()
but this is very heavy to orchestrate, and I already have (I suppose) all the information in the syntax tree. I also tried manual lookup by using namespaces an identifiers but I guess there should be a better way.
You can use SyntaxTree.GetTypes()
to enumerate all decompiled types. Since that's rather heavy, I'd build up a reference-to-declaration lookup, e.g.:
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>());
You can then fetch the TypeReference
from your TypeReferenceExpression
and use it to find the type's declaration in the lookup:
TypeReferenceExpression e = /* ... */;
TypeDeclaration declaration;
if (lookup.TryGetValue(e.Type.Annotation<TypeReference>(), out declaration))
Console.WriteLine(declaration.GetText()); // do whatever