2012-01-25 2 views
1

약 4 시간이 걸렸지 만 XPath는 상당히 독창적 인 사용자 지정 규칙을 개발할 때 매우 힘들었습니다.XPD를 통한 PMD PrimaryPrefix 문제

내 문제의 한 부분에 대해 다음 줄을 구별 할 수 있도록 PMD XPath가 필요합니다. int var = this.nocall; int var = nocall;

AST에서

, 내가 볼 것을 PrimaryPrefix이 하지만 // PrimaryPrefix [ '이'] 또는 // PrimaryExpression/PrimaryPrefix [ '이]] 또는 // PrimaryPrefix [@image으로 첫 번째 문을 선택할 수 없습니다입니다 = 'this']

누구나 'this'로 모든 표현식을 검색하는 방법에 대한 힌트가 있는지 궁금합니다. XPath를 통해 할당 부분.

<MethodDeclaration Abstract="false" BeginColumn="16" BeginLine="3" EndColumn="9" EndLine="6" Final="false" Image="" InterfaceMember="false" Label="" MethodName="myMethod" Modifiers="1" Native="false" PackagePrivate="false" Private="false" Protected="false" Public="true" Static="false" Strictfp="false" Synchronized="false" SyntacticallyAbstract="false" SyntacticallyPublic="true" Transient="false" Void="true" Volatile="false"> 
        <ResultType BeginColumn="16" BeginLine="3" EndColumn="19" EndLine="3" Image="" Label="" Void="true" returnsArray="false"/> 
        <MethodDeclarator BeginColumn="21" BeginLine="3" EndColumn="30" EndLine="3" Image="myMethod" Label="" ParameterCount="0"> 
         <FormalParameters BeginColumn="29" BeginLine="3" EndColumn="30" EndLine="3" Image="" Label="" ParameterCount="0"/> 
        </MethodDeclarator> 
        <Block BeginColumn="32" BeginLine="3" EndColumn="9" EndLine="6" Image="" Label="" containsComment="false"> 
         <BlockStatement Allocation="false" BeginColumn="17" BeginLine="4" EndColumn="38" EndLine="4" Image="" Label=""> 
          <LocalVariableDeclaration Abstract="false" Array="false" ArrayDepth="0" BeginColumn="17" BeginLine="4" EndColumn="37" 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="var" Volatile="false"> 
           <Type Array="false" ArrayDepth="0" BeginColumn="17" BeginLine="4" EndColumn="19" EndLine="4" Image="" Label="" TypeImage="int"> 
            <PrimitiveType Array="false" ArrayDepth="0" BeginColumn="17" BeginLine="4" Boolean="false" EndColumn="19" EndLine="4" Image="int" Label=""/> 
           </Type> 
           <VariableDeclarator BeginColumn="21" BeginLine="4" EndColumn="37" EndLine="4" Image="" Label=""> 
            <VariableDeclaratorId Array="false" ArrayDepth="0" BeginColumn="21" BeginLine="4" EndColumn="23" EndLine="4" ExceptionBlockParameter="false" Image="var" Label=""/> 
            <VariableInitializer BeginColumn="27" BeginLine="4" EndColumn="37" EndLine="4" Image="" Label=""> 
             <Expression BeginColumn="27" BeginLine="4" EndColumn="37" EndLine="4" Image="" Label=""> 
              <PrimaryExpression BeginColumn="27" BeginLine="4" EndColumn="37" EndLine="4" Image="" Label=""> 
               <PrimaryPrefix BeginColumn="27" BeginLine="4" EndColumn="30" EndLine="4" Image="" Label="this" SuperModifier="false" ThisModifier="true"/> 
               <PrimarySuffix ArgumentCount="" Arguments="false" ArrayDereference="false" BeginColumn="31" BeginLine="4" EndColumn="37" EndLine="4" Image="nocall" Label=""/> 
              </PrimaryExpression> 
             </Expression> 
            </VariableInitializer> 
           </VariableDeclarator> 
          </LocalVariableDeclaration> 
         </BlockStatement> 
         <BlockStatement Allocation="false" BeginColumn="17" BeginLine="5" EndColumn="39" EndLine="5" Image="" Label=""> 

답변

2

, 나는 ThisModifier 사용합니다 - 그 이유는, 그 레이블 더 이상 PMD 5에서 사용할 수 없습니다. 레이블은 문자열 표현입니다 (toString()과 유사).

//PrimaryExpression[PrimaryPrefix/@ThisModifier='true'] 

이것은 PMD 4.x와 향후 PMD 5 모두에서 작동하므로 규칙을 수정하지 않아도됩니다.

다음을 참조하십시오. https://sourceforge.net/projects/pmd/forums/forum/188194/topic/4971141

+0

