如何在pmd中的一个规则中使用两个AST节点?

时间:2016-05-03 08:44:55

标签: java eclipse-plugin pmd

我想编写一个使用两个PMD节点的自定义AST规则。

我的自定义规则扫描源代码以查找数学运算符。

我希望我的规则可以从这些

中找到多个运算符
+,*,/, and - 

在同一个表达式中。

我尝试了一些解决方案,但它们没有用,例如:

public class OperatorPrecednece extends AbstractJavaRule {

    Public Object visit(ASTMultiplicativeExpression node, Object data) {


        Object tvisi(ASTAdditiveExpression node2, Object data2){
        addViolation(data2, node2);


        }

        return super.visit(node, data);

    }
}

怎么做?

2 个答案:

答案 0 :(得分:1)

我选择了XPath而不是Java。将此规则放入pmd规则集配置xml:

<rule name="MultipleOperatorsInExpression" language="java" message="More than one different operator used in expression" class="net.sourceforge.pmd.lang.rule.XPathRule">
  <properties>
    <property name="xpath">
      <value>
        <![CDATA[
//Expression[.//AdditiveExpression and .//MultiplicativeExpression]
        ]]>
      </value>
    </property>
  </properties>
</rule>

但它还不是一个完整的解决方案......我正在研究一个可能的pmd错误:看起来1+2-3+4这样的表达式会改为一个AdditiveExpression:+节点3个不同节点及其各自的运算符,因此检测仅使用+和 - 或仅*和/的表达式将不会被检测到。但它会检测混合加法和乘法运算符的表达式。

如果我弄明白,我会更新答案,但我希望这条规则有用。

答案 1 :(得分:1)

我正在添加另一个答案,以说明如何使用Java界面进行类似的操作。这是未经测试的代码,但这是一般的想法:

public class OperatorPrecednece extends AbstractJavaRule {

    private boolean additiveExpression = false;
    private boolean multiplicativeExpression = false;

    public Object visit(ASTMultiplicativeExpression node, Object data) {
        multiplicativeExpression = true;
        if (additiveExpression) {
            addViolation(data, node);
        }
        Object superVisit = super.visit(node, data);
        multiplicativeExpression = false;
        return superVisit;
    }

    public Object visit(ASTAdditiveExpression node, Object data) {
        additiveExpression = true;
        if (multiplicativeExpression) {
            addViolation(data, node);
        }
        Object superVisit = super.visit(node, data);
        additiveExpression = false;
        return superVisit;
    }

}

因此,访问者模式遍历AST,当它达到ASTMultiplicativeExpression时,它设置multiplicativeExpression标志,然后继续遍历。如果在遍历内部达到ASTAdditiveExpression,则将设置标志,并添加违规。当您从该遍历返回到ASTMultiplicativeExpression时,标志将被取消设置。 ASTAdditiveExpression和additiveExpression标志相同。