PMD自定义规则,用于检测StringBuffer的追加操作

时间:2012-01-31 14:12:58

标签: xpath abstract-syntax-tree pmd

我正在尝试检测是否使用了StringBuffer,以及是否调用了append方法。所以,我的方法如下。但我还没有找到解决方案。

期待寻求帮助。

xPath准备好了:

//PrimaryExpression/PrimaryPrefix/Name[contains(@Image,'append') and contains(@Image,
//LocalVariableDeclaration[descendant::ClassOrInterfaceType[@Image='StringBuffer']]
/VariableDeclarator/VariableDeclaratorId/@Image)]

测试输入

public class pmdTestSomeCollection {
    StringBuffer sb11 = new StringBuffer("abcdeeee");
      public static void main(String args[]) {
        StringBuffer sb1 = new StringBuffer("abcde");
        sb1.append("abcdefghij");
        StringBuffer sb2 = sb1.reverse();
         sb2.append("A");
        System.out.println(sb1);
        System.out.println(sb2);
     }
}

生成的XML(抽象语法树)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<CompilationUnit BeginColumn="1" BeginLine="1" EndColumn="1" EndLine="10" Image="" Label="" declarationsAreInDefaultPackage="true">
    <TypeDeclaration BeginColumn="1" BeginLine="1" EndColumn="1" EndLine="10" Image="" Label="">
        <ClassOrInterfaceDeclaration Abstract="false" BeginColumn="8" BeginLine="1" EndColumn="1" EndLine="10" Final="false" Image="pmdTestSomeCollection" Interface="false" Label="" Modifiers="1" Native="false" Nested="false" PackagePrivate="false" Private="false" Protected="false" Public="true" Static="false" Strictfp="false" Synchronized="false" Transient="false" Volatile="false">
            <ClassOrInterfaceBody BeginColumn="36" BeginLine="1" EndColumn="1" EndLine="10" Image="" Label="">
                <ClassOrInterfaceBodyDeclaration AnonymousInnerClass="false" BeginColumn="1" BeginLine="2" EndColumn="49" EndLine="2" EnumChild="false" Image="" Label="">
                    <FieldDeclaration Abstract="false" Array="false" ArrayDepth="0" BeginColumn="1" BeginLine="2" EndColumn="49" EndLine="2" Final="false" Image="" InterfaceMember="false" Label="" Modifiers="0" Native="false" PackagePrivate="true" Private="false" Protected="false" Public="false" Static="false" Strictfp="false" Synchronized="false" SyntacticallyFinal="false" SyntacticallyPublic="false" SyntacticallyStatic="false" Transient="false" VariableName="sb11" Volatile="false">
                        <Type Array="false" ArrayDepth="0" BeginColumn="1" BeginLine="2" EndColumn="12" EndLine="2" Image="" Label="" TypeImage="StringBuffer">
                            <ReferenceType Array="false" ArrayDepth="0" BeginColumn="1" BeginLine="2" EndColumn="12" EndLine="2" Image="" Label="">
                                <ClassOrInterfaceType BeginColumn="1" BeginLine="2" EndColumn="12" EndLine="2" Image="StringBuffer" Label=""/>
                            </ReferenceType>
                        </Type>
                        <VariableDeclarator BeginColumn="14" BeginLine="2" EndColumn="48" EndLine="2" Image="" Label="">
                            <VariableDeclaratorId Array="false" ArrayDepth="0" BeginColumn="14" BeginLine="2" EndColumn="17" EndLine="2" ExceptionBlockParameter="false" Image="sb11" Label=""/>
                            <VariableInitializer BeginColumn="21" BeginLine="2" EndColumn="48" EndLine="2" Image="" Label="">
                                <Expression BeginColumn="21" BeginLine="2" EndColumn="48" EndLine="2" Image="" Label="">
                                    <PrimaryExpression BeginColumn="21" BeginLine="2" EndColumn="48" EndLine="2" Image="" Label="">
                                        <PrimaryPrefix BeginColumn="21" BeginLine="2" EndColumn="48" EndLine="2" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                            <AllocationExpression BeginColumn="21" BeginLine="2" EndColumn="48" EndLine="2" Image="" Label="">
                                                <ClassOrInterfaceType BeginColumn="25" BeginLine="2" EndColumn="36" EndLine="2" Image="StringBuffer" Label=""/>
                                                <Arguments ArgumentCount="1" BeginColumn="37" BeginLine="2" EndColumn="48" EndLine="2" Image="" Label="">
                                                    <ArgumentList BeginColumn="38" BeginLine="2" EndColumn="47" EndLine="2" Image="" Label="">
                                                        <Expression BeginColumn="38" BeginLine="2" EndColumn="47" EndLine="2" Image="" Label="">
                                                            <PrimaryExpression BeginColumn="38" BeginLine="2" EndColumn="47" EndLine="2" Image="" Label="">
                                                                <PrimaryPrefix BeginColumn="38" BeginLine="2" EndColumn="47" EndLine="2" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                                                    <Literal BeginColumn="38" BeginLine="2" CharLiteral="false" EndColumn="47" EndLine="2" FloatLiteral="false" Image="&quot;abcdeeee&quot;" IntLiteral="false" Label="" SingleCharacterStringLiteral="false" StringLiteral="true"/>
                                                                </PrimaryPrefix>
                                                            </PrimaryExpression>
                                                        </Expression>
                                                    </ArgumentList>
                                                </Arguments>
                                            </AllocationExpression>
                                        </PrimaryPrefix>
                                    </PrimaryExpression>
                                </Expression>
                            </VariableInitializer>
                        </VariableDeclarator>
                    </FieldDeclaration>
                </ClassOrInterfaceBodyDeclaration>
                <ClassOrInterfaceBodyDeclaration AnonymousInnerClass="false" BeginColumn="3" BeginLine="3" EndColumn="3" EndLine="9" EnumChild="false" Image="" Label="">
                    <MethodDeclaration Abstract="false" BeginColumn="17" BeginLine="3" EndColumn="3" EndLine="9" Final="false" Image="" InterfaceMember="false" Label="" MethodName="main" Modifiers="17" Native="false" PackagePrivate="false" Private="false" Protected="false" Public="true" Static="true" Strictfp="false" Synchronized="false" SyntacticallyAbstract="false" SyntacticallyPublic="true" Transient="false" Void="true" Volatile="false">
                        <ResultType BeginColumn="17" BeginLine="3" EndColumn="20" EndLine="3" Image="" Label="" Void="true" returnsArray="false"/>
                        <MethodDeclarator BeginColumn="22" BeginLine="3" EndColumn="40" EndLine="3" Image="main" Label="" ParameterCount="1">
                            <FormalParameters BeginColumn="26" BeginLine="3" EndColumn="40" EndLine="3" Image="" Label="" ParameterCount="1">
                                <FormalParameter Abstract="false" Array="true" ArrayDepth="1" BeginColumn="27" BeginLine="3" EndColumn="39" EndLine="3" Final="false" Image="" Label="" Modifiers="0" Native="false" PackagePrivate="true" Private="false" Protected="false" Public="false" Static="false" Strictfp="false" Synchronized="false" Transient="false" Varargs="false" Volatile="false">
                                    <Type Array="false" ArrayDepth="0" BeginColumn="27" BeginLine="3" EndColumn="32" EndLine="3" Image="" Label="" TypeImage="String">
                                        <ReferenceType Array="false" ArrayDepth="0" BeginColumn="27" BeginLine="3" EndColumn="32" EndLine="3" Image="" Label="">
                                            <ClassOrInterfaceType BeginColumn="27" BeginLine="3" EndColumn="32" EndLine="3" Image="String" Label=""/>
                                        </ReferenceType>
                                    </Type>
                                    <VariableDeclaratorId Array="true" ArrayDepth="1" BeginColumn="34" BeginLine="3" EndColumn="39" EndLine="3" ExceptionBlockParameter="false" Image="args" Label=""/>
                                </FormalParameter>
                            </FormalParameters>
                        </MethodDeclarator>
                        <Block BeginColumn="42" BeginLine="3" EndColumn="3" EndLine="9" Image="" Label="" containsComment="false">
                            <BlockStatement Allocation="true" BeginColumn="5" BeginLine="4" EndColumn="49" EndLine="4" Image="" Label="">
                                <LocalVariableDeclaration Abstract="false" Array="false" ArrayDepth="0" BeginColumn="5" BeginLine="4" EndColumn="48" EndLine="4" Final="false" Image="" Label="" Modifiers="0" Native="false" PackagePrivate="true" Private="false" Protected="false" Public="false" Static="false" Strictfp="false" Synchronized="false" Transient="false" VariableName="sb1" Volatile="false">
                                    <Type Array="false" ArrayDepth="0" BeginColumn="5" BeginLine="4" EndColumn="16" EndLine="4" Image="" Label="" TypeImage="StringBuffer">
                                        <ReferenceType Array="false" ArrayDepth="0" BeginColumn="5" BeginLine="4" EndColumn="16" EndLine="4" Image="" Label="">
                                            <ClassOrInterfaceType BeginColumn="5" BeginLine="4" EndColumn="16" EndLine="4" Image="StringBuffer" Label=""/>
                                        </ReferenceType>
                                    </Type>
                                    <VariableDeclarator BeginColumn="18" BeginLine="4" EndColumn="48" EndLine="4" Image="" Label="">
                                        <VariableDeclaratorId Array="false" ArrayDepth="0" BeginColumn="18" BeginLine="4" EndColumn="20" EndLine="4" ExceptionBlockParameter="false" Image="sb1" Label=""/>
                                        <VariableInitializer BeginColumn="24" BeginLine="4" EndColumn="48" EndLine="4" Image="" Label="">
                                            <Expression BeginColumn="24" BeginLine="4" EndColumn="48" EndLine="4" Image="" Label="">
                                                <PrimaryExpression BeginColumn="24" BeginLine="4" EndColumn="48" EndLine="4" Image="" Label="">
                                                    <PrimaryPrefix BeginColumn="24" BeginLine="4" EndColumn="48" EndLine="4" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                                        <AllocationExpression BeginColumn="24" BeginLine="4" EndColumn="48" EndLine="4" Image="" Label="">
                                                            <ClassOrInterfaceType BeginColumn="28" BeginLine="4" EndColumn="39" EndLine="4" Image="StringBuffer" Label=""/>
                                                            <Arguments ArgumentCount="1" BeginColumn="40" BeginLine="4" EndColumn="48" EndLine="4" Image="" Label="">
                                                                <ArgumentList BeginColumn="41" BeginLine="4" EndColumn="47" EndLine="4" Image="" Label="">
                                                                    <Expression BeginColumn="41" BeginLine="4" EndColumn="47" EndLine="4" Image="" Label="">
                                                                        <PrimaryExpression BeginColumn="41" BeginLine="4" EndColumn="47" EndLine="4" Image="" Label="">
                                                                            <PrimaryPrefix BeginColumn="41" BeginLine="4" EndColumn="47" EndLine="4" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                                                                <Literal BeginColumn="41" BeginLine="4" CharLiteral="false" EndColumn="47" EndLine="4" FloatLiteral="false" Image="&quot;abcde&quot;" IntLiteral="false" Label="" SingleCharacterStringLiteral="false" StringLiteral="true"/>
                                                                            </PrimaryPrefix>
                                                                        </PrimaryExpression>
                                                                    </Expression>
                                                                </ArgumentList>
                                                            </Arguments>
                                                        </AllocationExpression>
                                                    </PrimaryPrefix>
                                                </PrimaryExpression>
                                            </Expression>
                                        </VariableInitializer>
                                    </VariableDeclarator>
                                </LocalVariableDeclaration>
                            </BlockStatement>
                            <BlockStatement Allocation="false" BeginColumn="5" BeginLine="5" EndColumn="29" EndLine="5" Image="" Label="">
                                <Statement BeginColumn="5" BeginLine="5" EndColumn="29" EndLine="5" Image="" Label="">
                                    <StatementExpression BeginColumn="5" BeginLine="5" EndColumn="28" EndLine="5" Image="" Label="">
                                        <PrimaryExpression BeginColumn="5" BeginLine="5" EndColumn="28" EndLine="5" Image="" Label="">
                                            <PrimaryPrefix BeginColumn="5" BeginLine="5" EndColumn="14" EndLine="5" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                                <Name BeginColumn="5" BeginLine="5" EndColumn="14" EndLine="5" Image="sb1.append" Label=""/>
                                            </PrimaryPrefix>
                                            <PrimarySuffix ArgumentCount="1" Arguments="true" ArrayDereference="false" BeginColumn="15" BeginLine="5" EndColumn="28" EndLine="5" Image="" Label="">
                                                <Arguments ArgumentCount="1" BeginColumn="15" BeginLine="5" EndColumn="28" EndLine="5" Image="" Label="">
                                                    <ArgumentList BeginColumn="16" BeginLine="5" EndColumn="27" EndLine="5" Image="" Label="">
                                                        <Expression BeginColumn="16" BeginLine="5" EndColumn="27" EndLine="5" Image="" Label="">
                                                            <PrimaryExpression BeginColumn="16" BeginLine="5" EndColumn="27" EndLine="5" Image="" Label="">
                                                                <PrimaryPrefix BeginColumn="16" BeginLine="5" EndColumn="27" EndLine="5" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                                                    <Literal BeginColumn="16" BeginLine="5" CharLiteral="false" EndColumn="27" EndLine="5" FloatLiteral="false" Image="&quot;abcdefghij&quot;" IntLiteral="false" Label="" SingleCharacterStringLiteral="false" StringLiteral="true"/>
                                                                </PrimaryPrefix>
                                                            </PrimaryExpression>
                                                        </Expression>
                                                    </ArgumentList>
                                                </Arguments>
                                            </PrimarySuffix>
                                        </PrimaryExpression>
                                    </StatementExpression>
                                </Statement>
                            </BlockStatement>
                            <BlockStatement Allocation="false" BeginColumn="5" BeginLine="6" EndColumn="37" EndLine="6" Image="" Label="">
                                <LocalVariableDeclaration Abstract="false" Array="false" ArrayDepth="0" BeginColumn="5" BeginLine="6" EndColumn="36" EndLine="6" Final="false" Image="" Label="" Modifiers="0" Native="false" PackagePrivate="true" Private="false" Protected="false" Public="false" Static="false" Strictfp="false" Synchronized="false" Transient="false" VariableName="sb2" Volatile="false">
                                    <Type Array="false" ArrayDepth="0" BeginColumn="5" BeginLine="6" EndColumn="16" EndLine="6" Image="" Label="" TypeImage="StringBuffer">
                                        <ReferenceType Array="false" ArrayDepth="0" BeginColumn="5" BeginLine="6" EndColumn="16" EndLine="6" Image="" Label="">
                                            <ClassOrInterfaceType BeginColumn="5" BeginLine="6" EndColumn="16" EndLine="6" Image="StringBuffer" Label=""/>
                                        </ReferenceType>
                                    </Type>
                                    <VariableDeclarator BeginColumn="18" BeginLine="6" EndColumn="36" EndLine="6" Image="" Label="">
                                        <VariableDeclaratorId Array="false" ArrayDepth="0" BeginColumn="18" BeginLine="6" EndColumn="20" EndLine="6" ExceptionBlockParameter="false" Image="sb2" Label=""/>
                                        <VariableInitializer BeginColumn="24" BeginLine="6" EndColumn="36" EndLine="6" Image="" Label="">
                                            <Expression BeginColumn="24" BeginLine="6" EndColumn="36" EndLine="6" Image="" Label="">
                                                <PrimaryExpression BeginColumn="24" BeginLine="6" EndColumn="36" EndLine="6" Image="" Label="">
                                                    <PrimaryPrefix BeginColumn="24" BeginLine="6" EndColumn="34" EndLine="6" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                                        <Name BeginColumn="24" BeginLine="6" EndColumn="34" EndLine="6" Image="sb1.reverse" Label=""/>
                                                    </PrimaryPrefix>
                                                    <PrimarySuffix ArgumentCount="0" Arguments="true" ArrayDereference="false" BeginColumn="35" BeginLine="6" EndColumn="36" EndLine="6" Image="" Label="">
                                                        <Arguments ArgumentCount="0" BeginColumn="35" BeginLine="6" EndColumn="36" EndLine="6" Image="" Label=""/>
                                                    </PrimarySuffix>
                                                </PrimaryExpression>
                                            </Expression>
                                        </VariableInitializer>
                                    </VariableDeclarator>
                                </LocalVariableDeclaration>
                            </BlockStatement>
                            <BlockStatement Allocation="false" BeginColumn="5" BeginLine="7" EndColumn="28" EndLine="7" Image="" Label="">
                                <Statement BeginColumn="5" BeginLine="7" EndColumn="28" EndLine="7" Image="" Label="">
                                    <StatementExpression BeginColumn="5" BeginLine="7" EndColumn="27" EndLine="7" Image="" Label="">
                                        <PrimaryExpression BeginColumn="5" BeginLine="7" EndColumn="27" EndLine="7" Image="" Label="">
                                            <PrimaryPrefix BeginColumn="5" BeginLine="7" EndColumn="22" EndLine="7" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                                <Name BeginColumn="5" BeginLine="7" EndColumn="22" EndLine="7" Image="System.out.println" Label=""/>
                                            </PrimaryPrefix>
                                            <PrimarySuffix ArgumentCount="1" Arguments="true" ArrayDereference="false" BeginColumn="23" BeginLine="7" EndColumn="27" EndLine="7" Image="" Label="">
                                                <Arguments ArgumentCount="1" BeginColumn="23" BeginLine="7" EndColumn="27" EndLine="7" Image="" Label="">
                                                    <ArgumentList BeginColumn="24" BeginLine="7" EndColumn="26" EndLine="7" Image="" Label="">
                                                        <Expression BeginColumn="24" BeginLine="7" EndColumn="26" EndLine="7" Image="" Label="">
                                                            <PrimaryExpression BeginColumn="24" BeginLine="7" EndColumn="26" EndLine="7" Image="" Label="">
                                                                <PrimaryPrefix BeginColumn="24" BeginLine="7" EndColumn="26" EndLine="7" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                                                    <Name BeginColumn="24" BeginLine="7" EndColumn="26" EndLine="7" Image="sb1" Label=""/>
                                                                </PrimaryPrefix>
                                                            </PrimaryExpression>
                                                        </Expression>
                                                    </ArgumentList>
                                                </Arguments>
                                            </PrimarySuffix>
                                        </PrimaryExpression>
                                    </StatementExpression>
                                </Statement>
                            </BlockStatement>
                            <BlockStatement Allocation="false" BeginColumn="5" BeginLine="8" EndColumn="28" EndLine="8" Image="" Label="">
                                <Statement BeginColumn="5" BeginLine="8" EndColumn="28" EndLine="8" Image="" Label="">
                                    <StatementExpression BeginColumn="5" BeginLine="8" EndColumn="27" EndLine="8" Image="" Label="">
                                        <PrimaryExpression BeginColumn="5" BeginLine="8" EndColumn="27" EndLine="8" Image="" Label="">
                                            <PrimaryPrefix BeginColumn="5" BeginLine="8" EndColumn="22" EndLine="8" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                                <Name BeginColumn="5" BeginLine="8" EndColumn="22" EndLine="8" Image="System.out.println" Label=""/>
                                            </PrimaryPrefix>
                                            <PrimarySuffix ArgumentCount="1" Arguments="true" ArrayDereference="false" BeginColumn="23" BeginLine="8" EndColumn="27" EndLine="8" Image="" Label="">
                                                <Arguments ArgumentCount="1" BeginColumn="23" BeginLine="8" EndColumn="27" EndLine="8" Image="" Label="">
                                                    <ArgumentList BeginColumn="24" BeginLine="8" EndColumn="26" EndLine="8" Image="" Label="">
                                                        <Expression BeginColumn="24" BeginLine="8" EndColumn="26" EndLine="8" Image="" Label="">
                                                            <PrimaryExpression BeginColumn="24" BeginLine="8" EndColumn="26" EndLine="8" Image="" Label="">
                                                                <PrimaryPrefix BeginColumn="24" BeginLine="8" EndColumn="26" EndLine="8" Image="" Label="" SuperModifier="false" ThisModifier="false">
                                                                    <Name BeginColumn="24" BeginLine="8" EndColumn="26" EndLine="8" Image="sb2" Label=""/>
                                                                </PrimaryPrefix>
                                                            </PrimaryExpression>
                                                        </Expression>
                                                    </ArgumentList>
                                                </Arguments>
                                            </PrimarySuffix>
                                        </PrimaryExpression>
                                    </StatementExpression>
                                </Statement>
                            </BlockStatement>
                        </Block>
                    </MethodDeclaration>
                </ClassOrInterfaceBodyDeclaration>
            </ClassOrInterfaceBody>
        </ClassOrInterfaceDeclaration>
    </TypeDeclaration>
</CompilationUnit>

1 个答案:

答案 0 :(得分:0)

我认为它不可能,它适用于任何方法中声明的一个局部变量和任何类中的第一个参数。这里的一个大问题是,一旦您进入谓词并指定了将返回多个节点的路径,谓词将仅应用于第一个节点。

例如,在下面的代码中,// LocalVariableDeclaration /.../VariableDeclaratorId应该与所有局部变量进行比较,但它只匹配与String缓冲区谓词匹配的第一个LocalVariable。在XPath 2.0中有一个for构造支持这些类型的查询,但PMD目前还不支持它。

... and contains(@Image, 
//LocalVariableDeclaration[descendant::ClassOrInterfaceType[@Image='StringBuffer']]
/VariableDeclarator/VariableDeclaratorId/@Image)]