Issue #2362: Add 'validateOnlyOverlapping' option for RequireThisCheck

This commit is contained in:
Andrei Selkin 2016-03-03 21:11:38 +03:00 committed by Roman Ivanov
parent 0fd3dd6fa4
commit d274db7b32
7 changed files with 1755 additions and 140 deletions

View File

@ -228,15 +228,7 @@
<module name="OverloadMethodsDeclarationOrder"/>
<module name="PackageDeclaration"/>
<module name="ParameterAssignment"/>
<module name="RequireThis">
<!--
till https://github.com/checkstyle/checkstyle/issues/2362
we will not use that fanatic validation, extra modifiers pollute a code
it is better to use different names for arguments, or expect IDE to highlight field.
But this Check will exists as it was created by community demand.
-->
<property name="severity" value="ignore"/>
</module>
<module name="RequireThis"/>
<module name="ReturnCount"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>

View File

@ -54,7 +54,7 @@
<properties>
<!-- *TokenTypes are special classes that a big due to a lot of description comments -->
<!-- JavadocMethodCheck is deprecated class, till it is redone to use JavadocAst -->
<property name="violationSuppressXPath" value="//ClassOrInterfaceDeclaration[@Image='JavadocTokenTypes' or @Image='TokenTypes' or @Image='JavadocMethodCheck']"/>
<property name="violationSuppressXPath" value="//ClassOrInterfaceDeclaration[@Image='JavadocTokenTypes' or @Image='TokenTypes' or @Image='JavadocMethodCheck' or @Image='RequireThisCheck']"/>
</properties>
</rule>
<rule ref="rulesets/java/codesize.xml/ExcessiveMethodLength">

View File

