PsiFileReference for custom java literal

已回答

I need to open custom file from specified folder after "go to declaration" on java String. I've created PsiReferenceContributor, which registers array of PsiReference (which return single PsiFile as getVariants(), resolve(), etc.), but I still get "cannot find declaration to go" message. There are no examples in documentation related with opening files from "go to".

0

Please show your code

0
Avatar
Permanently deleted user
test code:

public class QueryReferenceContributor extends PsiReferenceContributor {
@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {

registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression.class),
new PsiReferenceProvider() {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element,
@NotNull ProcessingContext
context) {
PsiLiteralExpression literalExpression = (PsiLiteralExpression) element;
String value = literalExpression.getValue() instanceof String ?
(String) literalExpression.getValue() : null;
if (value != null) {
PsiReference[] references = Stream.of(FilenameIndex.getFilesByName(element.getProject(), value + ".query", GlobalSearchScope.allScope(element.getProject())))
.map(PsiElement::getReference).toArray(PsiReference[]::new);
return references;
}
return PsiReference.EMPTY_ARRAY;
}

@Override
public boolean acceptsTarget(@NotNull PsiElement target) {
return super.acceptsTarget(target);
}
});
}
}


and class that extends PsiFileImpl:

@Override
public PsiReference getReference() {
new FileReference(new FileReferenceSet("something", QueryFileElement.this, 0, null, true), TextRange.EMPTY_RANGE, 0, "azaz"){
@Override
public String getText() {
return super.getText() + ".query";
}
}
0

Why does your PsiFileImpl try to return references?

 

QueryReferenceContributor looks like good approach, but simply use FileReferenceSet there and return all references instead of "Stream.of..." expression

0
Avatar
Permanently deleted user

ok, I return single FileReference with FileReferenceSet, but still "cannot find declaration to go"

return Stream.of(FilenameIndex.getFilesByName(element.getProject(), value + ".query", GlobalSearchScope.allScope(element.getProject())))
.map(file -> new FileReference(new FileReferenceSet(value, file, 0, null, true), TextRange.EMPTY_RANGE, 0, value))
.toArray(PsiReference[]::new);

0

You must return com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet#getAllReferences, remove everything with Stream.... around it

0
Avatar
Permanently deleted user

Still isn't working

PsiElement[] files = FilenameIndex.getFilesByName(element.getProject(), value + ".query", GlobalSearchScope.allScope(element.getProject()));
return new FileReferenceSet(value, files[0], 0, null, true).getAllReferences();
0

2nd parameter in FileReferenceSet must be the PsiElement for which references are provided, not the files[0] . Please look at existing usages of FileReferenceSet in IntelliJ Community sources for further details on customizing

0
Avatar
Permanently deleted user

So how FileReferenceSet has to know what files to open? There are no constructor parameters for this. "String str"? No. "PsiReferenceProvider provider"? Well, you told me not to create FileReferences manually.

0

It will resolve to all files which match the limitations set in FileReferenceSet - it can be customized to some degree. if you want to hardcode resolve target to specific file, you can simply return com.intellij.psi.PsiReferenceBase.Immediate and pass file in "resolveTo" parameter

0
Avatar
Permanently deleted user

It returns one FileReference, but it just ignored somewhere else

0
Avatar
Permanently deleted user

And even when it finds file by name - same situation.

0

Sorry I don't understand what the exact problem is. Please post/link updated code of what you're trying now

0
Avatar
Permanently deleted user
public class QueryReferenceContributor extends PsiReferenceContributor {
@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {

registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression.class),
new PsiReferenceProvider() {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element,
@NotNull ProcessingContext
context) {
PsiLiteralExpression literalExpression = (PsiLiteralExpression) element;
String value = literalExpression.getValue() instanceof String ?
(String) literalExpression.getValue() : null;
if (value != null) {
return new FileReferenceSet(value, element, 0, this, false).getAllReferences();
}
return PsiReference.EMPTY_ARRAY;
}
});
}
}

FileReferenceSet returns single FileReference which provides to file with name from "value", but IDE still shows message "cannot find declaration to go". Why?

0

passing '0' as "startinElement" is most probably wrong (at least for Java String literal). Try passing in com.intellij.psi.ElementManipulators#getOffsetInElement for given literalExpression.

0
Avatar
Permanently deleted user
return new FileReferenceSet(value, element, ElementManipulators.getOffsetInElement(element), this, false).getAllReferences();

 

ElementManipulators.getOffsetInElement(element)

for my literal returns 1. Still not working

 

0

Please share your full plugin's sources and test project that doesn't work as expected

0

请先登录再写评论。