Providing Outlines

Outline information is used by clients to allow users to see the structure of their code.

Implementation details

Outline information is available through a subscription. If the server has subscribed for outline information in some set of files, then the plugin should send the information in an analysis.outline notification whenever the information needs to be updated.

When a notification needs to be sent, the method sendOutlineNotification will be invoked. This method is responsible for sending the notification.

The easiest way to add support for this notification is by adding the classes OutlineMixin and DartOutlineMixin (from package:analyzer_plugin/plugin/outline_mixin.dart) to the list of mixins for your subclass of ServerPlugin. This will leave you with one abstract method that you need to implement: getOutlineContributors. That method is responsible for returning a list of OutlineContributors. It is the outline contributors that produce the actual outline information. (Most plugins will only need a single outline contributor.)

To write an outline contributor, create a class that implements OutlineContributor. The interface defines a single method named computeOutline. The method has two arguments: an OutlineRequest that describes the file for which outline information is being requested and an OutlineCollector through which outline information is to be added.

If you mix in the class DartOutlineMixin, then the request will be an instance of DartOutlineRequest, which also has analysis results.

Example

Start by creating a class that implements OutlineContributor, then implement the method computeOutline. This method is typically implemented by creating a visitor (such as an AstVisitor) that can visit the results of the analysis (such as a CompilationUnit) and extract the outline information from the analysis result.

For example, your contributor might look something like the following:

class MyOutlineContributor implements OutlineContributor {
  @override
  void computeOutline(
      OutlineRequest request, OutlineCollector collector) {
    if (request is DartOutlineRequest) {
      OutlineVisitor visitor = new OutlineVisitor(collector);
      request.result.unit.accept(visitor);
    }
  }
}

class OutlineVisitor extends RecursiveAstVisitor {
  final OutlineCollector collector;

  OutlineVisitor(this.collector);

  @override
  void visitClassDeclaration(ClassDeclaration node) {
    // ...
  }
}

Given a contributor like the one above, you can implement your plugin similar to the following:

class MyPlugin extends ServerPlugin with OutlineMixin, DartOutlineMixin {
  // ...

  @override
  List<OutlineContributor> getOutlineContributors(String path) {
    return <OutlineContributor>[new MyOutlineContributor()];
  }
}