/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.codeInspection.expression; import com.intellij.codeInspection.LocalInspectionToolSession; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.codeInspection.ex.BaseLocalInspectionTool; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiFile; import gw.lang.parser.IExpression; import gw.lang.parser.exceptions.IWarningSuppressor; import gw.lang.parser.expressions.IBeanMethodCallExpression; import gw.lang.reflect.IFunctionType; import gw.lang.reflect.IType; import gw.lang.reflect.java.JavaTypes; import gw.plugin.ij.intentions.ObjectEqualsAsOpFix; import gw.plugin.ij.lang.psi.impl.GosuElementVisitor; import gw.plugin.ij.lang.psi.impl.expressions.GosuBeanMethodCallExpressionImpl; import gw.plugin.ij.util.GosuBundle; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; public class GosuObjectEqualsInspection extends BaseLocalInspectionTool implements IWarningSuppressor { public static final String SUPPRESS_WARNING_CODE = "EqualsMethodToOperator"; @Nls @NotNull @Override public String getGroupDisplayName() { return GosuBundle.message("inspection.group.name.expression.issues"); } @Nls @NotNull @Override public String getDisplayName() { return GosuBundle.message("inspection.object.equals.as.op"); } @NotNull @Override public String getShortName() { return "GosuObjectEqualsInspection"; } @Override public boolean isEnabledByDefault() { return true; } @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session) { return new GosuElementVisitor() { @Override public void visitBeanMethodCallExpression(GosuBeanMethodCallExpressionImpl callExpression) { IBeanMethodCallExpression parsedElement = callExpression.getParsedElement(); if(parsedElement == null) { return; } if( parsedElement.isSuppressed( GosuObjectEqualsInspection.this ) ) { return; } IFunctionType functionType = parsedElement.getFunctionType(); if(functionType == null) { return; } IType[] parameterTypes = functionType.getParameterTypes(); String displayName = functionType.getDisplayName(); if(displayName != null && parameterTypes != null && displayName.equals("equals") && functionType.getReturnType() == JavaTypes.pBOOLEAN() && parameterTypes.length == 1 && parameterTypes[0] == JavaTypes.OBJECT()) { IExpression[] args = parsedElement.getArgs(); IType rootType = parsedElement.getRootType(); if(args != null && args.length == 1 && args[0].getType() == rootType) { holder.registerProblem(callExpression, GosuBundle.message("inspection.object.equals.as.op"), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new GosuObjectEqualsInspectionFix(callExpression)); } } } }; } @Override public boolean isSuppressed( String warningCode ) { return SUPPRESS_WARNING_CODE.equals( warningCode ) || "all".equals( warningCode ); } private class GosuObjectEqualsInspectionFix implements LocalQuickFix { private final ObjectEqualsAsOpFix myQuickFix; public GosuObjectEqualsInspectionFix(GosuBeanMethodCallExpressionImpl callExpression) { myQuickFix = new ObjectEqualsAsOpFix(callExpression); } @NotNull public String getName() { return myQuickFix.getText(); } @NotNull public String getFamilyName() { return GosuBundle.message("inspection.group.name.expression.issues"); } public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { PsiElement element = descriptor.getPsiElement(); if (element == null) return; final PsiFile psiFile = element.getContainingFile(); if (myQuickFix.isAvailable(project, null, psiFile)) { myQuickFix.invoke(project, null, psiFile); } } } }