dartdart-analyzer

In Dart, how do I get from the AST to Elements?


In Dart, how do I get from the AST to Elements?

I generate the AST like this:

var ast = parseFile(path: "/home/user/myFile.dart", featureSet: FeatureSet.latestLanguageVersion());

I can access the declaration nodes, but I would like get to the Elements (e.g. LibraryElement, ClassElement, etc.).

How to do this?


Solution

  • The Dart Analyzer is built to work with a filesystem structure, and cannot build an element tree from a single file alone.

    The analysis APIs to analyze a collection of files are described in this document.

    On another note, the analyzer package also provides APIs to emulate a filesystem in-memory.
    This means that library code in the form of a String can also be analyzed if need be, by emulating a file.

    In order to analyse a single file, we can use these APIs alongside, if need be, an in-memory filesystem structure layered on top of the real filesystem, to allow the analyzer to access required SDK files in addition to the emulated file.

    import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
    import 'package:analyzer/dart/analysis/results.dart';
    import 'package:analyzer/file_system/overlay_file_system.dart';
    import 'package:analyzer/file_system/physical_file_system.dart';
    
    const filePath = '/path/to/myFile.dart';
    
    final collection = AnalysisContextCollection(
      includedPaths: const [filePath],
    
      // If using an in-memory file, also provide a layered ResourceProvider:
      resourceProvider: OverlayResourceProvider(PhysicalResourceProvider())
        ..setOverlay(
          filePath,
          content: libraryCode,
          modificationStamp: 0,
        ),
    );
    final analysisSession = collection.contextFor(filePath).currentSession;
    final libraryElement = await analysisSession
        .getLibraryByUri('file://$filePath')
        .then((libraryResult) => (libraryResult as LibraryElementResult).element);