@ -30,7 +30,6 @@ import org.junit.Assert;
import org.junit.Test;
import antlr.CommonHiddenStreamToken;
import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
@ -47,12 +46,14 @@ public class RequireThisCheckTest extends BaseCheckTestSupport {
public void testIt() throws Exception {
final DefaultConfiguration checkConfig =
createCheckConfig(RequireThisCheck.class);
checkConfig.addAttribute("validateOnlyOverlapping", "false");
final String[] expected = {
"11:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
"17:9: " + getCheckMessage(MSG_METHOD, "method1", ""),
"31:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
"49:13: " + getCheckMessage(MSG_VARIABLE, "z", ""),
"56:9: " + getCheckMessage(MSG_VARIABLE, "z", ""),
"86:16: " + getCheckMessage(MSG_VARIABLE, "CONST", ""),
"113:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
"114:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
"115:9: " + getCheckMessage(MSG_METHOD, "instanceMethod", ""),
@ -70,6 +71,7 @@ public class RequireThisCheckTest extends BaseCheckTestSupport {
final DefaultConfiguration checkConfig =
createCheckConfig(RequireThisCheck.class);
checkConfig.addAttribute("checkFields", "false");
checkConfig.addAttribute("validateOnlyOverlapping", "false");
final String[] expected = {
"17:9: " + getCheckMessage(MSG_METHOD, "method1", ""),
"115:9: " + getCheckMessage(MSG_METHOD, "instanceMethod", ""),
@ -86,11 +88,13 @@ public class RequireThisCheckTest extends BaseCheckTestSupport {
final DefaultConfiguration checkConfig =
createCheckConfig(RequireThisCheck.class);
checkConfig.addAttribute("checkMethods", "false");
checkConfig.addAttribute("validateOnlyOverlapping", "false");
final String[] expected = {
"11:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
"31:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
"49:13: " + getCheckMessage(MSG_VARIABLE, "z", ""),
"56:9: " + getCheckMessage(MSG_VARIABLE, "z", ""),
"86:16: " + getCheckMessage(MSG_VARIABLE, "CONST", ""),
"113:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
"114:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
"122:13: " + getCheckMessage(MSG_VARIABLE, "i", "Issue2240."),
@ -104,6 +108,7 @@ public class RequireThisCheckTest extends BaseCheckTestSupport {
public void testGenerics() throws Exception {
final DefaultConfiguration checkConfig =
createCheckConfig(RequireThisCheck.class);
checkConfig.addAttribute("validateOnlyOverlapping", "false");
final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY;
verify(checkConfig, getPath("Input15Extensions.java"), expected);
}
@ -112,6 +117,7 @@ public class RequireThisCheckTest extends BaseCheckTestSupport {
public void testGithubIssue41() throws Exception {
final DefaultConfiguration checkConfig =
createCheckConfig(RequireThisCheck.class);
checkConfig.addAttribute("validateOnlyOverlapping", "false");
final String[] expected = {
"7:19: " + getCheckMessage(MSG_VARIABLE, "number", ""),
"8:16: " + getCheckMessage(MSG_METHOD, "other", ""),
@ -132,6 +138,7 @@ public class RequireThisCheckTest extends BaseCheckTestSupport {
@Test
public void testWithAnonymousClass() throws Exception {
final DefaultConfiguration checkConfig = createCheckConfig(RequireThisCheck.class);
checkConfig.addAttribute("validateOnlyOverlapping", "false");
final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY;
verify(checkConfig,
getPath("InputRequireThis3.java"),
@ -145,4 +152,120 @@ public class RequireThisCheckTest extends BaseCheckTestSupport {
ast.initialize(new CommonHiddenStreamToken(TokenTypes.ENUM, "ENUM"));
check.visitToken(ast);
}
@Test
public void testValidateOnlyOverlappingFalse() throws Exception {
final DefaultConfiguration checkConfig = createCheckConfig(RequireThisCheck.class);
checkConfig.addAttribute("validateOnlyOverlapping", "false");
final String[] expected = {
"20:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"21:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
"22:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
"23:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
"27:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
"28:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
"29:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
"33:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
"37:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
"41:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
"43:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"45:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
"49:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
"50:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
"60:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
"61:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
"80:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"84:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
"119:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"128:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"132:9: " + getCheckMessage(MSG_METHOD, "method1", ""),
"168:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
"169:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
"170:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
"172:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"176:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
"177:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
"178:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
"180:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"185:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"189:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"210:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"215:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"225:21: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"228:21: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"238:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"253:9: " + getCheckMessage(MSG_VARIABLE, "booleanField", ""),
"262:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"270:18: " + getCheckMessage(MSG_METHOD, "addSuffixToField", ""),
"275:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"275:18: " + getCheckMessage(MSG_METHOD, "addSuffixToField", ""),
"301:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"340:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"360:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
"374:40: " + getCheckMessage(MSG_METHOD, "getServletRelativeAction", ""),
"376:20: " + getCheckMessage(MSG_METHOD, "processAction", ""),
"383:9: " + getCheckMessage(MSG_VARIABLE, "servletRelativeAction", ""),
"384:16: " + getCheckMessage(MSG_METHOD, "processAction", ""),
"443:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
"447:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
"451:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
"455:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
"459:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
"463:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
};
verify(checkConfig, getPath("InputValidateOnlyOverlappingFalse.java"), expected);
}
@Test
public void testValidateOnlyOverlappingTrue() throws Exception {
final DefaultConfiguration checkConfig = createCheckConfig(RequireThisCheck.class);
final String[] expected = {
"20:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"43:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"80:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"119:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"172:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"180:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"238:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"253:9: " + getCheckMessage(MSG_VARIABLE, "booleanField", ""),
"262:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"275:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"301:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"339:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
"359:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
"442:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
"450:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
"454:9: " + getCheckMessage(MSG_VARIABLE, "fieldStatic", ""),
};
verify(checkConfig, getPath("InputValidateOnlyOverlappingTrue.java"), expected);
}
}

View File

@ -0,0 +1,469 @@
package com.puppycrawl.tools.checkstyle.checks.coding;
import java.util.BitSet;
public class InputValidateOnlyOverlappingFalse {
private static String fieldStatic = "fieldStatic";
private final long fieldFinal1;
private final long fieldFinal2;
private final BitSet fieldFinal3;
private String field1;
private String field2;
private String field3 = "some string";
private boolean booleanField;
private int intField;
public InputValidateOnlyOverlappingFalse(String field1) {
field1 = field1; // violation
fieldFinal1 = 0; // violation
fieldFinal2 = 0; // violation
fieldFinal3 = new BitSet(); // violation
}
public InputValidateOnlyOverlappingFalse(long value) {
fieldFinal1 = value; // violation
fieldFinal2 = 0; // violation
fieldFinal3 = new BitSet(); // violation
}
public InputValidateOnlyOverlappingFalse() {
fieldFinal1 = 0; // violation
long fieldFinal2 = 0L;
fieldFinal2 = 1L;
this.fieldFinal2 = fieldFinal2;
fieldFinal3 = new BitSet(); // violation
}
public InputValidateOnlyOverlappingFalse(String name, long id) {
fieldFinal1 = 0; // violation
long field1 = 0L;
field1 = field1; // violation
this.fieldFinal2 = 1L;
fieldFinal3 = new BitSet(); // violation
}
public InputValidateOnlyOverlappingFalse(int param) {
fieldFinal2 = 0L; // violation
fieldFinal3 = new BitSet(); // violation
long fieldFinal1 = 1L;
try {
fieldFinal1 = 2L;
}
catch (Exception ex) {}
this.fieldFinal1 = fieldFinal1;
}
public InputValidateOnlyOverlappingFalse(BitSet fieldFinal3) {
fieldFinal1 = 1L; // violation
fieldFinal2 = 0L; // violation
fieldFinal3 = new BitSet();
if (true) {
fieldFinal3 = (BitSet) fieldFinal3.clone();
}
this.fieldFinal3 = fieldFinal3;
}
void foo1(String methodParam) {
methodParam = methodParam;
}
void foo2() {
String localVar = "values";
localVar = localVar;
}
void foo3() {
String field1 = "values";
field1 = field1; // violation
}
void foo4(String methodParam) {
fieldStatic = methodParam; // violation
}
void foo5(String methodParam) {
methodParam = methodParam + "string";
}
void foo6(String field1) {
field1 = this.field1 + field1;
this.field1 = field1 + this.field1;
field1 = field1 + this.field1;
field1 = this.field1 + this.field1;
this.field1 = this.field1 + this.field1;
this.field1 = this.field1 + field1;
field1 += field1;
}
String addSuffixToParameter(String methodParam) {
return methodParam += "suffix";
}
String addSuffixToField(String field1) {
return field1 += "suffix";
}
String addSuffixToThisField(String field1) {
return this.field1 += "suffix";
}
static void foo7(String fieldStatic) {
// this.fieldStatic = fieldStatic; <- fieldStatic cannot be referenced from a static context
fieldStatic = fieldStatic;
}
void foo8(Long field1) {
field1 += field1; // violation
}
void foo9(Long fieldFinal1) {
// this.fieldFinal1 += fieldFinal1; <- cannot assign value to a final variable
fieldFinal1 += fieldFinal1;
}
void method1() {
field1 = "2"; // violation
}
void method2() {
method1() ; // violation
}
void method3() {
staticFoo();
staticTwoArgs("message", "arg");
staticTwoArgs("message", 1);
this.method1() ;
}
static void staticFoo() { }
static void foo10() {
staticFoo();
staticTwoArgs("message", "arg");
}
// void staticFoo() {} -> compile time error. Already defined in the scope.
static void staticTwoArgs(String message1, String argument) {}
void staticTwoArgs(String message1, int argument) {}
static void foo16() {
long fieldFinal1 = 5L;
// this.fieldFinal1 = fieldFinal1; // compile time error: cannot be referenced from a static context
fieldFinal1 = 11L;
}
static void foo17() {
String fieldStatic = "";
// this.fieldStatic = fieldStatic; // compile time error: cannot be referenced from a static context
fieldStatic = "Hello, World!";
}
InputValidateOnlyOverlappingFalse(boolean flag) {
fieldFinal1 = 0L; // violation
fieldFinal2 = 0L; // violation
fieldFinal3 = new BitSet(); // violation
long field1 = 1L;
field1 = field1; // violation
}
InputValidateOnlyOverlappingFalse(boolean flag, String name) {
fieldFinal1 = 0L; // violation
fieldFinal2 = 0L; // violation
fieldFinal3 = new BitSet(); // violation
long field1 = 1L;
field1 = field1; // violation
return;
}
void foo18() {
field1 = "Hello"; // violation
}
void foo19(String field1) {
field1 = "Hello"; // violation
}
void foo20() {
boolean foo21 = this.foo21("");
if (foo21) {
}
}
boolean foo21(String s) {
return true;
}
void foo22() {
long fieldFinal1 = 1L;
// this.fieldFinal1 = fieldFinal1; <- cannot assign value to a final variable
fieldFinal1 = fieldFinal1;
}
void foo23() {
field1 = "Hello!"; // violation
}
void foo24() {
String field1 = "Hello";
field1 = "Java"; // violation
this.booleanField = true;
this.booleanField = booleanField;
}
void foo25() {
try {
if (true) {
String field1 = "Hello, World!";
if (true) {
field1 = new String(); // violation
}
else {
field1 = new String(); // violation
}
}
}
catch (Exception ex) {
}
}
void foo26(String field1) {
field1 = field1.replace('/', '*'); // violation
}
void foo27() {
int intField = -1;
if (intField == -1) {
intField = 20;
}
else {
intField = this.intField / 100;
}
}
void foo28() {
boolean booleanField = true;
booleanField = !booleanField; // violation
}
static void foo29(String field1) {
// this.field1 = true ? "field1" : field1; <- compile time error: cannot be referenced from a static context
field1 = true ? "field1" : field1;
}
void foo30(String field1) {
field1 = true ? "field1" : field1; // violation
}
void foo31(String field1) {
field1 = this.field1;
}
String foo32(String field1) {
field1 = addSuffixToField(field1); // no violation!!! it is just modification of parameter which is returned at the end of the method
return field1;
}
String foo33(String field1 ) {
field1 = addSuffixToField(field1); // violation (no return, variable 'stringField' will not be saved after method execution)
return "New String";
}
String foo34(String field1) {
field1 = field1.replace('A', 'B');
if (field1.contains("C")) {
return field1;
}
else {
return field1 + 'C';
}
}
String foo35() {
String field1 = "values";
field1 = field1;
return field1;
}
void foo36(String field1) {
field1 = field1.replace('/', '*');
field1 = this.field1;
}
String foo37(String field1) {
field1 += "suffix"; // violation
return "New string";
}
static void foo38() {
// this.fieldStatic = ""; <-- compile time error: cannot be referenced from a static context
fieldStatic = "";
}
static void foo39() {
boolean booleanField = true;
// this.booleanField = !booleanField; <-- compile time error: cannot be referenced from a static context
booleanField = !booleanField;
}
static void foo40() {
try {
boolean booleanField = true;
// this.booleanField = !booleanField; <-- compile time error: cannot be referenced from a static context
booleanField = !booleanField;
}
catch (Exception e) {}
}
static {
// this.fieldStatic = ""; <-- compile time error: cannot be referenced from a static context
fieldStatic = "";
}
{
// if we assign variable to a final variable in initialization block,
// it will lead to compile time error in constructor block: variable migh have been
// already assigned
// fieldFinal1 = 1;
}
{
String field1 = "";
field1 = field1; // violation
}
static {
fieldStatic = "";
String field1 = "";
// this.field1 = field1; <-- compile time error: cannot be referenced from a static context
field1 = field1;
}
void foo41(long fieldFinal1) {
// this.fieldFinal1 = 1L; <- cannot assign value to a final variable
fieldFinal1 = fieldFinal1;
}
void foo42(String fieldStatic) {
this.fieldStatic = fieldStatic;
}
void foo43(String fieldStatic) {
fieldStatic = fieldStatic; // violation
}
void foo44(String fieldStatic) {
fieldStatic = this.fieldStatic;
}
private String servletRelativeAction;
public String getServletRelativeAction() {
return this.servletRelativeAction;
}
public String foo45() {
String servletRelativeAction = getServletRelativeAction(); // violation (Method call to 'getServletRelativeAction' needs "this.".)
if (true) {
return processAction("action"); // violation (Method call to 'processAction' needs "this.".)
}
else if (servletRelativeAction.endsWith("/")) {
if (servletRelativeAction.startsWith("/")) {
servletRelativeAction = "" + servletRelativeAction;
}
}
servletRelativeAction = "servletRelativeAction"; // violation
return processAction(servletRelativeAction); // violation (Method call to 'processAction' needs "this.".)
}
private String processAction(String servletRelativeAction) {
return "";
}
public InputValidateOnlyOverlappingFalse(long fieldFinal1, long fieldFinal2,
BitSet fieldFinal3, boolean booleanField) {
this.fieldFinal1 = fieldFinal1;
this.fieldFinal2 = fieldFinal2;
this.fieldFinal3 = fieldFinal3;
booleanField = this.booleanField;
if (booleanField) {
booleanField = "Hello, World!".equals("Hello, Checkstyle!");
}
this.booleanField = booleanField;
}
void foo46(boolean booleanField) {
booleanField = this.booleanField;
if (booleanField) {
booleanField = "Hello, World!".equals("Hello, Checkstyle!");
}
this.booleanField = booleanField;
}
static void foo47(String fieldStatic) {
fieldStatic = "Andrei";
}
void foo48(long fieldFinal1) {
fieldFinal1 = 1L;
}
private boolean foo49(boolean booleanField) {
boolean suppressionSourceExists = true;
try {
}
catch (Exception ex) {
suppressionSourceExists = false;
}
finally {
if (booleanField) {
try {
}
catch (Exception ignored) {
this.booleanField = false;
}
}
}
return suppressionSourceExists;
}
void foo50(String fieldStatic) {
fieldStatic = fieldStatic; // violation
}
void foo51(String methodParam) {
fieldStatic = methodParam; // violation
}
void foo52(String fieldStatic) {
fieldStatic += fieldStatic; // violation
}
void foo53(String fieldStatic) {
fieldStatic += fieldStatic; // violation
}
void foo54(String methodParam) {
fieldStatic += methodParam; // violation
}
void foo55(String methodParam) {
fieldStatic += fieldStatic; // violation
}
void foo56(boolean booleanField) { booleanField = this.booleanField; }
boolean foo57(boolean booleanField) { booleanField = !booleanField; return booleanField; }
}

View File

@ -0,0 +1,468 @@
package com.puppycrawl.tools.checkstyle.checks.coding;
import java.util.BitSet;
public class InputValidateOnlyOverlappingTrue {
private static String fieldStatic = "fieldStatic";
private final long fieldFinal1;
private final long fieldFinal2;
private final BitSet fieldFinal3;
private String field1;
private String field2;
private String field3 = "some string";
private boolean booleanField;
private int intField;
public InputValidateOnlyOverlappingTrue(String field1) {
field1 = field1; // violation
fieldFinal1 = 0;
fieldFinal2 = 0;
fieldFinal3 = new BitSet();
}
public InputValidateOnlyOverlappingTrue(long value) {
fieldFinal1 = value;
fieldFinal2 = 0;
fieldFinal3 = new BitSet();
}
public InputValidateOnlyOverlappingTrue() {
fieldFinal1 = 0;
long fieldFinal2 = 0L;
fieldFinal2 = 1L;
this.fieldFinal2 = fieldFinal2;
fieldFinal3 = new BitSet();
}
public InputValidateOnlyOverlappingTrue(String name, long id) {
fieldFinal1 = 0;
long field1 = 0L;
field1 = field1; // violation
this.fieldFinal2 = 1L;
fieldFinal3 = new BitSet();
}
public InputValidateOnlyOverlappingTrue(int param) {
fieldFinal2 = 0L;
fieldFinal3 = new BitSet();
long finalField1 = 1L;
try {
finalField1 = 2L;
}
catch (Exception ex) {}
this.fieldFinal1 = finalField1;
}
public InputValidateOnlyOverlappingTrue(BitSet fieldFinal3) {
fieldFinal1 = 1L;
fieldFinal2 = 0L;
fieldFinal3 = new BitSet();
if (true) {
fieldFinal3 = (BitSet) fieldFinal3.clone();
}
this.fieldFinal3 = fieldFinal3;
}
void foo1(String methodParam) {
methodParam = methodParam;
}
void foo2() {
String localVar = "values";
localVar = localVar;
}
void foo3() {
String field1 = "values";
field1 = field1; // violation
}
void foo4(String methodParam) {
fieldStatic = methodParam;
}
void foo5(String methodParam) {
methodParam = methodParam + "string";
}
void foo6(String field1) {
field1 = this.field1 + field1;
this.field1 = field1 + field1;
field1 = field1 + this.field1;
field1 = this.field1 + this.field1;
this.field1 = this.field1 + this.field1;
this.field1 = this.field1 + field1;
field1 += field1;
}
String addSuffixToParameter(String methodParam) {
return methodParam += "suffix";
}
String addSuffixToField(String field1) {
return field1 += "suffix";
}
String addSuffixToThisField(String field1) {
return this.field1 += "suffix";
}
static void foo7(String fieldStatic) {
// this.fieldStatic = fieldStatic; <- fieldStatic cannot be referenced from a static context
fieldStatic = fieldStatic;
}
void foo8(Long field1) {
field1 += field1; // violation
}
void foo9(Long fieldFinal1) {
// this.fieldFinal1 += fieldFinal1; <- cannot assign value to a final variable
fieldFinal1 += fieldFinal1;
}
void method1() {
field1 = "2";
}
void method2() {
method1();
}
void method3() {
staticFoo();
staticTwoArgs("message", "arg");
staticTwoArgs("message", 1);
this.method1() ;
}
static void staticFoo() { }
static void foo10() {
staticFoo();
staticTwoArgs("message", "arg");
}
// void staticFoo() {} -> compile time error. Already defined in the scope.
static void staticTwoArgs(String message1, String argument) {}
void staticTwoArgs(String message1, int argument) {}
static void foo16() {
long fieldFinal1 = 5L;
// this.fieldFinal1 = fieldFinal1; // compile time error: cannot be referenced from a static context
fieldFinal1 = 11L;
}
static void foo17() {
String fieldStatic = "";
// this.fieldStatic = fieldStatic; // compile time error: cannot be referenced from a static context
fieldStatic = "Hello, World!";
}
InputValidateOnlyOverlappingTrue(boolean flag) {
fieldFinal1 = 0L;
fieldFinal2 = 0L;
fieldFinal3 = new BitSet();
long field1 = 1L;
field1 = field1; // violation
}
InputValidateOnlyOverlappingTrue(boolean flag, String name) {
fieldFinal1 = 0L;
fieldFinal2 = 0L;
fieldFinal3 = new BitSet();
long field1 = 1L;
field1 = field1; // violation
return;
}
void foo18() {
field1 = "Hello";
}
void foo19(String field1) {
field1 = "Hello";
}
void foo20() {
boolean foo21 = this.foo21("");
if (foo21) {
}
}
boolean foo21(String s) {
return true;
}
void foo22() {
long fieldFinal1 = 1L;
// this.fieldFinal1 = fieldFinal1; <- cannot assign value to a final variable
fieldFinal1 = fieldFinal1;
}
void foo23() {
field1 = "Hello!";
}
void foo24() {
String field1 = "Hello";
field1 = "Java";
this.booleanField = true;
this.booleanField = booleanField;
}
void foo25() {
try {
if (true) {
String field1 = "Hello, World!";
if (true) {
field1 = new String();
}
else {
field1 = new String();
}
}
}
catch (Exception ex) {
}
}
void foo26(String field1) {
field1 = field1.replace('/', '*'); // violation
}
void foo27() {
int intField = -1;
if (intField == -1) {
intField = 20;
}
else {
intField = this.intField / 100;
}
}
void foo28() {
boolean booleanField = true;
booleanField = !booleanField; // violation
}
static void foo29(String field1) {
// this.field1 = true ? "field1" : field1; <- compile time error: cannot be referenced from a static context
field1 = true ? "field1" : field1;
}
void foo30(String field1) {
field1 = true ? "field1" : field1; // violation
}
void foo31(String field1) {
field1 = this.field1;
}
String foo32(String field1) {
field1 = addSuffixToField(field1); // no violation!!! it is just modification of parameter which is returned at the end of the method
return field1;
}
String foo33(String field1) {
field1 = addSuffixToField(field1); // violation (no return, variable 'stringField' will not be saved after method execution)
return "New String";
}
String foo34(String field1) {
field1 = field1.replace('A', 'B');
if (field1.contains("C")) {
return field1;
}
else {
return field1 + 'C';
}
}
String foo35() {
String field1 = "values";
field1 = field1;
return field1;
}
void foo36(String field1) {
field1 = field1.replace('/', '*');
field1 = this.field1;
}
String foo37(String field1) {
field1 += "suffix"; // violation
return "New string";
}
static void foo38() {
// this.fieldStatic = ""; <-- compile time error: cannot be referenced from a static context
fieldStatic = "";
}
static void foo39() {
boolean booleanField = true;
// this.booleanField = !booleanField; <-- compile time error: cannot be referenced from a static context
booleanField = !booleanField;
}
static void foo40() {
try {
boolean booleanField = true;
// this.booleanField = !booleanField; <-- compile time error: cannot be referenced from a static context
booleanField = !booleanField;
}
catch (Exception e) {}
}
static {
fieldStatic = "";
}
// {
// if we assign variable to a final variable in initialization block,
// it will lead to compile time error in constructor block: variable migh have been
// already assigned
// fieldFinal1 = 1;
// }
{
String field1 = "";
field1 = field1; // violation
}
static {
fieldStatic = "";
String field1 = "";
// this.field1 = field1; <-- compile time error: cannot be referenced from a static context
field1 = field1;
}
void foo41(long fieldFinal1) {
// this.fieldFinal1 = 1L; <- cannot assign value to a final variable
fieldFinal1 = fieldFinal1;
}
void foo42(String fieldStatic) {
this.fieldStatic = fieldStatic;
}
void foo43(String fieldStatic) {
fieldStatic = fieldStatic; // violation
}
void foo44(String fieldStatic) {
fieldStatic = this.fieldStatic;
}
private String servletRelativeAction;
public String getServletRelativeAction() {
return this.servletRelativeAction;
}
public String foo45() {
String servletRelativeAction = getServletRelativeAction();
if (true) {
return processAction("action");
}
else if (servletRelativeAction.endsWith("/")) {
if (servletRelativeAction.startsWith("/")) {
servletRelativeAction = "" + servletRelativeAction;
}
}
servletRelativeAction = "servletRelativeAction";
return processAction(servletRelativeAction);
}
private String processAction(String servletRelativeAction) {
return "";
}
public InputValidateOnlyOverlappingTrue(long fieldFinal1, long fieldFinal2,
BitSet fieldFinal3, boolean booleanField) {
this.fieldFinal1 = fieldFinal1;
this.fieldFinal2 = fieldFinal2;
this.fieldFinal3 = fieldFinal3;
booleanField = this.booleanField;
if (booleanField) {
booleanField = "Hello, World!".equals("Hello, Checkstyle!");
}
this.booleanField = booleanField;
}
void foo46(boolean booleanField) {
booleanField = this.booleanField;
if (booleanField) {
booleanField = "Hello, World!".equals("Hello, Checkstyle!");
}
this.booleanField = booleanField;
}
static void foo47(String fieldStatic) {
fieldStatic = "Andrei";
}
void foo48(long fieldFinal1) {
fieldFinal1 = 1L;
}
private boolean foo49(boolean booleanField) {
boolean suppressionSourceExists = true;
try {
}
catch (Exception ex) {
suppressionSourceExists = false;
}
finally {
if (booleanField) {
try {
}
catch (Exception ignored) {
this.booleanField = false;
}
}
}
return suppressionSourceExists;
}
void foo50(String fieldStatic) {
fieldStatic = fieldStatic; // violation
}
void foo51(String methodParam) {
fieldStatic = methodParam;
}
void foo52(String fieldStatic) {
fieldStatic += fieldStatic; // violation
}
void foo53(String fieldStatic) {
fieldStatic += fieldStatic; // violation
}
void foo54(String methodParam) {
fieldStatic += methodParam;
}
void foo55(String methodParam) {
fieldStatic += fieldStatic;
}
void foo56(boolean booleanField) { booleanField = this.booleanField; }
boolean foo57(boolean booleanField) { booleanField = !booleanField; return booleanField; }
}

View File

@ -3255,7 +3255,8 @@ public void foo(int i, String s) {}
</p>
<p>
Warning: the Check is very controversial and not that actual nowadays.
Warning: the Check is very controversial if 'validateOnlyOverlapping' option is set to
'false' and not that actual nowadays.
</p>
<p>
@ -3294,6 +3295,12 @@ public void foo(int i, String s) {}
<td><a href="property_types.html#boolean">boolean</a></td>
<td><code>true</code></td>
</tr>
<tr>
<td>validateOnlyOverlapping</td>
<td>Whether to check only overlapping by variables or arguments.</td>
<td><a href="property_types.html#boolean">boolean</a></td>
<td><code>true</code></td>
</tr>
</table>
</subsection>
@ -3313,6 +3320,105 @@ public void foo(int i, String s) {}
&lt;property name=&quot;checkMethods&quot; value=&quot;false&quot;/&gt;
&lt;/module&gt;
</source>
<p>
Examples of how the check works if validateOnlyOverlapping option is set to true:
</p>
<source>
public static class A {
private int field1;
private int field2;
public A(int field1) {
// Overlapping by constructor argument.
field1 = field1; // violation: Reference to instance variable "field1" needs "this".
field2 = 0;
}
void foo3() {
String field1 = "values";
// Overlapping by local variable.
field1 = field1; // violation: Reference to instance variable "field1" needs "this".
}
}
public static class B {
private int field1;
public A(int f) {
field1 = f;
}
String addSuffixToField(String field1) {
// Overlapping by method argument. Equal to "return field1 = field1 + "suffix";"
return field1 += "suffix"; // violation: Reference to instance variable "field1" needs "this".
}
}
</source>
<p>
Please, be aware of the following logic, which is implemented in the check:
</p>
<p>
1) If you arranges 'this' in your code on your own, the check will not rise violation for
variables which use 'this' to reference a class field, for example:
</p>
<source>
public class C {
private int scale;
private int x;
public void foo(int scale) {
scale = this.scale; // no violation
if (scale > 0) {
scale = -scale; // no violation
}
x *= scale;
}
}
</source>
<p>
2) If method parameter is returned from the method, the check will not rise violation for
returned variable/parameter, for example:
</p>
<source>
public class D {
private String prefix;
public String modifyPrefix(String prefix) {
prefix = "^" + prefix + "$" // no violation (modification of parameter)
return prefix; // modified method parameter is returned from the method
}
}
</source>
<p>
Examples of how the check works if validateOnlyOverlapping option is set to false:
</p>
<source>
public static class A {
private int field1;
private int field2;
public A(int field1) {
field1 = field1; // violation: Reference to instance variable "field1" needs "this".
field2 = 0; // violation: Reference to instance variable "field2" needs "this".
}
void foo3() {
String field1 = "values";
field1 = field1; // violation: Reference to instance variable "field1" needs "this".
}
}
public static class B {
private int field1;
public A(int f) {
field1 = f; // violation: Reference to instance variable "field1" needs "this".
}
String addSuffixToField(String field1) {
return field1 += "suffix"; // violation: Reference to instance variable "field1" needs "this".
}
}
</source>
</subsection>
<subsection name="Example of Usage">