Language API: (1) getVariants() never called? (2) Find Usages only partly works
I am having two more problems with Language API. I hope someone can help
me with them.
First, even when inside an element which implements PsiReference, (I can
ctrl+click on it so it must be PsiReference for sure), I press
ctrl+space anywhere in it and my breakpoint inside getVariants() is
never hit - it's never called. Is there some special setup necessary for
completion to work?
Second, I implemented a find-usages provider. Here are facts:
1. Ctrlshiftf7 on a definition works, highlighting all the right usages.
2. Ctrlshiftf7 on a usage does not work, even though it is a
PsiReference to the original element. It says "no usages found"
3. Ctrl+f7 sort of works on a reference, it correctly shows the dialog
saying "Find usasges for message xxx". However, when I click "find," it
says no usages are found.
4. Ctrl+f7 doesn't work at all on the element itself, a dialog says
"Cannot find usages."
I think am missing some piece here. I will paste my reference class and
my find usages provider:
defs =
protoFile.getMessageDefinitions();
return defs.toArray();
}
public boolean isSoft() {
return false;
}
}
class ProtoFindUsagesProvider implements FindUsagesProvider {
public boolean mayHaveReferences(IElementType token, short
searchContext) {
if ((searchContext & UsageSearchContext.IN_CODE) != 0 && (token
== ProtoElementTypes.MESSAGE_TYPE_REFERENCE)) {
return true;
}
if ((searchContext & UsageSearchContext.IN_COMMENTS) != 0 && (
token == ProtoTokenTypes.END_OF_LINE_COMMENT || token
== ProtoTokenTypes.C_STYLE_COMMENT)) {
return true;
}
if ((searchContext & UsageSearchContext.IN_STRINGS) != 0
&& token == ProtoTokenTypes.STRING_LITERAL) {
return true;
}
return false;
}
@Nullable
public WordsScanner getWordsScanner() {
return new ProtoWordsScanner();
}
public boolean canFindUsagesFor(PsiElement psiElement) {
return psiElement instanceof ProtoMessageDefinition;
}
@Nullable
public String getHelpId(PsiElement psiElement) {
return null;
}
@NotNull
public String getType(PsiElement psiElement) {
if (psiElement instanceof ProtoMessageDefinition) return "message";
if (psiElement instanceof ProtoServiceDefinition) return "service";
if (psiElement instanceof ProtoProperty) return "property";
if (psiElement instanceof ProtoRpcDefinition) return "rpc";
return "";
}
@NotNull
public String getDescriptiveName(PsiElement psiElement) {
return getNodeText(psiElement, false);
}
@NotNull
public String getNodeText(PsiElement psiElement, boolean useFullName) {
if (psiElement instanceof ProtoNamedElement) {
ProtoNamedElement protoNamedElement = (ProtoNamedElement)
psiElement;
String name = protoNamedElement.getName();
if (name != null) return name;
}
return "";
}
}
]]>
Please sign in to leave a comment.
Does file.findReferenceAt(offset) return your reference?
"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:dbrjke$k6k$1@is.intellij.net...
>I am having two more problems with Language API. I hope someone can help me
>with them.
>
>
>
>
>
Yes, it finds PsiReference instances correctly.
In the meantime I have a question about references:
Let's prtend I'm writing Java language editor with language API.
int x = 2;
should "x" be PsiReference to the PsiVariable? How does IDEA know that "x" is the name of the PsiVariable to which PsiReferences resolve?
In my classes, I've implemented getTextOffset() for things which have a name, so in that example it would return "4". This is what the JS plugin does. Should I implement getTextLength() to return 1 in this example? Or is there some special annotation or interface to implement to tell IDEA which element is the name element of a declaration?
Hello Keith,
KL> In the meantime I have a question about references:
KL>
KL> Let's prtend I'm writing Java language editor with language API.
KL>
KL> int x = 2;
KL>
KL> should "x" be PsiReference to the PsiVariable? How does IDEA know
KL> that "x" is the name of the PsiVariable to which PsiReferences
KL> resolve?
No, the "x" must not be a PsiReference in this case. Instead, it must be
a PsiNamedElement, and return "x" from its getName() method.
--
Dmitry Jemerov
Software Developer
JetBrains, Inc.
http://www.jetbrains.com
"Develop with pleasure!"
Dmitry Jemerov (JetBrains) wrote:
Do you mean "x" should be PsiNamedElement, or "int x = 2" should be
PsiNamedElement?
Dmitry Jemerov (JetBrains) wrote:
Okay, I made my definitions implement PsiNamedElement, and now some more
stuff works, like find usages on a reference. However, I still can't
Find Usages on a definition. It says "Cannot search for usages."
Definition may have reference to itself.
Keith Lea wrote:
>> Hello Keith,
>>
>> KL> In the meantime I have a question about references:
>> KL> KL> Let's prtend I'm writing Java language editor with language API.
>> KL> KL> int x = 2;
>> KL> KL> should "x" be PsiReference to the PsiVariable? How does IDEA know
>> KL> that "x" is the name of the PsiVariable to which PsiReferences
>> KL> resolve?
>>
>> No, the "x" must not be a PsiReference in this case. Instead, it must
>> be a PsiNamedElement, and return "x" from its getName() method.
>>
--
Best regards,
Maxim Mossienko
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"
I don't think this is the problem. In JS plugin, JSFunction doesn't even
provide PsiElement child for name, let alone PsiReference to itself. Do
you know why this doesn't work for me? Does Find Usages only use a leaf
PsiElement, or something? When you Ctrl+F7 on my declaration, the cursor
is most definitely also inside a leaf node which is a child of the
actual declaration. Could this be the problem?
Maxim Mossienko wrote:
>> Dmitry Jemerov (JetBrains) wrote:
>>
>>> Hello Keith,
>>>
>>> KL> In the meantime I have a question about references:
>>> KL> KL> Let's prtend I'm writing Java language editor with language API.
>>> KL> KL> int x = 2;
>>> KL> KL> should "x" be PsiReference to the PsiVariable? How does IDEA
>>> know
>>> KL> that "x" is the name of the PsiVariable to which PsiReferences
>>> KL> resolve?
>>>
>>> No, the "x" must not be a PsiReference in this case. Instead, it must
>>> be a PsiNamedElement, and return "x" from its getName() method.
>>>
>>
>> Okay, I made my definitions implement PsiNamedElement, and now some
>> more stuff works, like find usages on a reference. However, I still
>> can't Find Usages on a definition. It says "Cannot search for usages."