Language API observations/questions
Hi,
after playing a bit more with the language API, I made the following observations that
may be worth to look at and also may be interesting for plugin developers to know about:
- Find Usages: After doing a find usages on an element, the next time it is invoked
on the same file(-type?), it will revert to a "Find Usages in File". This is probably
correct because neither the JS plugin nor my own toy language have references outside
the file, but this behavior doesn't seem right.
Also, the result view has options to toggle the listing of read/write access. There is
however no (obvious) way for a custom language to specify that. I think the FindUsages
provider should be able to provide custom filter/grouping actions for such language-
dependent purposes.
- Highlight Usages in File: This doesn't work at all. Shouldn't this use the same
mechanism as Find Usages does?
- Before build #3273 it was possible to use
AnnotationHolder.createInfoAnnotation(element, null).setTextAttributes(...)
to create special text styles/colors for certain elements. This still works, but now the
annotation shows up with a yellow mark in the right gutter with the tooltip "null".
How is this supposed to be done now without creating any gutter-mark?
- What exactly can be put into the Object[] that is returned by PsiReference.getVariants()?
PsiElements, Strings (with html formatting maybe?), ... ?
This is one of the places where 2 lines of JavaDoc would help immensely ;)
- I found this code e.g. in the JS-Function implementation:
public int getTextOffset() {
final ASTNode name = findNameIdentifier();
return name != null ? name.getStartOffset() : super.getTextOffset();
}
This will make the caret to jump to the function name on e.g. find usages or ctrl-b.
There is however also a method called getNavigationElement() that seems to be there for
exactly this purpose. But overriding this will cause ctrl-b to fail, while Find Usages
still works as expected. What's the deal with this method and why is the getTextOffset()
'hack' used here?
- What exactly is Language.mayHaveReferences() responsible for? Looking at the JS plugin
(and how the method works), shouldn't this be called "isReference"? It seems to be the
same as asking the according PsiElement if it is an instance of PsiReference, just on token
level.
Not sure if those things are any issues at all, but maybe it can help a little to improve the API.
Cheers,
Sascha
请先登录再写评论。
We'll dig into, thanks.
Nice shot. A JIRA request please?
Sure. It's just not implemented yet.
Bug...
That could be both strings and PsiElements. In latter case lookup items will
have nice icons if defined for that PSI element.
NavigationElement just servse slightly different purpose. One used (in java)
to open source file attached to a library when invoked against compiled version
of the class.
Generally, getTextOffset() may return offset that is located inside some
element which wouldn't be possible if we require whole element to be returned.
As the matter of fact PsiReference is not a PsiElement but rather array of
references might be returned by arbitrary PSI element. For instance, XML
attribute value element may return references to java class if there's something
in it's value that looks like qualified class name. Language.mayHaveReferences()
method serves like quite hacky possible performance problems workaround.
It is only used when searching for usages. We do process enormous number
of references at that time so this one quite helps to skip elements that
cannot ever contain references.
Sure. Feedbacks like this are highly appreciated.
Maxim Shafirov wrote:
>> I think the FindUsages provider should be able to
>> provide custom filter/grouping actions for such language- dependent
>> purposes.
Sure: http://www.jetbrains.net/jira/browse/IDEA-1216
Not important for me at all, but maybe useful for "serious" language
integrations :)
>> - Highlight Usages in File: This doesn't work at all. Shouldn't this
>> use the same mechanism as Find Usages does?
I thought it should work automagically. Not a problem at all.
>> - What exactly can be put into the Object[] that is returned by
>> PsiReference.getVariants()?
Well, the reason I'm asking is that for CSS there is the "choose color..."
completion that invokes an action, so I thought that there's maybe more than
just strings and PsiElements ;)
Ah, ok. It just had a slightly 'hacky' smell :)
>> - What exactly is Language.mayHaveReferences() responsible for?
I'm still chewing on that one, but it's getting more clear now: PsiElement
and PsiReference are totally distinct and the connection is only done by
PsiElement.getReference[s](). In the JS plugin's case however, the reference
expression and the PsiReference are the same, thus JSReferenceExpressionImpl
returns 'this' in getReference(). Yes, considering that, mayHaveReferences()
makes sense.
Thanks for the comments,
Sascha
Yep, indeed there are some more. But those look quite hacky right now so
we do not open them.
-
Maxim Shafirov
http://www.jetbrains.com
"Develop with pleasure!"
It still creates a gutter mark in #3281.
http://www.jetbrains.net/jira/browse/IDEA-1331
Vince.