package com.nvlad.yii2support.database;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.jetbrains.php.lang.inspections.PhpInspection;
import com.jetbrains.php.lang.psi.elements.*;
import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor;
import com.nvlad.yii2support.common.ClassUtils;
import com.nvlad.yii2support.common.DatabaseUtils;
import org.jetbrains.annotations.NotNull;
import java.util.*;
/**
* Created by oleg on 30.03.2017.
*/
public class MissedParamInspection extends PhpInspection {
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean isOnTheFly) {
return new PhpElementVisitor() {
@Override
public void visitPhpMethodReference(MethodReference reference) {
if (reference != null && reference.getParameters().length > 0) {
Method method = (Method) reference.resolve();
if (method == null)
return;
int paramParameterIndex = ClassUtils.getParamIndex(method, "params");
int conditionParameterIndex = ClassUtils.getParamIndex(method, new String[]{ "condition", "expression", "sql"});
if (paramParameterIndex > -1 && conditionParameterIndex > -1 && reference.getParameters().length > conditionParameterIndex &&
conditionParameterIndex == paramParameterIndex - 1) {
PsiElement element = reference.getParameters()[conditionParameterIndex];
String condition = ClassUtils.getStringByElement(element);
String[] conditionParams = DatabaseUtils.extractParamsFromCondition(condition);
String[] conditionParamsWithoutColon = DatabaseUtils.extractParamsFromCondition(condition, false);
if (conditionParams.length > 0) {
if (reference.getParameters().length > paramParameterIndex) {
PsiElement paramParam = reference.getParameters()[paramParameterIndex];
if (paramParam instanceof ArrayCreationExpression) {
ArrayCreationExpression array = (ArrayCreationExpression) paramParam;
ArrayList<String> paramString = new ArrayList<>();
for (ArrayHashElement elem : array.getHashElements()) {
if (elem.getKey() != null && elem.getKey().getText() != null)
paramString.add(ClassUtils.removeQuotes(elem.getKey().getText()).trim());
}
if (!Arrays.equals(paramString.toArray(), conditionParams) && !Arrays.equals(paramString.toArray(), conditionParamsWithoutColon)) {
MissedParamQuickFix qFix = new MissedParamQuickFix(reference);
problemsHolder.registerProblem(reference.getParameters()[paramParameterIndex], "Condition parameters do not conform to the condition", qFix);
}
}
} else {
MissedParamQuickFix qFix = new MissedParamQuickFix(reference);
problemsHolder.registerProblem(reference.getParameters()[conditionParameterIndex], "Condition parameters must be defined", qFix);
}
}
}
}
super.visitPhpMethodReference(reference);
}
/*
@Override
public void visitPhpArrayCreationExpression(ArrayCreationExpression expression) {
MethodReference methodRef = ClassUtils.getMethodRef(expression, 10);
if (methodRef != null) {
Method method = (Method) methodRef.resolve();
if (method == null)
return;
int paramPosition = ClassUtils.indexForElementInParameterList(expression);
if (paramPosition > 0 && method.getParameters().length > paramPosition) {
if (method.getParameters()[paramPosition].getName().equals("params") &&
(method.getParameters()[paramPosition - 1].getName().equals("condition") ||
method.getParameters()[paramPosition - 1].getName().equals("expression"))) {
PsiElement element = methodRef.getParameters()[paramPosition - 1];
if (element instanceof StringLiteralExpression) {
String condition = ((StringLiteralExpression) element).getContents();
String[] conditionParams = DatabaseUtils.extractParamsFromCondition(condition);
List<ArrayHashElement> hashElements = Lists.newArrayList(expression.getHashElements());
String[] params = new String[hashElements.size()];
for (int i = 0; i < hashElements.size(); i++) {
PsiElement key = hashElements.get(i).getKey();
if (key != null)
params[i] = ClassUtils.removeQuotes(key.getText());
}
if (!Arrays.equals(conditionParams, params)) {
MissedParamQuickFix qFix = new MissedParamQuickFix(methodRef);
String problemDesc = "Parameters do not correspond to the condition";
if (params.length == 1)
problemDesc = "Parameter does not correspond to the condition";
problemsHolder.registerProblem(expression, problemDesc, qFix);
}
}
}
}
}
super.visitPhpArrayCreationExpression(expression);
} */
};
}
}