이것은 내가 알지 못했던 몇 가지 새로운 정보입니다. Count (노드 집합)를 사용하여 PrimaryPrefix/Name이 FieldDelcaration 중 하나인지 확인하는 방법에 대해 알고 있습니까? 나는 하루 동안 아무런 결과도 찾지 못했다. 코드가 이상해질 것이므로 Java PMD 규칙을 다룰 필요가 없으면 좋겠습니다. – ttback

1

사용 :

class testRuleOne { 
    private int nocall; 
    public void myMethod() { 
     int var = this.nocall; 
     var = this.getNoCall(); 
    } 
} 

여기에 AST의 원시 XML의 : 구문 분석하려고

예제 코드

//PrimaryExpression[PrimaryPrefix/@Label='this'] 

이 XPath 식을 평가하는 경우 제공된 XML (그것은 심각하게 잘못된 것입니다,하지만 난 그것을 수정) :

<MethodDeclaration Abstract="false" BeginColumn="16" 
    BeginLine="3" EndColumn="9" EndLine="6" Final="false" 
    Image="" InterfaceMember="false" Label="" 
    MethodName="myMethod" Modifiers="1" Native="false" 
    PackagePrivate="false" Private="false" Protected="false" 
    Public="true" Static="false" Strictfp="false" 
    Synchronized="false" SyntacticallyAbstract="false" 
    SyntacticallyPublic="true" Transient="false" Void="true" Volatile="false"> 
    <ResultType BeginColumn="16" BeginLine="3" EndColumn="19" 
     EndLine="3" Image="" Label="" Void="true" returnsArray="false"/> 

    <MethodDeclarator BeginColumn="21" BeginLine="3" 
     EndColumn="30" EndLine="3" Image="myMethod" 
     Label="" ParameterCount="0"> 
     <FormalParameters BeginColumn="29" BeginLine="3" 
      EndColumn="30" EndLine="3" Image="" 
      Label="" ParameterCount="0"/> 
    </MethodDeclarator> 

    <Block BeginColumn="32" BeginLine="3" EndColumn="9" EndLine="6" Image="" Label="" containsComment="false"> 
     <BlockStatement Allocation="false" BeginColumn="17" BeginLine="4" EndColumn="38" EndLine="4" Image="" Label=""> 
      <LocalVariableDeclaration Abstract="false" Array="false" ArrayDepth="0" BeginColumn="17" BeginLine="4" EndColumn="37" 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="var" Volatile="false"> 
       <Type Array="false" ArrayDepth="0" BeginColumn="17" BeginLine="4" EndColumn="19" EndLine="4" Image="" Label="" TypeImage="int"> 
        <PrimitiveType Array="false" ArrayDepth="0" BeginColumn="17" BeginLine="4" Boolean="false" EndColumn="19" EndLine="4" Image="int" Label=""/> 
       </Type> 
       <VariableDeclarator BeginColumn="21" BeginLine="4" EndColumn="37" EndLine="4" Image="" Label=""> 
        <VariableDeclaratorId Array="false" ArrayDepth="0" BeginColumn="21" BeginLine="4" EndColumn="23" EndLine="4" ExceptionBlockParameter="false" Image="var" Label=""/> 
        <VariableInitializer BeginColumn="27" BeginLine="4" EndColumn="37" EndLine="4" Image="" Label=""> 
         <Expression BeginColumn="27" BeginLine="4" 
         EndColumn="37" EndLine="4" Image="" Label=""> 
          <PrimaryExpression BeginColumn="27" BeginLine="4" 
          EndColumn="37" EndLine="4" Image="" Label=""> 
           <PrimaryPrefix BeginColumn="27" BeginLine="4" 
           EndColumn="30" EndLine="4" Image="" 
           Label="this" SuperModifier="false" ThisModifier="true"/> 
           <PrimarySuffix ArgumentCount="" Arguments="false" 
           ArrayDereference="false" BeginColumn="31" 
           BeginLine="4" EndColumn="37" EndLine="4" Image="nocall" Label=""/> 
          </PrimaryExpression> 
         </Expression> 
        </VariableInitializer> 
       </VariableDeclarator> 
      </LocalVariableDeclaration> 
     </BlockStatement> 
     <BlockStatement Allocation="false" BeginColumn="17" BeginLine="5" EndColumn="39" 
          EndLine="5" Image="" Label=""/> 
    </Block> 
</MethodDeclaration> 

원하는 요소가 선택 :

대신 라벨의
<PrimaryExpression BeginColumn="27" 
    BeginLine="4" EndColumn="37" 
    EndLine="4" Image="" Label=""> 

    <PrimaryPrefix BeginColumn="27" 
     BeginLine="4" EndColumn="30" EndLine="4" Image="" 
     Label="this" SuperModifier="false" 
     ThisModifier="true"/> 

    <PrimarySuffix ArgumentCount="" Arguments="false" 
     ArrayDereference="false" BeginColumn="31" BeginLine="4" 
     EndColumn="37" EndLine="4" Image="nocall" Label=""/> 
</PrimaryExpression>