package fr.adrienbrault.idea.symfony2plugin.codeInspection.form;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.openapi.project.Project;
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.psi.elements.MethodReference;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
import fr.adrienbrault.idea.symfony2plugin.form.util.FormUtil;
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
import fr.adrienbrault.idea.symfony2plugin.util.SymfonyUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
/**
* @author Daniel Espendiller <daniel@espendiller.net>
*/
public class FormTypeAsClassConstantInspection extends LocalInspectionTool {
public static String MESSAGE = "Use fully-qualified class name (FQCN)";
@NotNull
public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, boolean isOnTheFly) {
if(!Symfony2ProjectComponent.isEnabled(holder.getProject()) || !SymfonyUtil.isVersionGreaterThenEquals(holder.getProject(), "2.8")) {
return super.buildVisitor(holder, isOnTheFly);
}
return new MyPsiElementVisitor(holder);
}
private static class MyPsiElementVisitor extends PsiElementVisitor {
private final ProblemsHolder holder;
MyPsiElementVisitor(ProblemsHolder holder) {
this.holder = holder;
}
@Override
public void visitElement(PsiElement element) {
if(!(element instanceof MethodReference) ||
!ArrayUtil.contains(((MethodReference) element).getName(), "add", "create") ||
!PhpElementsUtil.isMethodReferenceInstanceOf((MethodReference) element, "Symfony\\Component\\Form\\FormBuilderInterface")
) {
super.visitElement(element);
return;
}
PsiElement[] parameters = ((MethodReference) element).getParameters();
if(parameters.length < 2) {
super.visitElement(element);
return;
}
if(!(parameters[1] instanceof StringLiteralExpression) || ((StringLiteralExpression) parameters[1]).getContents().contains("\\")) {
super.visitElement(element);
return;
}
holder.registerProblem(
parameters[1],
MESSAGE,
ProblemHighlightType.WEAK_WARNING, new MyLocalQuickFix(parameters[1])
);
super.visitElement(element);
}
private static class MyLocalQuickFix extends LocalQuickFixOnPsiElement {
MyLocalQuickFix(@NotNull PsiElement element) {
super(element);
}
@NotNull
@Override
public String getText() {
return "Use class constant";
}
@Nls
@NotNull
@Override
public String getFamilyName() {
return "Class constant";
}
@Override
public void invoke(@NotNull Project project, @NotNull PsiFile psiFile, @NotNull PsiElement psiElement, @NotNull PsiElement psiElement1) {
if(!(getStartElement() instanceof StringLiteralExpression)) {
return;
}
try {
FormUtil.replaceFormStringAliasWithClassConstant((StringLiteralExpression) getStartElement());
} catch (Exception ignored) {
}
}
}
}
}