帮助。我想牺牲声誉以获得正确答案。
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'不起作用。如何定义?
答案 0 :(得分:0)
我们走了,昨晚我做了一些研究来帮助你。
createRuleViolation()
在AbstractRuleViolationFactory
中定义为抽象,并在特定于语言的工厂子类中实现(例如:JavaRuleViolationFactory
),而不是在规则类层次结构中直接可用。
而是使用addViolationWithMessage()
通过AbstractRule
继承的AbstractJavaRule
方法。此方法最终在运行时在适当的工厂上调用create方法。
我使用最新的PMD版本5.0.3尝试了您的代码,除了createRuleViolation()
方法的问题之外,还需要进行更多调整才能使其正常工作。主要是从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网站上的文档,或者如果您在谷歌周围有可用的负载。
希望这有用。