Reference highlighting in Dart

Answered

I am new to IntelliJ plugin development and trying to fix the issue for https://github.com/dart-lang/sdk/issues/48281

With this case

class A {
A(int x);
}

class B extends A {
int y;

B(super.x) : y = x * 2;
}

 

When the cursor is at `y`, its declaration and usage are highlighted, which is fine. However, when the cursor is in `x` in `x * 2`, it doesn't highlight any other `x`, which is not fine.


I have looked into the code, and `DartAnalysisServerService.getNavigation()` seems to return the navigation (clicking on `x` would jump the cursor to the declaration), which works fine.

My question is: what is the IntelliJ API that is responsible for highlighting other elements when the cursor is at an element. I suspect it should use 'occurrences' as returned from the server, instead of the current way (which I am not able to find how it currently works).

3 comments
Comment actions Permalink
Official comment

IntelliJ doesn't use AnalysisServer.occurrences() notification for occurrences highlighting but it uses its own standard mechanism, which is based on references resolution, which for Dart means - navigation info received from server.

The trick with this example is that "x" in "x * 2" is a reference to "x" in "super.x" while "x" in "super.x" is itself a reference to "x" in "int x".

I need more time to find a proper solution. As a quick check - changing "return target == element" to "return true" in DartReferenceImpl#isReferenceTo() helps a bit. All 3 occurrences of "x" are highlighted when caret is in "super.x". Unfortunately, not when caret in "x * 2". I haven't investigated further yet.

Switching to AnalysisServer.occurrences() notification is worth investigating as well.

 

Comment actions Permalink

Thanks for the feedback.

I currently understand that IntelliJ both highlighting and navigation uses `DartReferenceImpl` resolve/multiResolve(). Changing `DartResolver.findRegion` to return the region of the target would fix the highlighting, but it will make the navigation skips the "super.x", so that clicking "x * 2" would go to the "int x".

Is there an API which is used for only 'highlighting', or only 'navigation', which we can use to differentiate between the two cases, so we return the reference similar to the current behavior for 'navigation', but return the target for the 'highlighting'. Or can we know in 'resolve()' if it is called from highlighting or navigation?

I tried to debug around `highlightUsages.kt` but was lost afterwards.

0
Comment actions Permalink

I can say that yes, there's API for everything and yes, everything is possible, but I'll need some time to debug the IntelliJ Platform and find the best way of solving this task. Sorry, no helpful answer right away.

0

Please sign in to leave a comment.