diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/strings/StringToStringRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/strings/StringToStringRule.java index a5f4c3171a..8169c68601 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/strings/StringToStringRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/strings/StringToStringRule.java @@ -3,12 +3,15 @@ */ package net.sourceforge.pmd.lang.java.rule.strings; +import net.sourceforge.pmd.lang.java.ast.ASTMethodReference; import net.sourceforge.pmd.lang.java.ast.ASTName; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; +import net.sourceforge.pmd.lang.java.ast.AbstractJavaNode; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence; import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; +import net.sourceforge.pmd.lang.symboltable.ScopedNode; public class StringToStringRule extends AbstractJavaRule { @@ -21,13 +24,26 @@ public class StringToStringRule extends AbstractJavaRule { JavaNameOccurrence jocc = (JavaNameOccurrence)occ; NameOccurrence qualifier = jocc.getNameForWhichThisIsAQualifier(); if (qualifier != null) { - if (!isArray && qualifier.getImage().indexOf("toString") != -1) { + if (!isArray && isNotAMethodReference(qualifier) && qualifier.getImage().indexOf("toString") != -1) { addViolation(data, jocc.getLocation()); - } else if (isArray && qualifier.getLocation() != null && !(qualifier.getLocation() instanceof ASTName) && qualifier.getImage().equals("toString")) { + } else if (isArray && isNotAName(qualifier) && qualifier.getImage().equals("toString")) { addViolation(data, jocc.getLocation()); } } } return data; } + + private boolean isNotAMethodReference(NameOccurrence qualifier) { + return isNotA(qualifier, ASTMethodReference.class); + } + + private boolean isNotAName(NameOccurrence qualifier) { + return isNotA(qualifier, ASTName.class); + } + + private boolean isNotA(NameOccurrence qualifier, Class type) { + ScopedNode location = qualifier.getLocation(); + return location == null || !(type.isAssignableFrom(location.getClass())); + } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/strings/xml/StringToString.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/strings/xml/StringToString.xml index 5d117b6375..22aebcee4d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/strings/xml/StringToString.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/strings/xml/StringToString.xml @@ -129,6 +129,20 @@ public class Foo { MyObject o = new MyObject(); //MyObject has no relation with String System.out.println(Foo.toString(o)); //PMD violation false positive } +} + ]]> + + + #1397 StringToString should ignore method references + 0 + msg) { } + public void run() { + String abc = "abc"; + log(abc::toString); // fails rule + log(() -> abc); // passes rule + } } ]]> diff --git a/src/site/markdown/overview/changelog.md b/src/site/markdown/overview/changelog.md index 131cb10eff..03ec07c538 100644 --- a/src/site/markdown/overview/changelog.md +++ b/src/site/markdown/overview/changelog.md @@ -15,6 +15,7 @@ * [#1370](https://sourceforge.net/p/pmd/bugs/1370/): ConsecutiveAppendsShouldReuse not detected properly on StringBuffer * [#1371](https://sourceforge.net/p/pmd/bugs/1371/): InsufficientStringBufferDeclaration not detected properly on StringBuffer * [#1384](https://sourceforge.net/p/pmd/bugs/1384/): NullPointerException in ConsecutiveLiteralAppendsRule +* [#1397](https://sourceforge.net/p/pmd/bugs/1397/): StringToString should ignore method references * [#1398](https://sourceforge.net/p/pmd/bugs/1398/): False positive for GuardLogStatementJavaUtil with Log4j * [#1399](https://sourceforge.net/p/pmd/bugs/1399/): False positive for VariableNamingConventions with annotation @interface * [#1400](https://sourceforge.net/p/pmd/bugs/1400/): False positive with JUnit4TestShouldUseBeforeAnnotation