I want to create a PMD rule using the XPATH expression with the following scenario:
When a parameter of a method is only used in log like log.info, log.error, log.warn or log.debug from @Slf4j I want XPATH to catch that case. To prevent a parameter not being used (including for logs)
The AST tree generated was this:
└─ CompilationUnit
└─ ClassOrInterfaceDeclaration
├─ ModifierList
└─ ClassOrInterfaceBody
├─ MethodDeclaration
│ ├─ ModifierList
│ ├─ VoidType
│ ├─ FormalParameters
│ │ └─ FormalParameter
│ │ ├─ ModifierList
│ │ ├─ ClassOrInterfaceType
│ │ └─ VariableDeclaratorId
│ └─ Block
│ └─ ExpressionStatement
│ └─ MethodCall
│ ├─ AmbiguousName
│ └─ ArgumentList
│ └─ VariableAccess
└─ MethodDeclaration
├─ ModifierList
├─ VoidType
├─ FormalParameters
└─ Block
└─ ExpressionStatement
└─ MethodCall
├─ AmbiguousName
└─ ArgumentList
public void test(final String value) {
log.info(value);
// must take
}
public void method(final String value) {
log.info(value);
this.otherMethod(value);
// must not take
}
public void method() {
log.info("value");
// must not take
}
I've tried many things, the last attempt was this but without success:
//MethodDeclaration[string(FormalParameters/FormalParameter/VariableDeclaratorId/@name) = string(//MethodCall/ArgumentList/VariableAccess/@name) and Block/ExpressionStatement/MethodCall]
Given this java code
This XPath expression will detect
detectMeanddetectMe2methodsCan be tested generating an AST XML dump
And then testing the XPath
Result
Xpath expression parts applied as comments
Right side of the equal could also be more precise by adding possible names as
(@MethodName="info" or @MethodName="debug")./Block[@Size=1]//MethodCall[(@MethodName="info" or @MethodName="debug") and AmbiguousName/@Name ="log"