Merge branch 'pr-1116'

This commit is contained in:
Andreas Dangel
2018-05-18 21:10:30 +02:00
2 changed files with 2 additions and 49 deletions

View File

@ -250,55 +250,7 @@ Note that access modifiers are held as attributes, so, for example,
finds all private fields. You can see the code that determines all the attributes [here](pmd-core/xref/net/sourceforge/pmd/lang/ast/xpath/AttributeAxisIterator.html)
Thanks to Miguel Griffa for writing a longer [XPath tutorial](xpathruletutorial.html).
## I want to implement a rule that analyze more than the class!
An obvious limitation of the previous mechanism is the “class-centric” focus of the rule. How can you implement a rule that checks stuff across the all source code? Lets take a dummy example. Lets say you want to implement a rule that count how many Expression Node you have in your source code (told you, it was a dummy example :) ).
You realize quite simply. You just have to add static field to the RulesContext, as an attribute, and uses Rule.start() and Rule.end() hook to initialized and finalize your rules implementation:
```java
package net.sourceforge.pmd.rules;
import java.util.concurrent.atomic.AtomicLong;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
public class CountRule extends AbstractJavaRule {
private static final String COUNT = "count";
@Override
public void start(RuleContext ctx) {
ctx.setAttribute(COUNT, new AtomicLong());
super.start(ctx);
}
@Override
public Object visit(ASTExpression node, Object data) {
// How many Expression nodes are there in all files parsed! I must know!
RuleContext ctx = (RuleContext)data;
AtomicLong total = (AtomicLong)ctx.getAttribute(COUNT);
total.incrementAndGet();
return super.visit(node, data);
}
@Override
public void end(RuleContext ctx) {
AtomicLong total = (AtomicLong)ctx.getAttribute(COUNT);
addViolation(ctx, null, new Object[] { total });
ctx.removeAttribute(COUNT);
super.end(ctx);
}
}
```
As you can see in this example, the method start will be call the first time the rule is going to be used, so you can initialize properly your rule here. Once the rule will have finished to parses the source code, the method end() will be invoke you can assert there if, or not, your rule has been violated.
>Note that the example logs a violation **without** a proper classname. This is not really a good idea. Indeed, a lot of aggregating tools that PMD (Such as [XRadar](http://xradar.sourceforge.net), or [Sonar](http://www.sonarsource.com/)) probably uses this kind of meta data on their aggregation processes. So, when implements such a rule, always try to find a way to add classname to the violation report.
More information about writing XPath rules is [available here](pmd_userdocs_extending_writing_xpath_rules.html).
## I need some kind of Type Resolution for my rule!

View File

@ -37,6 +37,7 @@ This is a bug fixing release.
* [#1098](https://github.com/pmd/pmd/pull/1098): \[java] Simplify LongInstantiation, IntegerInstantiation, ByteInstantiation, and ShortInstantiation using type resolution
* doc
* [#999](https://github.com/pmd/pmd/issues/999): \[doc] Add a header before the XPath expression in rules
* [#1082](https://github.com/pmd/pmd/issues/1082): \[doc] Multifile analysis doc is invalid
* vf-security
* [#1100](https://github.com/pmd/pmd/issues/1100): \[vf] URLENCODE is ignored as valid escape method