diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheck.java index 975bc5081..f419978b6 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheck.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheck.java @@ -337,24 +337,24 @@ public class EqualsAvoidNullCheck extends Check { * @param expr the argument expression * @return - true if any child matches the set of tokens, false if not */ - private static boolean containsAllSafeTokens(final DetailAST expr) { + private boolean containsAllSafeTokens(final DetailAST expr) { DetailAST arg = expr.getFirstChild(); - if (arg.branchContains(TokenTypes.METHOD_CALL)) { - return false; - } arg = skipVariableAssign(arg); - //Plus assignment can have ill affects - //do not want to recommend moving expression - //See example: - //String s = "SweetString"; - //s.equals(s += "SweetString"); //false - //s = "SweetString"; - //(s += "SweetString").equals(s); //true + boolean argIsNotNull = false; + if (arg.getType() == TokenTypes.PLUS) { + DetailAST child = arg.getFirstChild(); + while (child != null + && !argIsNotNull) { + argIsNotNull = child.getType() == TokenTypes.STRING_LITERAL + || child.getType() == TokenTypes.IDENT; + child = child.getNextSibling(); + } + } - return !arg.branchContains(TokenTypes.PLUS_ASSIGN) - && !arg.branchContains(TokenTypes.IDENT) - && !arg.branchContains(TokenTypes.LITERAL_NULL); + return argIsNotNull + || !arg.branchContains(TokenTypes.IDENT) + && !arg.branchContains(TokenTypes.LITERAL_NULL); } /** diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheckTest.java index 960cdd9fe..7958521e9 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/EqualsAvoidNullCheckTest.java @@ -95,6 +95,9 @@ public class EqualsAvoidNullCheckTest extends BaseCheckTestSupport { "357:35: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), "368:30: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), "394:35: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), + "415:17: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), + "416:17: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), + "417:17: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), }; verify(checkConfig, getPath("InputEqualsAvoidNull.java"), expected); } @@ -145,6 +148,9 @@ public class EqualsAvoidNullCheckTest extends BaseCheckTestSupport { "357:35: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), "368:30: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), "394:35: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), + "415:17: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), + "416:17: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), + "417:17: " + getCheckMessage(MSG_EQUALS_AVOID_NULL), }; verify(checkConfig, getPath("InputEqualsAvoidNull.java"), expected); } diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/coding/InputEqualsAvoidNull.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/coding/InputEqualsAvoidNull.java index 1343da6ac..406c022d7 100644 --- a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/coding/InputEqualsAvoidNull.java +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/coding/InputEqualsAvoidNull.java @@ -407,3 +407,19 @@ enum TestEnum { this.ONE.equals(this); } } + +class TestConcatenations { + String s = null; + + void foo() { + s.equals(s + s); + s.equals("a" + "b"); + s.equals(getInt() + s); + s.equals(getInt() + getInt()); + } + + int getInt() { + return (Integer) null; + } +} +