Navigation information is used by clients to allow users to navigate to the location at which an identifier is defined.
Navigation information can be requested both by an analysis.getNavigation
request and by a subscription. If the server has subscribed for navigation information in some set of files, the the plugin should send the information in an analysis.navigation
notification whenever the information needs to be updated.
When an analysis.getNavigation
request is received, the method handleAnalysisGetNavigation
will be invoked. This method is responsible for returning a response that contains the available navigation information.
When a notification needs to be sent, the method sendNavigationNotification
will be invoked. This method is responsible for sending the notification.
The easiest way to add support for both the request and the notification is by adding the classes NavigationMixin
and DartNavigationMixin
(from package:analyzer_plugin/plugin/navigation_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: getNavigationContributors
. That method is responsible for returning a list of NavigationContributor
s. It is the navigation contributors that produce the actual navigation information. (Most plugins will only need a single navigation contributor.)
To write a navigation contributor, create a class that implements NavigationContributor
. The interface defines a single method named computeNavigation
. The method has two arguments: a NavigationRequest
that describes the region of the file for which navigation is being requested and a NavigationCollector
through which navigation information is to be added.
If you mix in the class DartNavigationMixin
, then the request will be an instance of DartNavigationRequest
, which also has analysis results.
Start by creating a class that implements NavigationContributor
, then implement the method computeNavigation
. 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 navigation information from the analysis result.
For example, your contributor might look something like the following:
class MyNavigationContributor implements NavigationContributor { @override void computeNavigation( NavigationRequest request, NavigationCollector collector) { if (request is DartNavigationRequest) { NavigationVisitor visitor = new NavigationVisitor(collector); request.result.unit.accept(visitor); } } } class NavigationVisitor extends RecursiveAstVisitor { final NavigationCollector collector; NavigationVisitor(this.collector); @override void visitSimpleIdentifier(SimpleIdentifier node) { // ... } }
Given a contributor like the one above, you can implement your plugin similar to the following:
class MyPlugin extends ServerPlugin with NavigationMixin, DartNavigationMixin { // ... @override List<NavigationContributor> getNavigationContributors(String path) { return <NavigationContributor>[new MyNavigationContributor()]; } }