How can I add a reference to PsiMethod or find usages ?

Answered

Hi, 
I am developing a Intellij Plugin, and I wanna to add a reference from execMethod("hello") to method `hello` so that I can use ctrl-click to hello.

How can I achieve this ?

private void hello(String name) { 
System.out.println("hello, " + name); 
}

public static void main(String[] args) { 
execMethod("hello"); 

I use this, but it can't work. 

registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiMethod.class),
new PsiReferenceProvider() {
@NotNull
@Override
public PsiReference[] getReferencesByElement(
@NotNull PsiElement element, @NotNull ProcessingContext context) {
log.info("element: {}", element);
if (!(element instanceof PsiMethod)) {
return PsiReference.EMPTY_ARRAY;
}
PsiMethod psiMethod = (PsiMethod) element;
String name = psiMethod.getName();
log.info("name: {}", name);

return PsiReference.EMPTY_ARRAY;
}
});

Thanks!

2 comments
Comment actions Permalink

AFAIU you want on install a reference from the parameter String literal "hello" resolving to the method declaration "hello()"? then the pattern to install reference must be installed on PsiLiteral as method parameter. See com.intellij.psi.impl.source.resolve.reference.impl.JavaReflectionReferenceContributor or others in IJ sources as reference.

0
Comment actions Permalink

Thank you Yann Cebron, I've found the way

public class VarReferenceContributor extends PsiReferenceContributor {
@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(PsiJavaPatterns.literalExpression(),
new PsiReferenceProvider() {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
if (element instanceof PsiLiteralExpression) {
PsiLiteralExpression literalExpression = (PsiLiteralExpression) element;
PsiClass psiClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
if (psiClass != null) {
return new PsiReference[]{new MyReference(literalExpression, psiClass)};
}
}
return PsiReference.EMPTY_ARRAY;
}
});
}
}
public class MyReference extends PsiReferenceBase<PsiLiteralExpression> {

private final PsiClass mPsiClass;

public MyReference(@NotNull PsiLiteralExpression element, PsiClass psiClass) {
super(element);
mPsiClass = psiClass;
}

@Nullable
@Override
public PsiElement resolve() {
if (myElement.getValue() instanceof String) {
PsiMethod[] methods = mPsiClass.findMethodsByName((String) myElement.getValue(), false);
return methods.length == 0 ? null : methods[0];
}
return null;
}

@NotNull
@Override
public Object[] getVariants() {
Object[] objects = Arrays.stream(mPsiClass.getMethods())
.map(method -> {
String[] signs = Arrays.stream(method.getParameterList().getParameters())
.map(PsiParameter::getType)
.map(PsiType::getPresentableText)
.toArray(String[]::new);
String sign = StringUtils.join(signs, ", ");
return LookupElementBuilder.create(method)
.withIcon(PlatformIcons.METHOD_ICON)
.withTailText("(" + sign + ")");
})
.toArray();
return objects;
}
}

Register this to open auto-complete popup.

public class MyCompletionConfidence extends CompletionConfidence {

@NotNull
@Override
public ThreeState shouldSkipAutopopup(@NotNull PsiElement contextElement, @NotNull PsiFile psiFile, int offset) {
return ThreeState.NO;
}
}

 

0

Please sign in to leave a comment.