package com.nvlad.yii2support.database; import com.intellij.codeInsight.template.Template; import com.intellij.codeInsight.template.TemplateManager; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.jetbrains.php.lang.psi.elements.*; import com.nvlad.yii2support.common.ClassUtils; import com.nvlad.yii2support.common.DatabaseUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; /** * Created by oleg on 31.03.2017. */ public class MissedParamQuickFix implements LocalQuickFix { MethodReference methodReference; public MissedParamQuickFix(MethodReference methodRef ) { methodReference = methodRef; } @Nls @NotNull @Override public String getFamilyName() { return "Conform parameters to condition"; } @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor problemDescriptor) { Method method = (Method)methodReference.resolve(); if (method != null) { Parameter[] parameters = method.getParameters(); int paramParameterIndex = ClassUtils.getParamIndex(method, "params"); int conditionParameterIndex = ClassUtils.getParamIndex(method, new String[]{ "condition", "expression", "sql"}); if (paramParameterIndex > -1 && conditionParameterIndex > -1 && conditionParameterIndex == paramParameterIndex - 1 && methodReference.getParameters().length > conditionParameterIndex) { String condition = methodReference.getParameters()[conditionParameterIndex].getText(); String[] conditionParams = DatabaseUtils.extractParamsFromCondition(condition); ArrayCreationExpression array = null; if (methodReference.getParameters().length > paramParameterIndex) { PsiElement paramParameter = methodReference.getParameters()[paramParameterIndex]; if (paramParameter instanceof ArrayCreationExpression) array = (ArrayCreationExpression)paramParameter; paramParameter.delete(); } TemplateManager templateManager = TemplateManager.getInstance(project); Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); if (editor == null || methodReference.getParameterList() == null) return; editor.getCaretModel().moveToOffset(methodReference.getParameterList().getLastChild().getTextRange().getEndOffset()); PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); Template template = templateManager.createTemplate("", ""); template.setToReformat(true); buildParamArray(template, conditionParams, array, conditionParameterIndex); PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); templateManager.startTemplate(editor, template); } } } private Template buildParamArray(Template template, String[] conditionParams, ArrayCreationExpression array, int conditionParameterIndex) { if (methodReference.getParameterList() != null && (methodReference.getParameterList().getParameters()[conditionParameterIndex].getNextSibling() == null || ! methodReference.getParameterList().getParameters()[conditionParameterIndex].getNextSibling().getText().equals(","))) template.addTextSegment(", "); template.addTextSegment("["); String separator = " "; if (conditionParams.length > 1) separator = "\n"; Boolean addComma = false; for (String variable : conditionParams) { if (addComma) { template.addTextSegment(","); } template.addTextSegment(separator); String templateVariable = "$" + variable.toUpperCase() + "$"; // template.addVariable(templateVariable, "", "'variable'", true); String value = getArrayValueByHash(variable, array); //if (value != null) // template.addVariable("test", value, true); String valueStr = value == null ? "''" : value; template.addTextSegment("'" + variable + "' => " + valueStr); // template.addVariableSegment(templateVariable); addComma = true; } template.addTextSegment(separator + "]"); return template; } private String getArrayValueByHash(String hash, ArrayCreationExpression array) { if (array == null) return null; for (ArrayHashElement el: array.getHashElements()) { PsiElement key = el.getKey(); PsiElement value = el.getValue(); if (key != null && value != null && ClassUtils.removeQuotes(key.getText()).equals(hash)) { return value.getText(); } } return null; } }