combine two PMD checks

2019-08-09 06:34发布

I met a problem while using PMD to check my code errors. I do not know how to satisfy two requirements at the same time. For example, if I want to check a method named ABC not existing in file extends from BCD. I know how to check whether ABC exists or whether it extends from BCD separately using PMD.

Like this:

//PrimaryExpression/PrimaryPrefix/Name [@Image = "ABC"];
//ExtendsList/ClassOrInterfaceType [@Image != "BCD"];

now, is there anyway that I can check these two together. For example, I want it no ABC in class extends BCD. It seems I cannot simply use things like and to connect this two Xpath queries. Also, I noticed I can use | to get connected with them, but | works as or. I need an and here instead of or.

Edit:

I tried something like this:

//PrimaryExpression/PrimaryPrefix/Name[@Image = "ABC"]
 [//ancestor::ClassOrInterfaceDeclaration/ExtendsList/
                                     ClassOrInterfaceType[@Image != "BCD"]]

Which seems like it works for me at least. But I am still not 100% sure if this is the correct way since I just tried this out.

1条回答
劳资没心,怎么记你
2楼-- · 2019-08-09 07:11

Your edit should work, although note that ancestor axis will recurse all parent nodes, so it should not be introduced with '//'.

Another alternative is to base the Xpath from a common ancestor (e.g. ClassOrInterfaceDeclaration) and then use and to ensure the two criteria are met. Since it seems that you are merely testing for the presence of a node meeting both criteria, I guess it doesn't really matter what the resultant expression / node-set actually returns:

//ClassOrInterfaceDeclaration[ExtendsList/ClassOrInterfaceType[@Image != "BCD"] 
                  and descendant::PrimaryExpression/PrimaryPrefix/Name[@Image = "ABC"]]

If however you do need to select a specific node upon success, just append the node's path, relative to ClassOrInterfaceDeclaration:

//ClassOrInterfaceDeclaration[... predicate ...]/Some/Path/Here

You could also apply a function like count() to determine the number of nodes meeting the criteria:

count(//ClassOrInterfaceDeclaration[... predicate ...])

And then evaluate the expression.

(Caveat - I'm not familiar with the PMD layout)

I've put some examples showing the effects of //ancestor:: vs ancestor:: and my alternative.

查看更多
登录 后发表回答