diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml index dddb6e1d3988..eca27bdaf661 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml @@ -2640,6 +2640,10 @@ bundle="com.siyeh.InspectionGadgetsBundle" key="parameter.hides.member.variable.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.visibility.issues" enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.visibility.ParameterHidingMemberVariableInspection"/> + diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index 7f61b374c9a9..feb3c083ed25 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -2066,3 +2066,6 @@ implicit.default.charset.usage.constructor.problem.descriptor=new #ref()#ref may be annotated with @FunctionalInterface only.report.public.methods.option=Only report 'public' methods +lambda.parameter.hides.member.variable.display.name=Lambda parameter hides field +lambda.parameter.hides.member.variable.problem.descriptor=Lambda parameter #ref hides field in class ''{0}'' #loc + diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionBase.java new file mode 100644 index 000000000000..5b245eccc0a0 --- /dev/null +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionBase.java @@ -0,0 +1,110 @@ +/* + * Copyright 2003-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.visibility; + +import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; +import com.intellij.psi.*; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.psiutils.ClassUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class LambdaParameterHidingMemberVariableInspectionBase extends BaseInspection { + + @SuppressWarnings("PublicField") + public boolean m_ignoreInvisibleFields = true; + + @Override + @NotNull + public String getID() { + return "LambdaParameterHidesMemberVariable"; + } + + @Override + @NotNull + public String getDisplayName() { + return InspectionGadgetsBundle.message("lambda.parameter.hides.member.variable.display.name"); + } + + @Override + protected boolean buildQuickFixesOnlyForOnTheFlyErrors() { + return true; + } + + @Override + @NotNull + public String buildErrorString(Object... infos) { + final PsiClass aClass = (PsiClass)infos[0]; + return InspectionGadgetsBundle.message("lambda.parameter.hides.member.variable.problem.descriptor", aClass.getName()); + } + + @Override + public JComponent createOptionsPanel() { + final MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this); + optionsPanel.addCheckbox(InspectionGadgetsBundle.message("parameter.hides.member.variable.ignore.superclass.option"), + "m_ignoreInvisibleFields"); + return optionsPanel; + } + + @Override + public BaseInspectionVisitor buildVisitor() { + return new LambdaParameterHidingMemberVariableVisitor(); + } + + private class LambdaParameterHidingMemberVariableVisitor extends BaseInspectionVisitor { + + @Override + public void visitParameter(@NotNull PsiParameter variable) { + super.visitParameter(variable); + final PsiElement declarationScope = variable.getDeclarationScope(); + if (!(declarationScope instanceof PsiLambdaExpression)) { + return; + } + final PsiClass aClass = checkFieldName(variable); + if (aClass == null) { + return; + } + registerVariableError(variable, aClass); + } + + @Nullable + private PsiClass checkFieldName(PsiVariable variable) { + final String variableName = variable.getName(); + if (variableName == null) { + return null; + } + PsiClass aClass = ClassUtils.getContainingClass(variable); + while (aClass != null) { + final PsiField[] fields = aClass.getAllFields(); + for (PsiField field : fields) { + final String fieldName = field.getName(); + if (!variableName.equals(fieldName)) { + continue; + } + if (!m_ignoreInvisibleFields || ClassUtils.isFieldVisible(field, aClass)) { + return aClass; + } + } + aClass = ClassUtils.getContainingClass(aClass); + } + return null; + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspection.java new file mode 100644 index 000000000000..4112dfe911da --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspection.java @@ -0,0 +1,26 @@ +/* + * Copyright 2003-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.visibility; + +import com.siyeh.ig.InspectionGadgetsFix; +import com.siyeh.ig.fixes.RenameFix; + +public class LambdaParameterHidingMemberVariableInspection extends LambdaParameterHidingMemberVariableInspectionBase { + @Override + protected InspectionGadgetsFix buildFix(Object... infos) { + return new RenameFix(); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LambdaParameterHidingMemberVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LambdaParameterHidingMemberVariable.html new file mode 100644 index 000000000000..3817e402e632 --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LambdaParameterHidingMemberVariable.html @@ -0,0 +1,11 @@ + + +Reports lambda parameters named identically to visible fields of the surrounding classes +and their superclasses. + +

+Use the checkbox below to ignore fields that are not actually visible from the lambda expression, for example private fields +

+New in 13.1 + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionTest.java new file mode 100644 index 000000000000..e7c3b75f1a6d --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.visibility; + +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; + +/** + * @author Bas Leijdekkers + */ +public class LambdaParameterHidingMemberVariableInspectionTest extends LightInspectionTestCase { + @Override + protected InspectionProfileEntry getInspection() { + return new LambdaParameterHidingMemberVariableInspection(); + } + + @Override + protected String[] getEnvironmentClasses() { + return new String[] {"package java.util.function;" + + "public interface Function {" + + " R apply(T t);" + + "}"}; + } + + public void testSimple() { + doTest("import java.util.function.Function;" + + "class X {" + + " private String s;" + + "" + + " void m() {" + + " Function f = (/*Lambda parameter 's' hides field in class 'X'*/s/**/) -> null;" + + " }" + + "}"); + } +}