IDEA-94922 (Report negatively named boolean variables and suggest to perform 'Invert Boolean' for them)

This commit is contained in:
Bas Leijdekkers
2013-11-07 20:45:46 +01:00
parent f637ac6729
commit fe23143c0b
6 changed files with 160 additions and 0 deletions
@@ -760,6 +760,10 @@
<localInspection language="JAVA" shortName="LawOfDemeter" bundle="com.siyeh.InspectionGadgetsBundle" key="law.of.demeter.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.data.flow.issues" enabledByDefault="false"
level="WARNING" implementationClass="com.siyeh.ig.dataflow.LawOfDemeterInspection"/>
<localInspection language="JAVA" shortName="NegativelyNamedBooleanVariable" bundle="com.siyeh.InspectionGadgetsBundle"
key="negatively.named.boolean.variable.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.data.flow.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.dataflow.NegativelyNamedBooleanVariableInspection"/>
<localInspection language="JAVA" shortName="OrredNotEqualExpression" bundle="com.siyeh.InspectionGadgetsBundle"
key="orred.not.equal.expression.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.data.flow.issues" enabledByDefault="true" level="WARNING"
@@ -2059,6 +2059,8 @@ problematic.whitespace.spaces.problem.descriptor=File ''{0}'' uses spaces for in
problematic.whitespace.show.whitespaces.quickfix=Toggle show whitespace in the editor
problematic.varargs.method.display.name=Non-varargs method overrides varargs method
problematic.varargs.method.override.problem.descriptor=Non-varargs method <code>#ref()</code> overrides varargs method #loc
negatively.named.boolean.variable.problem.descriptor=Boolean variable <code>#ref</code> is negatively named #loc
negatively.named.boolean.variable.display.name=Negatively named boolean variable
invert.quickfix.family.name=Invert boolean
invert.method.quickfix=Invert method
invert.quickfix=Invert ''{0}''
@@ -0,0 +1,72 @@
/*
* Copyright 2000-2013 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.dataflow;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiVariable;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* @author Bas Leijdekkers
*/
public class NegativelyNamedBooleanVariableInspectionBase extends BaseInspection {
@NonNls
private static final String[] NEGATIVE_NAMES = {"not", "isNot", "shouldNot", "shallNot", "willNot", "cannot", "cant", "hasNot",
"couldNot", "hidden", "isHidden", "disabled", "isDisabled"};
@Nls
@NotNull
@Override
public String getDisplayName() {
return InspectionGadgetsBundle.message("negatively.named.boolean.variable.display.name");
}
@NotNull
@Override
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message("negatively.named.boolean.variable.problem.descriptor");
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new NegativelyNamedBooleanVariableVisitor();
}
private static class NegativelyNamedBooleanVariableVisitor extends BaseInspectionVisitor {
@Override
public void visitVariable(PsiVariable variable) {
super.visitVariable(variable);
if (!PsiType.BOOLEAN.equals(variable.getType())) {
return;
}
final String name = variable.getName();
for (final String negativeName : NEGATIVE_NAMES) {
if (name.startsWith(negativeName) &&
(name.length() == negativeName.length() || Character.isUpperCase(name.charAt(negativeName.length())))) {
registerVariableError(variable, variable);
break;
}
}
}
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2000-2013 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.dataflow;
import com.intellij.psi.PsiVariable;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.InvertBooleanFix;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class NegativelyNamedBooleanVariableInspection extends NegativelyNamedBooleanVariableInspectionBase {
@Nullable
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
final PsiVariable variable = (PsiVariable)infos[0];
return new InvertBooleanFix(InspectionGadgetsBundle.message("invert.quickfix", variable.getName()));
}
}
@@ -0,0 +1,9 @@
<html>
<body>
Reports negatively named variables, for example 'disabled', 'hidden', 'isNotChanged'.
It is usually more clear to invert the <b>boolean</b> value and remove the negation from the name.
<!-- tooltip end -->
<p>
<small>New in 13</small>
</body>
</html>
@@ -0,0 +1,38 @@
/*
* Copyright 2000-2013 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.dataflow;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
/**
* @author Bas Leijdekkers
*/
public class NegativelyNamedBooleanVariableInspectionTest extends LightInspectionTestCase {
public void testTree() {
doTest("class X {" +
" boolean /*Boolean variable 'hidden' is negatively named*/hidden/**/ = false;" +
" boolean /*Boolean variable 'disabled' is negatively named*/disabled/**/ = false;" +
" boolean /*Boolean variable 'isNotChanged' is negatively named*/isNotChanged/**/ = false;" +
"}");
}
@Override
protected InspectionProfileEntry getInspection() {
return new NegativelyNamedBooleanVariableInspection();
}
}