mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-21316 (New inspection: suspicious getter/setter (accessing different field than expected))
This commit is contained in:
@@ -1221,6 +1221,10 @@
|
||||
key="property.value.set.to.itself.display.name" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.javabeans.issues" enabledByDefault="false" level="WARNING"
|
||||
implementationClass="com.siyeh.ig.javabeans.PropertyValueSetToItselfInspection"/>
|
||||
<localInspection language="JAVA" shortName="SuspiciousGetterSetter" bundle="com.siyeh.InspectionGadgetsBundle"
|
||||
key="suspicious.getter.setter.display.name" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.javabeans.issues" enabledByDefault="false" level="WARNING"
|
||||
implementationClass="com.siyeh.ig.javabeans.SuspiciousGetterSetterInspection"/>
|
||||
|
||||
<!--group.names.javadoc.issues-->
|
||||
<localInspection language="JAVA" shortName="HtmlTagCanBeJavadocTag" bundle="com.siyeh.InspectionGadgetsBundle"
|
||||
|
||||
+3
@@ -2125,3 +2125,6 @@ parameter.type.prevents.overriding.display.name=Parameter type prevents overridi
|
||||
parameter.type.prevents.overriding.problem.descriptor=Parameter type <code>#ref</code> is located in ''{0}'' while super method parameter type is located in ''{1}'' preventing overriding
|
||||
parameter.type.prevents.overriding.quickfix=Change type of parameter to ''{0}''
|
||||
parameter.type.prevents.overriding.family.quickfix=Change type of parameter
|
||||
suspicious.getter.setter.display.name=Suspicious getter/setter
|
||||
suspicious.setter.problem.descriptor=Setter <code>#ref()</code> assigns field ''{0}''
|
||||
suspicious.getter.problem.descriptor=Getter <code>#ref()</code> returns field ''{0}''
|
||||
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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.javabeans;
|
||||
|
||||
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class SuspiciousGetterSetterInspection extends BaseInspection {
|
||||
|
||||
@SuppressWarnings("PublicField")
|
||||
public boolean onlyWarnWhenFieldPresent = false;
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return InspectionGadgetsBundle.message("suspicious.getter.setter.display.name");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String buildErrorString(Object... infos) {
|
||||
return ((Boolean)infos[0]).booleanValue()
|
||||
? InspectionGadgetsBundle.message("suspicious.setter.problem.descriptor", infos[1])
|
||||
: InspectionGadgetsBundle.message("suspicious.getter.problem.descriptor", infos[1]);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
return new SingleCheckboxOptionsPanel("Only warn when field matching getter/setter name is present", this, "onlyWarnWhenFieldPresent");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseInspectionVisitor buildVisitor() {
|
||||
return new SuspiciousGetterSetterVisitor();
|
||||
}
|
||||
|
||||
private class SuspiciousGetterSetterVisitor extends BaseInspectionVisitor {
|
||||
|
||||
@Override
|
||||
public void visitMethod(PsiMethod method) {
|
||||
super.visitMethod(method);
|
||||
final String name = method.getName();
|
||||
final String fieldName;
|
||||
final boolean setter;
|
||||
final String extractedFieldName;
|
||||
if (nameStartsWith(name, "get")) {
|
||||
final PsiField getterField = PropertyUtil.getFieldOfGetter(method);
|
||||
if (getterField == null) {
|
||||
return;
|
||||
}
|
||||
fieldName = getterField.getName();
|
||||
extractedFieldName = name.substring(3);
|
||||
setter = false;
|
||||
}
|
||||
else if (nameStartsWith(name, "is")) {
|
||||
final PsiField getterField = PropertyUtil.getFieldOfGetter(method);
|
||||
if (getterField == null) {
|
||||
return;
|
||||
}
|
||||
fieldName = getterField.getName();
|
||||
extractedFieldName = name.substring(2);
|
||||
setter = false;
|
||||
}
|
||||
else if (nameStartsWith(name, "set")) {
|
||||
final PsiField setterField = PropertyUtil.getFieldOfSetter(method);
|
||||
if (setterField == null) {
|
||||
return;
|
||||
}
|
||||
fieldName = setterField.getName();
|
||||
extractedFieldName = name.substring(3);
|
||||
setter = true;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(method.getProject());
|
||||
final String computedFieldName = codeStyleManager.propertyNameToVariableName(decapitalize(extractedFieldName), VariableKind.FIELD);
|
||||
if (fieldName.equalsIgnoreCase(computedFieldName)) {
|
||||
return;
|
||||
}
|
||||
if (onlyWarnWhenFieldPresent) {
|
||||
final PsiClass aClass = method.getContainingClass();
|
||||
if (aClass == null) {
|
||||
return;
|
||||
}
|
||||
if (aClass.findFieldByName(computedFieldName, true) == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
registerMethodError(method, Boolean.valueOf(setter), fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean nameStartsWith(String name, String prefix) {
|
||||
return name.startsWith(prefix) && name.length() != prefix.length() && Character.isUpperCase(name.charAt(prefix.length()));
|
||||
}
|
||||
|
||||
private static String decapitalize(String name) {
|
||||
final StringBuilder result = new StringBuilder();
|
||||
for (int i = 0, length = name.length(); i < length; i++) {
|
||||
final char c = name.charAt(i);
|
||||
if (Character.isUpperCase(c)) {
|
||||
result.append(Character.toLowerCase(c));
|
||||
}
|
||||
else {
|
||||
result.append(name.substring(i));
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports suspicious getter or setter methods.
|
||||
A getter or setter is suspicious if it accesses a different field than would be expected by its name.
|
||||
|
||||
<!-- tooltip end -->
|
||||
<p>
|
||||
Use the checkbox below to indicate the inspection should only warn when a field
|
||||
with a name matching the getter or setter name is present in the class.
|
||||
<p>
|
||||
<small>New in 14</small>
|
||||
</body>
|
||||
</html>
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
public class SuspiciousGetterSetter {
|
||||
|
||||
private String myOne;
|
||||
private String myTwo;
|
||||
|
||||
public String <warning descr="Getter 'getTwo()' returns field 'myOne'">getTwo</warning>() {
|
||||
return myOne;
|
||||
}
|
||||
|
||||
public void <warning descr="Setter 'setTwo()' assigns field 'myOne'">setTwo</warning>(String two) {
|
||||
myOne = two;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.javabeans;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class SuspiciousGetterSetterInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
public void testSuspiciousGetterSetter() {
|
||||
final CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(getProject()).getCurrentSettings();
|
||||
final String oldPrefix = settings.FIELD_NAME_PREFIX;
|
||||
try {
|
||||
settings.FIELD_NAME_PREFIX = "my";
|
||||
doTest();
|
||||
} finally {
|
||||
settings.FIELD_NAME_PREFIX = oldPrefix;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
final SuspiciousGetterSetterInspection inspection = new SuspiciousGetterSetterInspection();
|
||||
inspection.onlyWarnWhenFieldPresent = true;
|
||||
return inspection;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user