Functions usages are not found in string literals

In our PHP project we use mechanism in which string literals can be parsed and resolved to function or static method. I wrote a plugin for navigation from literal to source function/method in PHPStorm. I see that `find usages` function use my implementation of PsiReferenceProvider to find usages in sting literals and it works fine for static methods but it doesn't work for functions. I debugged, but I cannot figure out why. Could you please give me a clue why it is so? Is functions some special case?

0
正式评论

Looks like I need some additional information. Could you, please, share your implementation of PsiReferenceProvider? 

My implementation of PsiReferenceProvider:

package com.cocinco.idea;

import com.cocinco.idea.reference.CoCallReference;
import com.cocinco.idea.reference.CoImportReference;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.project.Project;

import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.util.ProcessingContext;
import com.jetbrains.php.lang.psi.elements.ParameterList;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
import org.jetbrains.annotations.NotNull;

public class CoPsiReferenceProvider extends PsiReferenceProvider {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @NotNull ProcessingContext processingContext) {

final Project project = psiElement.getProject();
boolean enabledForProject;
if (project != null) {
PropertiesComponent properties = PropertiesComponent.getInstance(project);
enabledForProject = properties.getBoolean("ENABLE_FOR_PROJECT", false);
} else {
enabledForProject = false;
}
if (!enabledForProject) {
return PsiReference.EMPTY_ARRAY;
}

final PsiElement variableContext = psiElement.getContext();
final String literal = ((StringLiteralExpression) psiElement).getContents();

if (variableContext instanceof ParameterList) {
String funcName = variableContext.getNode().getTreeParent().getFirstChildNode().getText();

if (funcName.equals("co_call") ||
funcName.equals("co_echo_call") ||
funcName.equals("co_ob_call") ||
funcName.equals("co_datex_call") ||
funcName.equals("co_datum_call") ||
funcName.equals("co_datex_merge")
) {
return new PsiReference[]{
new CoCallReference(project, (StringLiteralExpression) psiElement)
};
} else if (
funcName.equals("co_import") ||
funcName.equals("co_import") ||
funcName.equals("co_getpath") ||
funcName.equals("co_file_exists")
) {
return new PsiReference[]{
new CoImportReference(project, (StringLiteralExpression) psiElement)
};
}
} else if (literal.matches("[a-z/:#._]+")) {
if (literal.contains("::") || literal.contains("#")) {
return new PsiReference[]{
new CoCallReference(project, (StringLiteralExpression) psiElement)
};
} else if (literal.contains(".")) {
return new PsiReference[]{
new CoImportReference(project, (StringLiteralExpression) psiElement)
};
}
}

return PsiReference.EMPTY_ARRAY;
}

}
0

PsiReferenceProvider implementation does not matter, - the thing is that debugger does not even step into CoPsiReferenceProvider#getReferencesByElement method when searching function usages!

0

That looks suspicious. Please, try to invalidate caches on a project you testing your code. If no luck please send me your implementation of PsiReferenceContributor

0

Invalidating caches doesn't help. My PhpReferenceContributor#registerReferenceProviders is quite simple:

@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(StandardPatterns.instanceOf(StringLiteralExpression.class), new CoPsiReferenceProvider());
}
0

Still it's unclear for me what's the reason of the problem. Please, if it's possible upload an archive with your plugin to https://uploads.services.jetbrains.com/  and leave a file name in comment

0

The problem might be in word scanner which IDE is using for finding usages.

At first it split all project files into words. Then this word index is used for filtering out the files that can contain usages.
If the string literal's text doesn't match the function name, the file containing your reference can be rejected at this step.

 

 

0

请先登录再写评论。