I want to identify print statements that are not inside the conditional statements (i.e., to check if the print statement has any if statement as its ancestor)
few test cases are as follows :
int x = 5;
int y = 10;
System.out.println("The value of x is " + x);
System.out.println("The value of y is " + y);
if (x > 10) {
System.out.println("x is greater than 10");
}
System.out.println("This is the end of the program");
I have tried the below Xpath expressions but have had no luck could anyone help me out with it?
//Name[@Image='System']/following-sibling::Name[@Image='out']/following-sibling::Name[@Image='println'][not(ancestor::IfStatement)]
//Name[@Image='System']/descendant-or-self::Name[@Image='println'][not(ancestor::IfStatement)]
//Name[@Image='System']/child::Name[@Image='println'][not(ancestor::IfStatement)]
//attribute::Image[.='System']/parent::Name/following-sibling::Name[attribute::Image='out']/following-sibling::Name[attribute::Image='println'][not(ancestor::IfStatement)]
//Name[@Image='System']/preceding-sibling::Name[@Image='out']/preceding-sibling::Name[@Image='println'][not(ancestor::IfStatement)]
Please note I am using PMD rule designer from PMD to test the XPath expressions.
Thanks in advance.
After 3 days of beating my head, I finally figured it out. I'm not too fond of the documentation of the PMD
anyways here is the solution
//MethodCall[ starts-with(@MethodName, 'print') ]
/FieldAccess[ @Name = ('err', 'out') ]
/TypeExpression[ pmd-java:typeIsExactly('java.lang.System') ]
[not(ancestor::IfStatement[VariableAccess[@Name = 'verbose']])]
This expression is used to select the print statements in Java code that are not inside an if statement whose condition is not verbose. Let me break it down for you:
//MethodCall[ starts-with(@MethodName, 'print') ]
: This part selects all the method calls that start with the word print, such as println, printf, or printStackTrace.
/FieldAccess[ @Name = ('err', 'out') ]
: This part selects the field accesses that have the name err or out, such as System.err or System.out.
/TypeExpression[ pmd-java:typeIsExactly('java.lang.System') ]
: This part selects the type expressions that are exactly the java.lang.System class, such as System or (System).
[not(ancestor::IfStatement[VariableAccess[@Name != 'verbose']])]
: This part filters out the nodes that have an ancestor (parent, grandparent, etc.) that is an if statement whose condition is a variable access with a name that is not verbose, such as if (DEBUG) or if (flag).