package com.nvlad.yii2support.views.inspections; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiFile; import com.intellij.util.ArrayUtil; import com.jetbrains.php.lang.inspections.PhpInspection; import com.jetbrains.php.lang.psi.PhpFile; import com.jetbrains.php.lang.psi.elements.*; import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; import com.nvlad.yii2support.views.ViewsUtil; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.HashSet; /** * Created by NVlad on 15.01.2017. */ final public class UnusedParameterInspection extends PhpInspection { @NotNull @Override public String getShortName() { return "UnusedParameterInspection"; } @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean isOnTheFly) { return new PhpElementVisitor() { @Override public void visitPhpMethodReference(MethodReference reference) { if (!ViewsUtil.isValidRenderMethod(reference)) { return; } final String name = reference.getName(); if (name == null || !ArrayUtil.contains(name, ViewsUtil.renderMethods)) { return; } final PsiElement[] parameters = reference.getParameters(); if (parameters.length < 2 || !(parameters[0] instanceof StringLiteralExpression)) { return; } final PsiFile file = ViewsUtil.getViewFile(parameters[0]); if (file == null) { return; } if (!(file instanceof PhpFile)) { return; } final ArrayList<String> viewParameters = ViewsUtil.getViewVariables(file); if (viewParameters.size() > 0) { final HashSet<String> unusedParameters = new HashSet<>(); final String errorUnusedParameter = "View %view% not use \"%parameter%\" parameter"; if (parameters[1] instanceof ArrayCreationExpression) { for (ArrayHashElement element : ((ArrayCreationExpression) parameters[1]).getHashElements()) { if (element.getKey() != null && element.getKey() instanceof StringLiteralExpression) { final String key = ((StringLiteralExpression) element.getKey()).getContents(); if (!viewParameters.contains(key)) { UnusedParameterLocalQuickFix fix = new UnusedParameterLocalQuickFix(key); String description = errorUnusedParameter .replace("%view%", parameters[0].getText()) .replace("%parameter%", key); problemsHolder.registerProblem(element, description, ProblemHighlightType.LIKE_UNUSED_SYMBOL, fix); unusedParameters.add(key); } } } } if (parameters[1] instanceof FunctionReference) { FunctionReference function = ((FunctionReference) parameters[1]); if (function.getName() != null && function.getName().contains("compact")) { for (PsiElement element : function.getParameters()) { if (element instanceof StringLiteralExpression) { String key = ((StringLiteralExpression) element).getContents(); if (!viewParameters.contains(key)) { UnusedParameterLocalQuickFix fix = new UnusedParameterLocalQuickFix(key); String description = errorUnusedParameter .replace("%view%", parameters[0].getText()) .replace("%parameter%", key); problemsHolder.registerProblem(element, description, ProblemHighlightType.LIKE_UNUSED_SYMBOL, fix); unusedParameters.add(key); } } } } } if (unusedParameters.size() > 0 && isOnTheFly) { if (viewParameters.containsAll(unusedParameters)) { String errorUnusedParameters = "This View does not use parameters"; UnusedParametersLocalQuickFix fix = new UnusedParametersLocalQuickFix(); problemsHolder.registerProblem(parameters[1], errorUnusedParameters, ProblemHighlightType.LIKE_UNUSED_SYMBOL, fix); problemsHolder.registerProblem(reference, errorUnusedParameters, ProblemHighlightType.INFORMATION, fix); } else { String errorUnusedParameters = "This View have unused parameters"; UnusedParametersLocalQuickFix fix = new UnusedParametersLocalQuickFix(unusedParameters); problemsHolder.registerProblem(reference, errorUnusedParameters, ProblemHighlightType.INFORMATION, fix); } } } else { if (parameters.length > 1) { if (parameters[1] instanceof ArrayCreationExpression || parameters[1] instanceof FunctionReference) { String errorUnusedParameters = "This View does not use parameters"; UnusedParametersLocalQuickFix fix = new UnusedParametersLocalQuickFix(); problemsHolder.registerProblem(parameters[1], errorUnusedParameters, ProblemHighlightType.LIKE_UNUSED_SYMBOL, fix); if (isOnTheFly) { problemsHolder.registerProblem(reference, errorUnusedParameters, ProblemHighlightType.INFORMATION, fix); } } } } } }; } }