package fr.adrienbrault.idea.symfony2plugin.util; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import com.intellij.psi.PsiReferenceBase; import com.intellij.psi.PsiReferenceProvider; import com.intellij.util.ProcessingContext; import com.jetbrains.php.lang.psi.elements.MethodReference; import com.jetbrains.php.lang.psi.elements.ParameterList; import com.jetbrains.php.lang.psi.elements.StringLiteralExpression; import fr.adrienbrault.idea.symfony2plugin.Symfony2InterfacesUtil; import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent; import org.jetbrains.annotations.NotNull; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; /** * @author Daniel Espendiller <daniel@espendiller.net> */ public class PhpStringLiteralExpressionReference extends PsiReferenceProvider { private ArrayList<Call> oneOfCall = new ArrayList<>(); private Class referenceClass; public PhpStringLiteralExpressionReference(Class referenceClass) { this.referenceClass = referenceClass; } public PhpStringLiteralExpressionReference addCall(String className, String methodName) { this.oneOfCall.add(new Call(className, methodName, 0)); return this; } public PhpStringLiteralExpressionReference addCall(String className, String methodName, int index) { this.oneOfCall.add(new Call(className, methodName, index)); return this; } @NotNull @Override public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @NotNull ProcessingContext processingContext) { if (!Symfony2ProjectComponent.isEnabled(psiElement) || !(psiElement.getContext() instanceof ParameterList)) { return new PsiReference[0]; } ParameterList parameterList = (ParameterList) psiElement.getContext(); if (parameterList == null || !(parameterList.getContext() instanceof MethodReference)) { return new PsiReference[0]; } MethodReference method = (MethodReference) parameterList.getContext(); Symfony2InterfacesUtil symfony2InterfacesUtil = new Symfony2InterfacesUtil(); for(Call call: this.oneOfCall) { if (symfony2InterfacesUtil.isCallTo(method, call.getClassName(), call.getMethodName()) && PsiElementUtils.getParameterIndexValue(psiElement) == call.getIndex()) { return this.getPsiReferenceBase(psiElement); } } return new PsiReference[0]; } private PsiReference[] getPsiReferenceBase(PsiElement psiElement) { try { PsiReferenceBase referenceClassInstance = (PsiReferenceBase) this.referenceClass.getDeclaredConstructor(StringLiteralExpression.class).newInstance((StringLiteralExpression) psiElement); return new PsiReference[]{ referenceClassInstance }; } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException ignored) { } return new PsiReference[0]; } private class Call { private String className; private String methodName; private int index = 0; public Call(String className, String methodName) { this.className = className; this.methodName = methodName; } public Call(String className, String methodName, int index) { this(className, methodName); this.index = index; } private int getIndex() { return index; } private String getClassName() { return className; } private String getMethodName() { return methodName; } } }