Issue
For example:
String user = "Daniel";
String result = doSomething(user);
I know I can find every occurence of doSomething(user) with //MethodCall[@MethodName = "doSomething"]/ArgumentList/VariableAccess[@Name = "user"]. Is it possible to only find those occurences, where user evaluates to "Daniel" at the time the method is called?
Solution
Both MethodCall and VariableDeclarator are descendants of the same Block element. That can be used to match the criteria
//Block[//AssignmentExpression[last()][VariableAccess[@AccessType="WRITE" and @Name="user"]]/StringLiteral[@ConstValue="LMC"] or //VariableDeclarator[@Name="user"]/StringLiteral[@ConstValue="LMC"]]//MethodCall[@MethodName = "detectMe"]/ArgumentList/VariableAccess[@Name = "user"]
This expresion finds Block elements containing a variable user = "LMC" either only declared or last assigned.
//Block[//AssignmentExpression[last()][VariableAccess[@AccessType="WRITE" and @Name="user"]]/StringLiteral[@ConstValue="LMC"] or //VariableDeclarator[@Name="user"]/StringLiteral[@ConstValue="LMC"]]
Will match something like
public void useIt(){
String user = "LMC";
String result = detectMe(user);
}
public void useIt(2){
String user = "Daniel";
user = "osoo";
user = "LMC";
String result = detectMe(user);
}
As a general method, a test class with the relevant use case can be written and dumped with pmd for later XML analysis
pmd ast-dump --format xml --language java --file PMDSource.java > PMDSource.java.xml
then use any XPath aware tool to test the expression
xmllint --xpath '//Block[//AssignmentExpression[last()][VariableAccess[@AccessType="WRITE" and @Name="user"]]/StringLiteral[@ConstValue="LMC"] or //VariableDeclarator[@Name="user"]/StringLiteral[@ConstValue="LMC"]]//MethodCall[@MethodName = "detectMe"]/ArgumentList/VariableAccess[@Name = "user"]' PMDSource.java.xml
Result
<VariableAccess AccessType="READ" CompileTimeConstant="false" Expression="true" Image="user" Name="user" ParenthesisDepth="0" Parenthesized="false"/>
<VariableAccess AccessType="READ" CompileTimeConstant="false" Expression="true" Image="user" Name="user" ParenthesisDepth="0" Parenthesized="false"/>
Answered By - LMC
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.