From 49862970ac522ae85fa014b5ac4985e56645fcff Mon Sep 17 00:00:00 2001 From: Oliver Burn Date: Fri, 31 Dec 2010 18:49:34 +1100 Subject: [PATCH] apply patch 3107393: EqualsAvoidNull should also check for equalsIgnoreCase --- .../checks/coding/EqualsAvoidNullCheck.java | 24 ++++ .../checks/coding/messages.properties | 1 + .../coding/InputEqualsAvoidNull.java | 133 +++++++++++++++++- .../checks/coding/EqualsAvoidNullTest.java | 44 +++++- 4 files changed, 199 insertions(+), 3 deletions(-) diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheck.java index a874eb33c..30f5f9ed6 100755 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheck.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheck.java @@ -88,6 +88,12 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes; */ public class EqualsAvoidNullCheck extends Check { + //Decides whether string literals with optional assignment assignment should be checked to be on the left side + //of the equalsIgnoreCase comparision. The earlier version of this class checked only for equals() comparision. + //This is added to support cases which may not want the equalsIgnoreCase() comparision + //for some reason (backward compatibility) + private boolean performEqualsIgnoreCaseCheck = true; + @Override public int[] getDefaultTokens() { @@ -123,6 +129,13 @@ public class EqualsAvoidNullCheck extends Check log(aMethodCall.getLineNo(), aMethodCall.getColumnNo(), "equals.avoid.null"); } + } else if(performEqualsIgnoreCaseCheck) { + if("equalsIgnoreCase".equals(method.getText()) && containsOneArg(expr)) { + if (containsAllSafeTokens(expr)) { + log(aMethodCall.getLineNo(), aMethodCall.getColumnNo(), + "equalsIgnoreCase.avoid.null"); + } + } } } @@ -219,4 +232,15 @@ public class EqualsAvoidNullCheck extends Check } return aCurrentAST; } + + /** + * + * @param performEqualsIgnoreCaseCheck - Decides whether string literals with optional assignment assignment + * should be checked to be on the left side of the equalsIgnoreCase comparision. The earlier version of this class + * checked only for equals() comparision. This is added to support cases which may not want the equalsIgnoreCase() + * comparision for some reason (backward compatibility) + */ + public void setPerformEqualsIgnoreCaseCheck(boolean performEqualsIgnoreCaseCheck) { + this.performEqualsIgnoreCaseCheck = performEqualsIgnoreCaseCheck; + } } diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties index eb92854bd..1f82c5168 100755 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties @@ -12,6 +12,7 @@ default.comes.last=Default should be last label in the switch. doublechecked.locking.avoid=The double-checked locking idiom is broken and should be avoided. empty.statement=Empty statement. equals.avoid.null=String literal expressions should be on the left side of an equals comparison. +equalsIgnoreCase.avoid.null=String literal expressions should be on the left side of an equalsIgnoreCase comparison. equals.noHashCode=Definition of ''equals()'' without corresponding definition of ''hashCode()''. explicit.init=Variable ''{0}'' explicitly initialized to ''{1}'' (default value for its type). fall.through=Fall through from previous branch of the switch statement. diff --git a/src/testinputs/com/puppycrawl/tools/checkstyle/coding/InputEqualsAvoidNull.java b/src/testinputs/com/puppycrawl/tools/checkstyle/coding/InputEqualsAvoidNull.java index b21f7e85a..0a6e1e87d 100755 --- a/src/testinputs/com/puppycrawl/tools/checkstyle/coding/InputEqualsAvoidNull.java +++ b/src/testinputs/com/puppycrawl/tools/checkstyle/coding/InputEqualsAvoidNull.java @@ -10,7 +10,7 @@ public class InputEqualsAvoidNull { * methods that should get flagged * @return */ - public void flag() { + public void flagForEquals() { Object o = new Object(); String s = "pizza"; @@ -28,12 +28,64 @@ public class InputEqualsAvoidNull { o.equals((("cheese" + "ham")) + "sauce"); } + /** + * methods that should get flagged + */ + public void flagForEqualsIgnoreCase() { + String s = "pizza"; + + s.equalsIgnoreCase("hot pizza"); + + s.equalsIgnoreCase(s = "cold pizza"); + + s.equalsIgnoreCase(((s = "cold pizza"))); + + s.equalsIgnoreCase("cheese" + "ham" + "sauce"); + + s.equalsIgnoreCase(("cheese" + "ham") + "sauce"); + + s.equalsIgnoreCase((("cheese" + "ham")) + "sauce"); + } + + /** + * methods that should get flagged + */ + public void flagForBoth() { + Object o = new Object(); + String s = "pizza"; + + o.equals("hot pizza"); + + o.equals(s = "cold pizza"); + + o.equals(((s = "cold pizza"))); + + o.equals("cheese" + "ham" + "sauce"); + + o.equals(("cheese" + "ham") + "sauce"); + + o.equals((("cheese" + "ham")) + "sauce"); + + s.equalsIgnoreCase("hot pizza"); + + s.equalsIgnoreCase(s = "cold pizza"); + + s.equalsIgnoreCase(((s = "cold pizza"))); + + s.equalsIgnoreCase("cheese" + "ham" + "sauce"); + + s.equalsIgnoreCase(("cheese" + "ham") + "sauce"); + + s.equalsIgnoreCase((("cheese" + "ham")) + "sauce"); + } + + /** * methods that should not get flagged * * @return */ - public void noFlag() { + public void noFlagForEquals() { Object o = new Object(); String s = "peperoni"; @@ -62,6 +114,83 @@ public class InputEqualsAvoidNull { outter.new InputEqualsAvoidNullInner().equals("eat pizza and enjoy inner classes"); } + /** + * methods that should not get flagged + */ + public void noFlagForEqualsIgnoreCase() { + String s = "peperoni"; + String s1 = "tasty"; + + s.equalsIgnoreCase(s += "mushrooms"); + + s1.equalsIgnoreCase(s += "mushrooms"); + + (s = "thin crust").equalsIgnoreCase("thick crust"); + + (s += "garlic").equalsIgnoreCase("basil"); + + ("Chicago Style" + "NY Style").equalsIgnoreCase("California Style" + "Any Style"); + + "onions".equalsIgnoreCase(s); + + s.equalsIgnoreCase(new String()); + + s.equals(s1); + + new String().equalsIgnoreCase("more cheese"); + + } + + public void noFlagForBoth() { + Object o = new Object(); + String s = "peperoni"; + String s1 = "tasty"; + + o.equals(s += "mushrooms"); + + (s = "thin crust").equals("thick crust"); + + (s += "garlic").equals("basil"); + + ("Chicago Style" + "NY Style").equals("California Style" + "Any Style"); + + equals("peppers"); + + "onions".equals(o); + + o.equals(new Object()); + + o.equals(equals(o)); + + equals("yummy"); + + new Object().equals("more cheese"); + + InputEqualsAvoidNullOutter outter = new InputEqualsAvoidNullOutter(); + + outter.new InputEqualsAvoidNullInner().equals("eat pizza and enjoy inner classes"); + + s.equalsIgnoreCase(s += "mushrooms"); + + s1.equalsIgnoreCase(s += "mushrooms"); + + (s = "thin crust").equalsIgnoreCase("thick crust"); + + (s += "garlic").equalsIgnoreCase("basil"); + + ("Chicago Style" + "NY Style").equalsIgnoreCase("California Style" + "Any Style"); + + "onions".equalsIgnoreCase(s); + + s.equalsIgnoreCase(new String()); + + s.equals(s1); + + new String().equalsIgnoreCase("more cheese"); + + + } + } class InputEqualsAvoidNullOutter { diff --git a/src/tests/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullTest.java b/src/tests/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullTest.java index 55702c831..88e961073 100755 --- a/src/tests/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullTest.java +++ b/src/tests/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullTest.java @@ -26,7 +26,7 @@ import org.junit.Test; public class EqualsAvoidNullTest extends BaseCheckTestSupport { @Test - public void testIt() throws Exception + public void testEqualsWithDefault() throws Exception { final DefaultConfiguration checkConfig = createCheckConfig(EqualsAvoidNullCheck.class); @@ -38,6 +38,48 @@ public class EqualsAvoidNullTest extends BaseCheckTestSupport "24:17: String literal expressions should be on the left side of an equals comparison.", "26:17: String literal expressions should be on the left side of an equals comparison.", "28:17: String literal expressions should be on the left side of an equals comparison.", + "37:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "39:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "41:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "43:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "45:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "47:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "57:17: String literal expressions should be on the left side of an equals comparison.", + "59:17: String literal expressions should be on the left side of an equals comparison.", + "61:17: String literal expressions should be on the left side of an equals comparison.", + "63:17: String literal expressions should be on the left side of an equals comparison.", + "65:17: String literal expressions should be on the left side of an equals comparison.", + "67:17: String literal expressions should be on the left side of an equals comparison.", + "69:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "71:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "73:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "75:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "77:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison.", + "79:27: String literal expressions should be on the left side of an equalsIgnoreCase comparison." + }; + verify(checkConfig, getPath("coding" + File.separator + "InputEqualsAvoidNull.java"), expected); + } + + @Test + public void testEqualsWithoutEqualsIgnoreCase() throws Exception + { + final DefaultConfiguration checkConfig = + createCheckConfig(EqualsAvoidNullCheck.class); + checkConfig.addAttribute("performEqualsIgnoreCaseCheck", "false"); + + final String[] expected = { + "18:17: String literal expressions should be on the left side of an equals comparison.", + "20:17: String literal expressions should be on the left side of an equals comparison.", + "22:17: String literal expressions should be on the left side of an equals comparison.", + "24:17: String literal expressions should be on the left side of an equals comparison.", + "26:17: String literal expressions should be on the left side of an equals comparison.", + "28:17: String literal expressions should be on the left side of an equals comparison.", + "57:17: String literal expressions should be on the left side of an equals comparison.", + "59:17: String literal expressions should be on the left side of an equals comparison.", + "61:17: String literal expressions should be on the left side of an equals comparison.", + "63:17: String literal expressions should be on the left side of an equals comparison.", + "65:17: String literal expressions should be on the left side of an equals comparison.", + "67:17: String literal expressions should be on the left side of an equals comparison.", }; verify(checkConfig, getPath("coding" + File.separator + "InputEqualsAvoidNull.java"), expected); }