mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IG: add option to ignore methods which return the type of the enclosing class (IDEA-93333)
for "Chained method calls" inspection
This commit is contained in:
+1
-1
@@ -1292,7 +1292,7 @@ literal.as.arg.to.string.equals.problem.descriptor=Literal <code>#ref</code> is
|
||||
literal.as.arg.to.string.equals.flip.quickfix=Flip ''{0}()''
|
||||
c.style.array.declaration.replace.quickfix=Replace with Java-style array declaration
|
||||
chained.method.call.ignore.option=Ignore chained method calls in field initializers
|
||||
chained.method.call.ignore.this.super.option=Ignore chained method calls in 'this()' and 'super()' calls
|
||||
chained.method.call.ignore.self.types.option=Ignore calls to methods returning the same type as their enclosing class
|
||||
introduce.variable.quickfix=Introduce variable
|
||||
introduce.variable.may.change.semantics.quickfix=Introduce variable (may change semantics)
|
||||
flip.comparison.quickfix=Flip comparison
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2016 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2019 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package com.siyeh.ig.style;
|
||||
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.JavaPsiConstructorUtil;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
@@ -25,6 +26,7 @@ import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.fixes.IntroduceVariableFix;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -32,14 +34,24 @@ import javax.swing.*;
|
||||
public class ChainedMethodCallInspection extends BaseInspection {
|
||||
@SuppressWarnings("PublicField")
|
||||
public boolean m_ignoreFieldInitializations = true;
|
||||
|
||||
@SuppressWarnings({"PublicField", "unused"})
|
||||
public boolean m_ignoreThisSuperCalls = true; // keep for compatibility
|
||||
|
||||
@SuppressWarnings("PublicField")
|
||||
public boolean m_ignoreThisSuperCalls = true;
|
||||
public boolean ignoreSelfTypes = true;
|
||||
|
||||
@Override
|
||||
public void writeSettings(@NotNull Element node) {
|
||||
defaultWriteSettings(node, "ignoreSelfTypes");
|
||||
writeBooleanOption(node, "ignoreSelfTypes", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
final MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this);
|
||||
panel.addCheckbox(InspectionGadgetsBundle.message("chained.method.call.ignore.option"), "m_ignoreFieldInitializations");
|
||||
panel.addCheckbox(InspectionGadgetsBundle.message("chained.method.call.ignore.this.super.option"), "m_ignoreThisSuperCalls");
|
||||
panel.addCheckbox(InspectionGadgetsBundle.message("chained.method.call.ignore.self.types.option"), "ignoreSelfTypes");
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -76,11 +88,11 @@ public class ChainedMethodCallInspection extends BaseInspection {
|
||||
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
|
||||
super.visitMethodCallExpression(expression);
|
||||
final PsiReferenceExpression reference = expression.getMethodExpression();
|
||||
final PsiExpression qualifier = reference.getQualifierExpression();
|
||||
final PsiExpression qualifier = ParenthesesUtils.stripParentheses(reference.getQualifierExpression());
|
||||
if (qualifier == null) {
|
||||
return;
|
||||
}
|
||||
if (!isCallExpression(qualifier)) {
|
||||
if (!(qualifier instanceof PsiCallExpression)) {
|
||||
return;
|
||||
}
|
||||
if (m_ignoreFieldInitializations) {
|
||||
@@ -89,21 +101,35 @@ public class ChainedMethodCallInspection extends BaseInspection {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (m_ignoreThisSuperCalls) {
|
||||
final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(expression, PsiExpressionList.class);
|
||||
if (expressionList != null) {
|
||||
final PsiElement parent = expressionList.getParent();
|
||||
if (JavaPsiConstructorUtil.isConstructorCall(parent)) {
|
||||
final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(expression, PsiExpressionList.class);
|
||||
if (expressionList != null) {
|
||||
final PsiElement parent = expressionList.getParent();
|
||||
if (JavaPsiConstructorUtil.isConstructorCall(parent)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ignoreSelfTypes) {
|
||||
if (qualifier instanceof PsiMethodCallExpression) {
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)qualifier;
|
||||
final PsiMethod qualifierMethod = methodCallExpression.resolveMethod();
|
||||
if (qualifierMethod == null) {
|
||||
return;
|
||||
}
|
||||
PsiClass containingClass = qualifierMethod.getContainingClass();
|
||||
PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(qualifierMethod.getReturnType());
|
||||
if (containingClass == null || containingClass.equals(aClass)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiClass callClass = PsiUtil.resolveClassInClassTypeOnly(expression.getType());
|
||||
PsiClass qualifierClass = PsiUtil.resolveClassInClassTypeOnly(qualifier.getType());
|
||||
if (qualifierClass == null || qualifierClass.equals(callClass)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
registerMethodCallError(expression);
|
||||
}
|
||||
|
||||
private boolean isCallExpression(PsiExpression expression) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
return expression instanceof PsiMethodCallExpression || expression instanceof PsiNewExpression;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.siyeh.igtest.bugs;
|
||||
|
||||
public class ChainedMethodInspection{
|
||||
private ChainedMethodInspection baz = foo().bar();
|
||||
public void baz(){
|
||||
foo().bar();
|
||||
(foo()).bar();
|
||||
}
|
||||
|
||||
public ChainedMethodInspection foo()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChainedMethodInspection bar()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.siyeh.igtest.bugs;
|
||||
|
||||
public class ChainedMethodCall {
|
||||
private X baz = new X().foo().bar();
|
||||
public void baz(){
|
||||
new X().<warning descr="Chained method call 'foo()'">foo</warning>().<warning descr="Chained method call 'bar()'">bar</warning>();
|
||||
(new X().<warning descr="Chained method call 'foo()'">foo</warning>()).<warning descr="Chained method call 'bar()'">bar</warning>();
|
||||
String s = new StringBuilder().append("x: ").append(new X()).append("y: ").append(new Y()).toString();
|
||||
}
|
||||
|
||||
class X {
|
||||
public Y foo() {
|
||||
return new Y();
|
||||
}
|
||||
}
|
||||
|
||||
class Y {
|
||||
public X bar() {
|
||||
return new X();
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.siyeh.ig.style;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class ChainedMethodCallInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
public void testChainedMethodCall() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new ChainedMethodCallInspection();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user