Marcelo Glasberg
Marcelo Glasberg

Reputation: 30879

How do I get the AstNode from some Element, in Dart Analyzer / source-gen?

I'm using source_gen to parse some Dart files, through the Dart analyzer.

I'm extending GeneratorForAnnotation<>, and overriding method FutureOr<String> generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep). This method gives me a base element, which I navigate until I find some other element, say a MethodElement.

Once I get hold of this MethodElement, I want to analyze the method's block, in detail. I'd like something like this:

AstNode node = methodElement.computeNode();

In more detail:

class MyGenerator extends GeneratorForAnnotation<MyAnnotation> {

    @override
    FutureOr<String> generateForAnnotatedElement(
        Element element, ConstantReader annotation, BuildStep buildStep,
    ) {
      if (element is ClassElement)
        for (MethodElement methodElement in element.methods) {
          AstNode node = methodElement.computeNode();
          processMyNode(node);
        }
      else
        throw AssertionError();
    }
}

Unfortunately, computeNode is deprecated. If I try to call it, I get:

NoSuchMethodError: Class 'RestrictedAnalysisContext' has no instance method 'resolveCompilationUnit' with matching arguments.
Receiver: Instance of 'RestrictedAnalysisContext'
Tried calling: resolveCompilationUnit(Instance of 'FileSource', Instance of 'LibraryElementImpl')
Found: resolveCompilationUnit(Source, LibraryElement) => CompilationUnit

My question: How can I get the AstNode?

Upvotes: 10

Views: 868

Answers (2)

hacker1024
hacker1024

Reputation: 3658

While MarcG's solution works for most elements, it does not work for the root LibraryElements themselves.

To get the AstNode (or, more specifically, a CompilationUnit) for a LibraryElement's defining CompilationUnitElement, the following can be done:

final libraryCompilationUnit = (libraryElement.session
        .getParsedLibraryByElement(libraryElement) as ParsedLibraryResult)
    .units[0]
    .unit;

Upvotes: 2

Marcelo Glasberg
Marcelo Glasberg

Reputation: 30879

Got it:

AstNode getAstNodeFromElement(Element element) {
  AnalysisSession session = element.session;
  ParsedLibraryResult parsedLibResult = session.getParsedLibraryByElement(element.library);
  ElementDeclarationResult elDeclarationResult = parsedLibResult.getElementDeclaration(element);
  return elDeclarationResult.node;
}

Upvotes: 12

Related Questions