forked from phoedos/pmd
@@ -22,6 +22,8 @@ This is a {{ site.pmd.release_type }} release.
|
||||
* [#4201](https://github.com/pmd/pmd/issues/4201): \[java] CommentDefaultAccessModifier should consider lombok's @<!-- -->Value
|
||||
* java-design
|
||||
* [#4200](https://github.com/pmd/pmd/issues/4200): \[java] ClassWithOnlyPrivateConstructorsShouldBeFinal should consider lombok's @<!-- -->Value
|
||||
* java-errorprone
|
||||
* [#4172](https://github.com/pmd/pmd/issues/4172): \[java] InvalidLogMessageFormat false positive on externally formatted strings
|
||||
|
||||
### API Changes
|
||||
|
||||
|
@@ -262,14 +262,41 @@ public class InvalidLogMessageFormatRule extends AbstractJavaRule {
|
||||
+ params.size();
|
||||
}
|
||||
|
||||
private boolean isStringFormatCall(ASTExpression node) {
|
||||
if (node.getNumChildren() > 0 && node.getChild(0) instanceof ASTPrimaryExpression
|
||||
&& node.getChild(0).getNumChildren() > 0 && node.getChild(0).getChild(0) instanceof ASTPrimaryPrefix
|
||||
&& node.getChild(0).getChild(0).getNumChildren() > 0 && node.getChild(0).getChild(0).getChild(0) instanceof ASTName) {
|
||||
String name = node.getChild(0).getChild(0).getChild(0).getImage();
|
||||
/**
|
||||
* Checks for {@code String.format("%s", x)} and {@code "%s".formatted(x)} calls.
|
||||
*/
|
||||
private boolean isStringFormatCall(ASTExpression expression) {
|
||||
ASTPrimaryExpression primaryExpression = null;
|
||||
ASTPrimaryPrefix primaryPrefix = null;
|
||||
|
||||
// Check beginning of tree: Expression/PrimaryExpression
|
||||
if (expression.getNumChildren() > 0 && expression.getChild(0) instanceof ASTPrimaryExpression) {
|
||||
primaryExpression = (ASTPrimaryExpression) expression.getChild(0);
|
||||
}
|
||||
|
||||
if (primaryExpression != null
|
||||
&& primaryExpression.getNumChildren() > 0 && primaryExpression.getChild(0) instanceof ASTPrimaryPrefix) {
|
||||
primaryPrefix = (ASTPrimaryPrefix) primaryExpression.getChild(0);
|
||||
}
|
||||
|
||||
// check for static String::format calls
|
||||
// Tree: Expression/PrimaryExpression/PrimaryPrefix/Name
|
||||
if (primaryPrefix != null && primaryPrefix.getNumChildren() > 0 && primaryPrefix.getChild(0) instanceof ASTName) {
|
||||
String name = primaryPrefix.getChild(0).getImage();
|
||||
|
||||
return "String.format".equals(name) || formatIsStringFormat && "format".equals(name);
|
||||
}
|
||||
|
||||
// check for String::formatted calls - this method has been added with Java 15
|
||||
// Tree: //Expression/PrimaryExpression[PrimaryPrefix/Literal[@StringLiteral = true()]]/PrimarySuffix[@Image = 'formatted']
|
||||
if (primaryPrefix != null && primaryPrefix.getNumChildren() > 0 && primaryPrefix.getChild(0) instanceof ASTLiteral) {
|
||||
ASTLiteral literal = (ASTLiteral) primaryPrefix.getChild(0);
|
||||
if (literal.isStringLiteral()
|
||||
&& primaryExpression.getNumChildren() > 1 && primaryExpression.getChild(1) instanceof ASTPrimarySuffix) {
|
||||
ASTPrimarySuffix primarySuffix = (ASTPrimarySuffix) primaryExpression.getChild(1);
|
||||
return "formatted".equals(primarySuffix.getImage());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -1085,4 +1085,22 @@ public class Foo {
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>[java] InvalidLogMessageFormat false positive on externally formatted strings #4172</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class Foo {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Foo.class);
|
||||
public void bar() {
|
||||
String msg = "Got kafka msg, headers=%s, body=%s".formatted(headers, new String(body, UTF_8));
|
||||
LOGGER.info(msg);
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
||||
|
Reference in New Issue
Block a user