我想创建一个SonarQube XPath自定义规则,该规则检测(使用SSLR java工具包)所有未声明给定方法的类。我希望能够用[not(contains(...))]
来做,但我被卡住了。
例如,如何检测所有未声明public String toString()
方法的类?
//typeDeclaration//classDeclaration (that do not contain a memberDecl of type String, that has an IDENTIFIER with value "toString" and has no formal parameters)
下面是一个包含该方法的java示例类(这个类不应该与XPath表达式匹配)
public class Example {
public String toString() {
return "";
}
}
下面是与示例java类的AST对应的XML代码。
<compilationUnit tokenValue="public" tokenLine="1" tokenColumn="0">
<typeDeclaration tokenValue="public" tokenLine="1" tokenColumn="0">
<modifier tokenValue="public" tokenLine="1" tokenColumn="0">
<PUBLIC tokenValue="public" tokenLine="1" tokenColumn="0">
<TOKEN tokenValue="public" tokenLine="1" tokenColumn="0"/>
</PUBLIC>
</modifier>
<classDeclaration tokenValue="class" tokenLine="1" tokenColumn="7">
<CLASS tokenValue="class" tokenLine="1" tokenColumn="7">
<TOKEN tokenValue="class" tokenLine="1" tokenColumn="7"/>
</CLASS>
<IDENTIFIER tokenValue="Example" tokenLine="1" tokenColumn="13">
<TOKEN tokenValue="Example" tokenLine="1" tokenColumn="13"/>
</IDENTIFIER>
<classBody tokenValue="{" tokenLine="1" tokenColumn="21">
<LWING tokenValue="{" tokenLine="1" tokenColumn="21">
<TOKEN tokenValue="{" tokenLine="1" tokenColumn="21"/>
</LWING>
<classBodyDeclaration tokenValue="public" tokenLine="2" tokenColumn="2">
<modifier tokenValue="public" tokenLine="2" tokenColumn="2">
<PUBLIC tokenValue="public" tokenLine="2" tokenColumn="2">
<TOKEN tokenValue="public" tokenLine="2" tokenColumn="2"/>
</PUBLIC>
</modifier>
<memberDecl tokenValue="String" tokenLine="2" tokenColumn="9">
<type tokenValue="String" tokenLine="2" tokenColumn="9">
<classType tokenValue="String" tokenLine="2" tokenColumn="9">
<IDENTIFIER tokenValue="String" tokenLine="2" tokenColumn="9">
<TOKEN tokenValue="String" tokenLine="2" tokenColumn="9"/>
</IDENTIFIER>
</classType>
</type>
<IDENTIFIER tokenValue="toString" tokenLine="2" tokenColumn="16">
<TOKEN tokenValue="toString" tokenLine="2" tokenColumn="16"/>
</IDENTIFIER>
<methodDeclaratorRest tokenValue="(" tokenLine="2" tokenColumn="24">
<formalParameters tokenValue="(" tokenLine="2" tokenColumn="24">
<LPAR tokenValue="(" tokenLine="2" tokenColumn="24">
<TOKEN tokenValue="(" tokenLine="2" tokenColumn="24"/>
</LPAR>
<RPAR tokenValue=")" tokenLine="2" tokenColumn="25">
<TOKEN tokenValue=")" tokenLine="2" tokenColumn="25"/>
</RPAR>
</formalParameters>
<methodBody tokenValue="{" tokenLine="2" tokenColumn="27">
<block tokenValue="{" tokenLine="2" tokenColumn="27">
<LWING tokenValue="{" tokenLine="2" tokenColumn="27">
<TOKEN tokenValue="{" tokenLine="2" tokenColumn="27"/>
</LWING>
<blockStatements tokenValue="return" tokenLine="3" tokenColumn="4">
<blockStatement tokenValue="return" tokenLine="3" tokenColumn="4">
<statement tokenValue="return" tokenLine="3" tokenColumn="4">
<returnStatement tokenValue="return" tokenLine="3" tokenColumn="4">
<RETURN tokenValue="return" tokenLine="3" tokenColumn="4">
<TOKEN tokenValue="return" tokenLine="3" tokenColumn="4"/>
</RETURN>
<expression tokenValue="""" tokenLine="3" tokenColumn="11">
<primary tokenValue="""" tokenLine="3" tokenColumn="11">
<literal tokenValue="""" tokenLine="3" tokenColumn="11">
<LITERAL tokenValue="""" tokenLine="3" tokenColumn="11">
<TOKEN tokenValue="""" tokenLine="3" tokenColumn="11"/>
</LITERAL>
</literal>
</primary>
</expression>
<SEMI tokenValue=";" tokenLine="3" tokenColumn="13">
<TOKEN tokenValue=";" tokenLine="3" tokenColumn="13"/>
</SEMI>
</returnStatement>
</statement>
</blockStatement>
</blockStatements>
<RWING tokenValue="}" tokenLine="4" tokenColumn="2">
<TOKEN tokenValue="}" tokenLine="4" tokenColumn="2"/>
</RWING>
</block>
</methodBody>
</methodDeclaratorRest>
</memberDecl>
</classBodyDeclaration>
<RWING tokenValue="}" tokenLine="5" tokenColumn="0">
<TOKEN tokenValue="}" tokenLine="5" tokenColumn="0"/>
</RWING>
</classBody>
</classDeclaration>
</typeDeclaration>
<EOF tokenValue="" tokenLine="5" tokenColumn="1"/>
</compilationUnit>
提前谢谢。
答案 0 :(得分:0)
以下是我自己问题的解决方案:
//classBody[not(//memberDecl[type[@tokenValue='String'] and IDENTIFIER[@tokenValue='toString'] and methodDeclaratorRest/formalParameters[not(formalParameterDecls)]])]