0

帮助。我想为了正确的答案而牺牲声誉..

public class ParameterNameConvention extends AbstractJavaRule {

private final static String PATTERN = "[p][a-zA-Z]+";

    public Object visit(ASTMethodDeclaration node, Object data) {
        RuleContext result = (RuleContext) data;
        String rulePattern = (!getStringProperty("rulePattern")
                .equalsIgnoreCase("")) ? getStringProperty("rulePattern")
                : PATTERN;
        if (node.containsChildOfType(ASTFormalParameter.class)) {
            Iterator iterator = node.findChildrenOfType(
                    ASTFormalParameter.class).iterator();
            while (iterator.hasNext()) {
                ASTFormalParameter element = (ASTFormalParameter) iterator
                        .next();
                Iterator decIdIterator = element.findChildrenOfType(
                        ASTVariableDeclaratorId.class).iterator();
                while (decIdIterator.hasNext()) {
                    ASTVariableDeclaratorId decElement = (ASTVariableDeclaratorId) decIdIterator
                            .next();
                    if (!decElement.getImage().matches(rulePattern)) {

                        result.getReport()
                                .addRuleViolation(
                                        createRuleViolation(
                                                this,
                                                node.getBeginLine(),
                                                "Parameter '"
                                                        + decElement.getImage()
                                                        + "' should match regular expression pattern '"
                                                        + rulePattern + "'",
                                                result));
                    }
                }
            }
        }
        return result;
    }
}

但是,“creatRuleViolation”不起作用。如何定义它?

4

1 回答 1

0

来吧,我昨晚做了一些研究来帮助你。 createRuleViolation()被定义AbstractRuleViolationFactory为抽象并在语言特定的工厂子类(例如:)中实现,JavaRuleViolationFactory在规则类层次结构中不直接可用。

而是使用从viaaddViolationWithMessage()继承的方法。此方法最终在运行时调用适当工厂的 create 方法。AbstractRuleAbstractJavaRule

createRuleViolation()我用最新的 PMD 版本 5.0.3 尝试了你的代码,除了让它工作的方法问题之外,还需要做一些调整。主要是从 MethodDeclaration 节点导航到 Parameter 节点,虽然可能有更好的方法,但它现在可以工作。我已经根据 AST(抽象源代码树)修改了代码。

package madhav.pmd.rule;

import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;

public class ParameterNameConvention extends AbstractJavaRule
{
    private final static String PATTERN = "[p][a-zA-Z]+";

    @Override
    public Object visit(final ASTMethodDeclaration node, final Object pData)
    {
        final RuleContext result = (RuleContext) pData;
        // TODO : get property
        final String rulePattern = PATTERN;
        final ASTMethodDeclarator methodDecNode = node.getFirstChildOfType(ASTMethodDeclarator.class);
        final ASTFormalParameters paramsNode = methodDecNode.getFirstChildOfType(ASTFormalParameters.class);
        if (paramsNode.getParameterCount() > 0)
        {
            for (final ASTFormalParameter element : paramsNode.findChildrenOfType(ASTFormalParameter.class))
            {
                for (final ASTVariableDeclaratorId decElement : element.findChildrenOfType(ASTVariableDeclaratorId.class))
                {
                    if (!decElement.getImage().matches(rulePattern))
                    {
                        addViolationWithMessage(result, node,
                                "Parameter '"
                                        + decElement.getImage()
                                        + "' should match regular expression pattern '"
                                        + rulePattern + "'",
                                node.getBeginLine(),
                                node.getEndLine());
                    }
                }
            }
        }
        return result;
    }
}

为了在同一个类上测试规则,我指定了一个参数满足规则和一个不满足(final ASTMethodDeclaration node, final Object pData)。

规则集 xml 是

<?xml version="1.0"?>
<ruleset name="My rules">
  <description>My test rules</description>
  <rule name="ParameterNameConvention"
        message="Parameter must start with p"
        class="madhav.pmd.rule.ParameterNameConvention">
    <description>Don't use non-complaint parameters </description>

    <example>
        <![CDATA[
         void methodX(int value)
        ]]>
    </example>
  </rule>
</ruleset>

生成的结果 xml PMD 是:

<?xml version="1.0" encoding="UTF-8"?>
<pmd version="5.0.3" timestamp="2013-06-13T16:03:52.404">
    <file name="D:\Projects\ZRules\src\madhav\pmd\rule\ParameterNameConvention.java">
        <violation beginline="16" endline="43" begincolumn="16" endcolumn="9" 
            rule="ParameterNameConvention" ruleset="My rules" package="madhav.pmd.rule" 
            class="ParameterNameConvention" priority="5">
                Parameter node should match regular expression pattern [p][a-zA-Z]+
        </violation>
    </file>
</pmd>

有关从命令行独立运行 PMD 的更多详细信息,请参阅 PMD 网站上的文档,或者如果您四处搜索,则有可用的负载。

希望这会有所帮助。

于 2013-06-13T15:33:03.133 回答