救命。 我想牺牲一个合适的回答声誉..
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”不起作用。 如何界定呢?
在这里,我们走了,我做了一些调查,昨晚来帮助你。 createRuleViolation()
中定义AbstractRuleViolationFactory
为抽象和特定的语言工厂子类实现(如: JavaRuleViolationFactory
),在规则类层次结构不能直接使用。
代替使用addViolationWithMessage()
是从继承的方法AbstractRule
经由AbstractJavaRule
。 这种方法最终调用在运行时相应的工厂创建方法。
我试着用最新的PMD版本5.0.3你的代码,需要比与问题的其他几个调整createRuleViolation()
方法得到它的工作。 主要从MethodDeclaration节点到节点的参数浏览,有可能是虽然更好的办法,但现在的工作。 我已经修改基础上,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网站上的文档或有可用的负载,如果你谷歌左右。
希望这是有帮助的。