Merge branch '7.0.x' into java-grammar

This commit is contained in:
Clément Fournier
2019-12-11 20:22:55 +01:00
73 changed files with 720 additions and 955 deletions

View File

@ -31,7 +31,12 @@ This is a {{ site.pmd.release_type }} release.
* {% jdoc java::lang.java.JavaLanguageHandler %}
* {% jdoc java::lang.java.JavaLanguageParser %}
* {% jdoc java::lang.java.JavaDataFlowHandler %}
* Implementations of {% jdoc core::lang.rule.RuleViolationFactory %} in each
language module, eg {% jdoc java::lang.java.rule.JavaRuleViolationFactory %}.
See javadoc of {% jdoc core::lang.rule.RuleViolationFactory %}.
* Implementations of {% jdoc core::RuleViolation %} in each language module,
eg {% jdoc java::lang.java.rule.JavaRuleViolation %}. See javadoc of
{% jdoc core::RuleViolation %}.
##### For removal

View File

@ -11,7 +11,6 @@ import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.VisitorStarter;
import net.sourceforge.pmd.lang.XPathHandler;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
@ -19,8 +18,7 @@ import net.sourceforge.pmd.lang.apex.metrics.ApexMetricsComputer;
import net.sourceforge.pmd.lang.apex.metrics.api.ApexClassMetricKey;
import net.sourceforge.pmd.lang.apex.metrics.api.ApexOperationMetricKey;
import net.sourceforge.pmd.lang.apex.multifile.ApexMultifileVisitorFacade;
import net.sourceforge.pmd.lang.apex.rule.ApexRuleViolationFactory;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.apex.rule.internal.ApexRuleViolationFactory;
import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider;
import net.sourceforge.pmd.lang.metrics.internal.AbstractLanguageMetricsProvider;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
@ -35,12 +33,6 @@ public class ApexHandler extends AbstractPmdLanguageVersionHandler {
return rootNode -> new ApexMultifileVisitorFacade().initializeWith((ApexNode<?>) rootNode);
}
@Override
public XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
@Override
public RuleViolationFactory getRuleViolationFactory() {
return ApexRuleViolationFactory.INSTANCE;

View File

@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.apex;
import java.io.Reader;
import java.util.Map;
import net.sourceforge.pmd.lang.AbstractParser;
import net.sourceforge.pmd.lang.ParserOptions;
@ -34,8 +33,4 @@ public class ApexParser extends AbstractParser {
return apexParser.parse(source);
}
@Override
public Map<Integer, String> getSuppressMap() {
return apexParser.getSuppressMap();
}
}

View File

@ -4,6 +4,9 @@
package net.sourceforge.pmd.lang.apex.ast;
import java.util.Collections;
import java.util.Map;
import net.sourceforge.pmd.lang.ast.RootNode;
import net.sourceforge.pmd.lang.ast.SourceCodePositioner;
@ -11,6 +14,9 @@ import apex.jorje.semantic.ast.AstNode;
import apex.jorje.services.Version;
public abstract class ApexRootNode<T extends AstNode> extends AbstractApexNode<T> implements RootNode {
private Map<Integer, String> noPmdComments = Collections.emptyMap();
public ApexRootNode(T node) {
super(node);
}
@ -32,4 +38,14 @@ public abstract class ApexRootNode<T extends AstNode> extends AbstractApexNode<T
public double getApexVersion() {
return getNode().getDefiningType().getCodeUnitDetails().getVersion().getExternal();
}
@Override
public Map<Integer, String> getNoPmdComments() {
return noPmdComments;
}
void setNoPmdComments(Map<Integer, String> noPmdComments) {
this.noPmdComments = noPmdComments;
}
}

View File

@ -1,69 +0,0 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.apex.ast.CanSuppressWarnings;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.ParametricRuleViolation;
/**
* This is an Apex RuleViolation. It knows how to try to extract the following
* extra information from the violation node:
* <ul>
* <li>Package name</li>
* <li>Class name</li>
* <li>Method name</li>
* <li>Variable name</li>
* <li>Suppression indicator</li>
* </ul>
* @param <T>
*/
@SuppressWarnings("PMD.UseUtilityClass") // we inherit non-static methods...
public class ApexRuleViolation<T> extends ParametricRuleViolation<Node> {
public ApexRuleViolation(Rule rule, RuleContext ctx, Node node, String message, int beginLine, int endLine) {
this(rule, ctx, node, message);
setLines(beginLine, endLine);
}
public ApexRuleViolation(Rule rule, RuleContext ctx, Node node, String message) {
super(rule, ctx, node, message);
if (node != null) {
if (!suppressed) {
suppressed = isSupressed(node, getRule());
}
}
}
/**
* Check for suppression on this node, on parents, and on contained types
* for ASTCompilationUnit
*
* @deprecated Is internal API, not useful, there's a typo. See <a href="https://github.com/pmd/pmd/pull/1927">#1927</a>
*/
@Deprecated
public static boolean isSupressed(Node node, Rule rule) {
boolean result = suppresses(node, rule);
if (!result) {
Node parent = node.jjtGetParent();
while (!result && parent != null) {
result = suppresses(parent, rule);
parent = parent.jjtGetParent();
}
}
return result;
}
private static boolean suppresses(final Node node, Rule rule) {
return node instanceof CanSuppressWarnings
&& ((CanSuppressWarnings) node).hasSuppressWarningsAnnotationFor(rule);
}
}

View File

@ -1,32 +0,0 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.AbstractRuleViolationFactory;
public final class ApexRuleViolationFactory extends AbstractRuleViolationFactory {
public static final ApexRuleViolationFactory INSTANCE = new ApexRuleViolationFactory();
private ApexRuleViolationFactory() {
}
@SuppressWarnings("rawtypes")
@Override
protected RuleViolation createRuleViolation(Rule rule, RuleContext ruleContext, Node node, String message) {
return new ApexRuleViolation<>(rule, ruleContext, node, message);
}
@Override
@SuppressWarnings("rawtypes")
protected RuleViolation createRuleViolation(Rule rule, RuleContext ruleContext, Node node, String message,
int beginLine, int endLine) {
return new ApexRuleViolation(rule, ruleContext, node, message, beginLine, endLine);
}
}

View File

@ -0,0 +1,71 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.internal;
import java.util.Collections;
import java.util.List;
import org.checkerframework.checker.nullness.qual.NonNull;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.Report.SuppressedViolation;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.ViolationSuppressor;
import net.sourceforge.pmd.lang.apex.ast.CanSuppressWarnings;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.impl.DefaultRuleViolationFactory;
public final class ApexRuleViolationFactory extends DefaultRuleViolationFactory {
public static final ApexRuleViolationFactory INSTANCE = new ApexRuleViolationFactory();
private static final ViolationSuppressor APEX_ANNOT_SUPPRESSOR = new ViolationSuppressor() {
@Override
public String getId() {
return "@SuppressWarnings";
}
@Override
public Report.SuppressedViolation suppressOrNull(RuleViolation rv, @NonNull Node node) {
if (isSuppressed(node, rv.getRule())) {
return new SuppressedViolation(rv, this, null);
}
return null;
}
};
private ApexRuleViolationFactory() {
}
@Override
protected List<ViolationSuppressor> getSuppressors() {
return Collections.singletonList(APEX_ANNOT_SUPPRESSOR);
}
/**
* Check for suppression on this node, on parents, and on contained types
* for ASTCompilationUnit
*
* @param node
*/
private static boolean isSuppressed(Node node, Rule rule) {
boolean result = suppresses(node, rule);
if (!result) {
Node parent = node.jjtGetParent();
while (!result && parent != null) {
result = suppresses(parent, rule);
parent = parent.jjtGetParent();
}
}
return result;
}
private static boolean suppresses(final Node node, Rule rule) {
return node instanceof CanSuppressWarnings
&& ((CanSuppressWarnings) node).hasSuppressWarningsAnnotationFor(rule);
}
}

View File

@ -42,7 +42,6 @@ public class Report implements Iterable<RuleViolation> {
private final List<ThreadSafeReportListener> listeners = new ArrayList<>();
private List<ProcessingError> errors;
private List<ConfigurationError> configErrors;
private Map<Integer, String> linesToSuppress = new HashMap<>();
private long start;
private long end;
private List<SuppressedViolation> suppressedRuleViolations = new ArrayList<>();
@ -177,72 +176,6 @@ public class Report implements Iterable<RuleViolation> {
}
}
/**
* Represents a violation, that has been suppressed.
*/
public static class SuppressedViolation {
private final RuleViolation rv;
private final boolean isNOPMD;
private final String userMessage;
/**
* Creates a suppressed violation.
*
* @param rv
* the actual violation, that has been suppressed
* @param isNOPMD
* the suppression mode: <code>true</code> if it is
* suppressed via a NOPMD comment, <code>false</code> if
* suppressed via annotations.
* @param userMessage
* contains the suppressed code line or <code>null</code>
*/
public SuppressedViolation(RuleViolation rv, boolean isNOPMD, String userMessage) {
this.isNOPMD = isNOPMD;
this.rv = rv;
this.userMessage = userMessage;
}
/**
* Returns <code>true</code> if the violation has been suppressed via a
* NOPMD comment.
*
* @return <code>true</code> if the violation has been suppressed via a
* NOPMD comment.
*/
public boolean suppressedByNOPMD() {
return this.isNOPMD;
}
/**
* Returns <code>true</code> if the violation has been suppressed via a
* annotation.
*
* @return <code>true</code> if the violation has been suppressed via a
* annotation.
*/
public boolean suppressedByAnnotation() {
return !this.isNOPMD;
}
public RuleViolation getRuleViolation() {
return this.rv;
}
public String getUserMessage() {
return userMessage;
}
}
/**
* Configure the lines, that are suppressed via a NOPMD comment.
*
* @param lines
* the suppressed lines
*/
public void suppress(Map<Integer, String> lines) {
linesToSuppress = lines;
}
private static String keyFor(RuleViolation rv) {
@ -301,6 +234,46 @@ public class Report implements Iterable<RuleViolation> {
return suppressedRuleViolations;
}
/**
* Represents a violation, that has been suppressed.
* TODO this should implement RuleViolation
*/
public static class SuppressedViolation {
private final RuleViolation rv;
private final String userMessage;
private final ViolationSuppressor suppressor;
/**
* Creates a suppressed violation.
*
* @param rv The violation, that has been suppressed
* @param suppressor The suppressor which suppressed the violation
* @param userMessage Any relevant info given by the suppressor
*/
public SuppressedViolation(RuleViolation rv, ViolationSuppressor suppressor, String userMessage) {
this.suppressor = suppressor;
this.rv = rv;
this.userMessage = userMessage;
}
public ViolationSuppressor getSuppressor() {
return suppressor;
}
public RuleViolation getRuleViolation() {
return this.rv;
}
public String getUserMessage() {
return userMessage;
}
}
public void addSuppressedViolation(SuppressedViolation sv) {
suppressedRuleViolations.add(sv);
}
/**
* Adds a new rule violation to the report and notify the listeners.
*
@ -308,19 +281,6 @@ public class Report implements Iterable<RuleViolation> {
* the violation to add
*/
public void addRuleViolation(RuleViolation violation) {
// NOPMD suppress
int line = violation.getBeginLine();
if (linesToSuppress.containsKey(line)) {
suppressedRuleViolations.add(new SuppressedViolation(violation, true, linesToSuppress.get(line)));
return;
}
if (violation.isSuppressed()) {
suppressedRuleViolations.add(new SuppressedViolation(violation, false, null));
return;
}
int index = Collections.binarySearch(violations, violation, RuleViolationComparator.INSTANCE);
violations.add(index < 0 ? -index - 1 : index, violation);
violationTree.addRuleViolation(violation);

View File

@ -6,7 +6,11 @@ package net.sourceforge.pmd;
/**
* A RuleViolation is created by a Rule when it identifies a violation of the
* Rule constraints.
* Rule constraints. RuleViolations are simple data holders that are collected
* into a {@link Report}.
*
* <p>Since PMD 6.21.0, implementations of this interface are considered internal
* API and hence deprecated. Clients should exclusively use this interface.
*
* @see Rule
*/
@ -26,13 +30,6 @@ public interface RuleViolation {
*/
String getDescription();
/**
* Indicates whether this violation has been suppressed.
*
* @return <code>true</code> if this violation is suppressed,
* <code>false</code> otherwise.
*/
boolean isSuppressed();
/**
* Get the source file name in which this violation was identified.

View File

@ -120,9 +120,7 @@ public class SourceCodeProcessor {
private Node parse(RuleContext ctx, Reader sourceCode, Parser parser) {
try (TimedOperation to = TimeTracker.startOperation(TimedOperationCategory.PARSER)) {
Node rootNode = parser.parse(String.valueOf(ctx.getSourceCodeFile()), sourceCode);
ctx.getReport().suppress(parser.getSuppressMap());
return rootNode;
return parser.parse(String.valueOf(ctx.getSourceCodeFile()), sourceCode);
}
}

View File

@ -0,0 +1,104 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd;
import java.util.Map;
import java.util.regex.Pattern;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import net.sourceforge.pmd.Report.SuppressedViolation;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.RootNode;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
/**
* An object that suppresses rule violations. Suppressors are used by
* {@link RuleViolationFactory} to filter out violations. In PMD 6.0.x,
* the {@link Report} object filtered violations itself - but it has
* no knowledge of language-specific suppressors.
*/
public interface ViolationSuppressor {
/**
* Suppressor for the violationSuppressRegex property.
*/
ViolationSuppressor REGEX_SUPPRESSOR = new ViolationSuppressor() {
@Override
public String getId() {
return "Regex";
}
@Override
public @Nullable SuppressedViolation suppressOrNull(RuleViolation rv, @NonNull Node node) {
String regex = rv.getRule().getProperty(Rule.VIOLATION_SUPPRESS_REGEX_DESCRIPTOR); // Regex
if (regex != null && rv.getDescription() != null) {
if (Pattern.matches(regex, rv.getDescription())) {
return new SuppressedViolation(rv, this, regex);
}
}
return null;
}
};
/**
* Suppressor for the violationSuppressXPath property.
*/
ViolationSuppressor XPATH_SUPPRESSOR = new ViolationSuppressor() {
@Override
public String getId() {
return "XPath";
}
@Override
public @Nullable SuppressedViolation suppressOrNull(RuleViolation rv, @NonNull Node node) {
String xpath = rv.getRule().getProperty(Rule.VIOLATION_SUPPRESS_XPATH_DESCRIPTOR);
if (xpath != null && node.hasDescendantMatchingXPath(xpath)) {
return new SuppressedViolation(rv, this, xpath);
}
return null;
}
};
/**
* Suppressor for regular NOPMD comments.
*
* @implNote This requires special support from the language, namely
* an implementation of {@link RootNode#getNoPmdComments()}.
*/
ViolationSuppressor NOPMD_COMMENT_SUPPRESSOR = new ViolationSuppressor() {
@Override
public String getId() {
return "//NOPMD";
}
@Override
public @Nullable SuppressedViolation suppressOrNull(RuleViolation rv, @NonNull Node node) {
Map<Integer, String> noPmd = node.getRoot().getNoPmdComments();
if (noPmd.containsKey(rv.getBeginLine())) {
return new SuppressedViolation(rv, this, noPmd.get(rv.getBeginLine()));
}
return null;
}
};
/**
* A name, for reporting and documentation purposes.
*/
String getId();
/**
* Returns a {@link SuppressedViolation} if the given violation is
* suppressed by this object. The node and the rule are provided
* for context. Returns null if the violation is not suppressed.
*/
@Nullable
SuppressedViolation suppressOrNull(RuleViolation rv, @NonNull Node node);
}

View File

@ -69,11 +69,6 @@ public final class CachedRuleViolation implements RuleViolation {
return description;
}
@Override
public boolean isSuppressed() {
return false; // By definition, if cached, it was not suppressed
}
@Override
public String getFilename() {
return fileName;

View File

@ -4,7 +4,6 @@
package net.sourceforge.pmd.lang;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.dfa.DFAGraphRule;
import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider;
import net.sourceforge.pmd.util.designerbindings.DesignerBindings;
@ -22,11 +21,6 @@ public abstract class AbstractLanguageVersionHandler implements LanguageVersionH
return DataFlowHandler.DUMMY;
}
@Override
public XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
@Override
public ParserOptions getDefaultParserOptions() {
return new ParserOptions();

View File

@ -12,6 +12,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.TreeSet;
@ -34,12 +35,17 @@ public final class LanguageRegistry {
// Use current class' classloader instead of the threads context classloader, see https://github.com/pmd/pmd/issues/1377
ServiceLoader<Language> languageLoader = ServiceLoader.load(Language.class, getClass().getClassLoader());
Iterator<Language> iterator = languageLoader.iterator();
//noinspection WhileLoopReplaceableByForEach -- https://youtrack.jetbrains.com/issue/IDEA-223743
while (iterator.hasNext()) {
while (true) {
// this loop is weird, but both hasNext and next may throw ServiceConfigurationError,
// it's more robust that way
try {
Language language = iterator.next();
sortedLangs.add(language);
} catch (UnsupportedClassVersionError e) {
if (iterator.hasNext()) {
Language language = iterator.next();
sortedLangs.add(language);
} else {
break;
}
} catch (UnsupportedClassVersionError | ServiceConfigurationError e) {
// Some languages require java8 and are therefore only available
// if java8 or later is used as runtime.
System.err.println("Ignoring language for PMD: " + e.toString());

View File

@ -9,9 +9,11 @@ import java.util.List;
import net.sourceforge.pmd.annotation.Experimental;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.AstProcessingStage;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.dfa.DFAGraphRule;
import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
import net.sourceforge.pmd.lang.rule.impl.DefaultRuleViolationFactory;
import net.sourceforge.pmd.util.designerbindings.DesignerBindings;
import net.sourceforge.pmd.util.designerbindings.DesignerBindings.DefaultDesignerBindings;
@ -32,7 +34,9 @@ public interface LanguageVersionHandler {
/**
* Get the XPathHandler.
*/
XPathHandler getXPathHandler();
default XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
/**
@ -63,7 +67,9 @@ public interface LanguageVersionHandler {
/**
* Get the RuleViolationFactory.
*/
RuleViolationFactory getRuleViolationFactory();
default RuleViolationFactory getRuleViolationFactory() {
return DefaultRuleViolationFactory.defaultInstance();
}
/**

View File

@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang;
import java.io.Reader;
import java.util.Map;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.ParseException;
@ -47,21 +46,5 @@ public interface Parser {
*/
Node parse(String fileName, Reader source) throws ParseException;
/**
* Returns the map of line numbers to suppression / review comments.
* Only single line comments are considered, that start with the configured
* "suppressMarker", which by default is "PMD". The text after the
* suppressMarker is used as a "review comment" and included in this map.
*
* <p>
* This map is later used to determine, if a violation is being suppressed.
* It is suppressed, if the line of the violation is contained in this suppress map.
*
* @return map of the suppress lines with the corresponding review comments.
*
* @deprecated With 7.0.0, this method will be removed. To support
* suppressing with suppress markers, this method is still needed in PMD 6.
*/
@Deprecated
Map<Integer, String> getSuppressMap();
}

View File

@ -12,6 +12,7 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.jaxen.BaseXPath;
import org.jaxen.JaxenException;
import org.w3c.dom.Document;
@ -397,4 +398,17 @@ public interface Node {
default Iterator<Attribute> getXPathAttributesIterator() {
return new AttributeAxisIterator(this);
}
@NonNull
default RootNode getRoot() {
Node r = this;
while (r != null && !(r instanceof RootNode)) {
r = r.jjtGetParent();
}
if (r == null) {
throw new IllegalStateException("No root node in tree ?");
}
return (RootNode) r;
}
}

View File

@ -4,13 +4,35 @@
package net.sourceforge.pmd.lang.ast;
import java.util.Collections;
import java.util.Map;
import net.sourceforge.pmd.annotation.Experimental;
import net.sourceforge.pmd.annotation.InternalApi;
/**
* This interface can be used to tag the root node of various ASTs.
*/
public interface RootNode extends Node {
// that's only a marker interface.
// TODO we could add some utilities here eg to get the file name,
// the language of the node,
// the source code of the file (as recently done in PLSQL - #1728),
// the whole token chain, etc
/**
* Returns the map of line numbers to suppression / review comments.
* Only single line comments are considered, that start with the configured
* "suppressMarker", which by default is "PMD". The text after the
* suppressMarker is used as a "review comment" and included in this map.
*
* <p>
* This map is later used to determine, if a violation is being suppressed.
* It is suppressed, if the line of the violation is contained in this suppress map.
*
* @return map of the suppress lines with the corresponding review comments.
*/
@InternalApi
@Experimental
default Map<Integer, String> getNoPmdComments() {
return Collections.emptyMap();
}
}

View File

@ -6,8 +6,6 @@ package net.sourceforge.pmd.lang.ast.impl.antlr4;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import org.antlr.v4.runtime.Lexer;
@ -51,11 +49,6 @@ public abstract class AntlrBaseParser<T extends org.antlr.v4.runtime.Parser> imp
}
}
@Override
public Map<Integer, String> getSuppressMap() {
return new HashMap<>();
}
protected abstract AntlrBaseNode getRootNode(T parser);
protected abstract Lexer getLexer(Reader source) throws IOException;

View File

@ -1,35 +0,0 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.ast.impl.antlr4;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.AbstractRuleViolationFactory;
import net.sourceforge.pmd.lang.rule.ParametricRuleViolation;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
public final class AntlrRuleViolationFactory extends AbstractRuleViolationFactory {
public static final RuleViolationFactory INSTANCE = new AntlrRuleViolationFactory();
private AntlrRuleViolationFactory() {
}
@Override
protected RuleViolation createRuleViolation(final Rule rule, final RuleContext ruleContext, final Node node,
final String message) {
return new ParametricRuleViolation<>(rule, ruleContext, (AntlrBaseNode) node, message);
}
@Override
protected RuleViolation createRuleViolation(final Rule rule, final RuleContext ruleContext, final Node node,
final String message, final int beginLine, final int endLine) {
final ParametricRuleViolation<AntlrBaseNode> violation = new ParametricRuleViolation<>(rule, ruleContext,
(AntlrBaseNode) node, message);
violation.setLines(beginLine, endLine);
return violation;
}
}

View File

@ -1,54 +1,15 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.rule;
import java.text.MessageFormat;
import net.sourceforge.pmd.lang.rule.impl.DefaultRuleViolationFactory;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.ast.Node;
public abstract class AbstractRuleViolationFactory implements RuleViolationFactory {
private static final Object[] NO_ARGS = new Object[0];
private String cleanup(String message, Object[] args) {
if (message != null) {
// Escape PMD specific variable message format, specifically the {
// in the ${, so MessageFormat doesn't bitch.
final String escapedMessage = StringUtils.replace(message, "${", "$'{'");
return MessageFormat.format(escapedMessage, args != null ? args : NO_ARGS);
} else {
return message;
}
}
@Override
public void addViolation(RuleContext ruleContext, Rule rule, Node node, String message, Object[] args) {
String formattedMessage = cleanup(message, args);
ruleContext.getReport().addRuleViolation(createRuleViolation(rule, ruleContext, node, formattedMessage));
}
@Override
public void addViolation(RuleContext ruleContext, Rule rule, Node node, String message, int beginLine, int endLine,
Object[] args) {
String formattedMessage = cleanup(message, args);
ruleContext.getReport()
.addRuleViolation(createRuleViolation(rule, ruleContext, node, formattedMessage, beginLine, endLine));
}
protected abstract RuleViolation createRuleViolation(Rule rule, RuleContext ruleContext, Node node, String message);
protected abstract RuleViolation createRuleViolation(Rule rule, RuleContext ruleContext, Node node, String message,
int beginLine, int endLine);
/**
* @deprecated This is kept for binary compatibility with the 6.x designer, yet will
* go away in 7.0. Use {@link DefaultRuleViolationFactory}
*/
@Deprecated
public class AbstractRuleViolationFactory extends DefaultRuleViolationFactory {
}

View File

@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.rule;
import java.io.File;
import java.util.regex.Pattern;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
@ -18,7 +17,6 @@ public class ParametricRuleViolation<T extends Node> implements RuleViolation {
protected final Rule rule;
protected final String description;
protected boolean suppressed;
protected String filename;
protected int beginLine;
@ -36,6 +34,7 @@ public class ParametricRuleViolation<T extends Node> implements RuleViolation {
// must not (to prevent erroneous Rules silently logging w/o a Node). Modify
// RuleViolationFactory to support identifying without a Node, and update
// Rule base classes too.
// TODO we never need a node. We just have to have a "position", ie line/column, or offset, + file, whatever
public ParametricRuleViolation(Rule theRule, RuleContext ctx, T node, String message) {
rule = theRule;
description = message;
@ -53,28 +52,6 @@ public class ParametricRuleViolation<T extends Node> implements RuleViolation {
endColumn = node.getEndColumn();
}
// Apply Rule specific suppressions
if (node != null && rule != null) {
setSuppression(rule, node);
}
}
private void setSuppression(Rule rule, T node) {
String regex = rule.getProperty(Rule.VIOLATION_SUPPRESS_REGEX_DESCRIPTOR); // Regex
if (regex != null && description != null) {
if (Pattern.matches(regex, description)) {
suppressed = true;
}
}
if (!suppressed) { // XPath
String xpath = rule.getProperty(Rule.VIOLATION_SUPPRESS_XPATH_DESCRIPTOR);
if (xpath != null) {
suppressed = node.hasDescendantMatchingXPath(xpath);
}
}
}
protected String expandVariables(String message) {
@ -127,11 +104,6 @@ public class ParametricRuleViolation<T extends Node> implements RuleViolation {
return expandVariables(description);
}
@Override
public boolean isSuppressed() {
return suppressed;
}
@Override
public String getFilename() {
return filename;

View File

@ -4,13 +4,20 @@
package net.sourceforge.pmd.lang.rule;
import org.checkerframework.checker.nullness.qual.Nullable;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.LanguageVersionHandler;
import net.sourceforge.pmd.lang.ast.Node;
/**
* This class handles of producing a Language specific RuleViolation and adding
* to a Report.
*
* <p>Since PMD 6.21.0, implementations of this interface are considered internal
* API and hence deprecated. Clients should exclusively use this interface and obtain
* instances through {@link LanguageVersionHandler#getRuleViolationFactory()}.
*/
public interface RuleViolationFactory {
/**
@ -27,8 +34,8 @@ public interface RuleViolationFactory {
* @param args
* arguments to embed in the rule violation message
*/
void addViolation(RuleContext ruleContext, Rule rule, Node node, String message, Object[] args);
void addViolation(RuleContext ruleContext, Rule rule, @Nullable Node node, String message, Object[] args);
void addViolation(RuleContext ruleContext, Rule rule, Node node, String message, int beginLine, int endLine,
Object[] args);
void addViolation(RuleContext ruleContext, Rule rule, @Nullable Node node, String message, int beginLine, int endLine, Object[] args);
}

View File

@ -0,0 +1,124 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.rule.impl;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import net.sourceforge.pmd.Report.SuppressedViolation;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.ViolationSuppressor;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.ParametricRuleViolation;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
/**
* This is a functional implementation of {@link RuleViolationFactory}.
* It uses only the standard {@link ViolationSuppressor}s (constants in the interface).
* It may be extended to add more suppression options.
*
* <p>Implementations should be internal. Only the interface should be exposed.
*/
public class DefaultRuleViolationFactory implements RuleViolationFactory {
private static final Object[] NO_ARGS = new Object[0];
private static final DefaultRuleViolationFactory DEFAULT = new DefaultRuleViolationFactory();
private Set<ViolationSuppressor> allSuppressors;
private String cleanup(String message, Object[] args) {
if (message != null) {
// Escape PMD specific variable message format, specifically the {
// in the ${, so MessageFormat doesn't bitch.
final String escapedMessage = StringUtils.replace(message, "${", "$'{'");
return MessageFormat.format(escapedMessage, args != null ? args : NO_ARGS);
} else {
return message;
}
}
@Override
public void addViolation(RuleContext ruleContext, Rule rule, Node node, String message, Object[] args) {
String formattedMessage = cleanup(message, args);
RuleViolation rv = createRuleViolation(rule, ruleContext, node, formattedMessage);
maybeSuppress(ruleContext, node, rv);
}
@Override
public void addViolation(RuleContext ruleContext, Rule rule, Node node, String message, int beginLine, int endLine, Object[] args) {
String formattedMessage = cleanup(message, args);
RuleViolation rv = createRuleViolation(rule, ruleContext, node, formattedMessage, beginLine, endLine);
maybeSuppress(ruleContext, node, rv);
}
private void maybeSuppress(RuleContext ruleContext, @Nullable Node node, RuleViolation rv) {
if (node != null) {
// note: no suppression when node is null.
// Node should in fact never be null, this is todo for later
for (ViolationSuppressor suppressor : getAllSuppressors()) {
SuppressedViolation suppressed = suppressor.suppressOrNull(rv, node);
if (suppressed != null) {
ruleContext.getReport().addSuppressedViolation(suppressed);
return;
}
}
}
ruleContext.getReport().addRuleViolation(rv);
}
/**
* Returns a list of additional suppressors for this language. These
* are added to regular //NOPMD, regex and XPath suppression.
*/
protected List<ViolationSuppressor> getSuppressors() {
return Collections.emptyList();
}
protected RuleViolation createRuleViolation(Rule rule, RuleContext ruleContext, Node node, String message) {
return new ParametricRuleViolation<>(rule, ruleContext, node, message);
}
protected RuleViolation createRuleViolation(Rule rule, RuleContext ruleContext, Node node, String message,
int beginLine, int endLine) {
ParametricRuleViolation<Node> rv = new ParametricRuleViolation<>(rule, ruleContext, node, message);
rv.setLines(beginLine, endLine);
return rv;
}
private Set<ViolationSuppressor> getAllSuppressors() {
if (allSuppressors == null) {
// lazy loaded because calling getSuppressors in constructor
// is not safe wrt initialization of static constants
// (order dependent otherwise)
this.allSuppressors = new LinkedHashSet<>(getSuppressors());
allSuppressors.add(ViolationSuppressor.NOPMD_COMMENT_SUPPRESSOR);
allSuppressors.add(ViolationSuppressor.REGEX_SUPPRESSOR);
allSuppressors.add(ViolationSuppressor.XPATH_SUPPRESSOR);
}
return allSuppressors;
}
/** Returns the default instance (no additional suppressors, creates a ParametricRuleViolation). */
public static RuleViolationFactory defaultInstance() {
return DEFAULT;
}
}

View File

@ -113,13 +113,13 @@ public class HTMLRenderer extends AbstractIncrementingRenderer {
buf.append(" bgcolor=\"lightgrey\"");
}
colorize = !colorize;
buf.append("> " + PMD.EOL);
buf.append("<td align=\"center\">" + violationCount + "</td>" + PMD.EOL);
buf.append("<td width=\"*%\">"
+ maybeWrap(StringEscapeUtils.escapeHtml4(determineFileName(rv.getFilename())),
linePrefix == null ? "" : linePrefix + Integer.toString(rv.getBeginLine()))
+ "</td>" + PMD.EOL);
buf.append("<td align=\"center\" width=\"5%\">" + Integer.toString(rv.getBeginLine()) + "</td>" + PMD.EOL);
buf.append("> ").append(PMD.EOL);
buf.append("<td align=\"center\">").append(violationCount).append("</td>").append(PMD.EOL);
buf.append("<td width=\"*%\">")
.append(maybeWrap(StringEscapeUtils.escapeHtml4(determineFileName(rv.getFilename())), linePrefix == null ? "" : linePrefix + rv.getBeginLine()))
.append("</td>")
.append(PMD.EOL);
buf.append("<td align=\"center\" width=\"5%\">").append(rv.getBeginLine()).append("</td>").append(PMD.EOL);
String d = StringEscapeUtils.escapeHtml4(rv.getDescription());
@ -127,8 +127,11 @@ public class HTMLRenderer extends AbstractIncrementingRenderer {
if (StringUtils.isNotBlank(infoUrl)) {
d = "<a href=\"" + infoUrl + "\">" + d + "</a>";
}
buf.append("<td width=\"*\">" + d + "</td>" + PMD.EOL);
buf.append("</tr>" + PMD.EOL);
buf.append("<td width=\"*\">")
.append(d)
.append("</td>")
.append(PMD.EOL)
.append("</tr>").append(PMD.EOL);
writer.write(buf.toString());
violationCount++;
}
@ -154,10 +157,10 @@ public class HTMLRenderer extends AbstractIncrementingRenderer {
buf.append(" bgcolor=\"lightgrey\"");
}
colorize = !colorize;
buf.append("> " + PMD.EOL);
buf.append("<td>" + determineFileName(pe.getFile()) + "</td>" + PMD.EOL);
buf.append("<td><pre>" + pe.getDetail() + "</pre></td>" + PMD.EOL);
buf.append("</tr>" + PMD.EOL);
buf.append("> ").append(PMD.EOL);
buf.append("<td>").append(determineFileName(pe.getFile())).append("</td>").append(PMD.EOL);
buf.append("<td><pre>").append(pe.getDetail()).append("</pre></td>").append(PMD.EOL);
buf.append("</tr>").append(PMD.EOL);
writer.write(buf.toString());
}
writer.write("</table>");
@ -182,19 +185,19 @@ public class HTMLRenderer extends AbstractIncrementingRenderer {
buf.append(" bgcolor=\"lightgrey\"");
}
colorize = !colorize;
buf.append("> " + PMD.EOL);
buf.append("<td align=\"left\">" + determineFileName(sv.getRuleViolation().getFilename()) + "</td>" + PMD.EOL);
buf.append("<td align=\"center\">" + sv.getRuleViolation().getBeginLine() + "</td>" + PMD.EOL);
buf.append("<td align=\"center\">" + sv.getRuleViolation().getRule().getName() + "</td>" + PMD.EOL);
buf.append("<td align=\"center\">" + (sv.suppressedByNOPMD() ? "NOPMD" : "Annotation") + "</td>" + PMD.EOL);
buf.append("<td align=\"center\">" + (sv.getUserMessage() == null ? "" : sv.getUserMessage()) + "</td>"
+ PMD.EOL);
buf.append("</tr>" + PMD.EOL);
buf.append("> ").append(PMD.EOL);
buf.append("<td align=\"left\">").append(determineFileName(sv.getRuleViolation().getFilename())).append("</td>").append(PMD.EOL);
buf.append("<td align=\"center\">").append(sv.getRuleViolation().getBeginLine()).append("</td>").append(PMD.EOL);
buf.append("<td align=\"center\">").append(sv.getRuleViolation().getRule().getName()).append("</td>").append(PMD.EOL);
buf.append("<td align=\"center\">").append(sv.getSuppressor().getId()).append("</td>").append(PMD.EOL);
buf.append("<td align=\"center\">").append(
sv.getUserMessage() == null ? "" : sv.getUserMessage()).append("</td>").append(PMD.EOL);
buf.append("</tr>").append(PMD.EOL);
writer.write(buf.toString());
}
writer.write("</table>");
}
private void glomConfigurationErrors(final Writer writer, final List<ConfigurationError> configErrors) throws IOException {
if (configErrors.isEmpty()) {
return;
@ -214,10 +217,10 @@ public class HTMLRenderer extends AbstractIncrementingRenderer {
buf.append(" bgcolor=\"lightgrey\"");
}
colorize = !colorize;
buf.append("> " + PMD.EOL);
buf.append("<td>" + ce.rule().getName() + "</td>" + PMD.EOL);
buf.append("<td>" + ce.issue() + "</td>" + PMD.EOL);
buf.append("</tr>" + PMD.EOL);
buf.append("> ").append(PMD.EOL);
buf.append("<td>").append(ce.rule().getName()).append("</td>").append(PMD.EOL);
buf.append("<td>").append(ce.issue()).append("</td>").append(PMD.EOL);
buf.append("</tr>").append(PMD.EOL);
writer.write(buf.toString());
}
writer.write("</table>");

View File

@ -35,7 +35,7 @@ public class TextRenderer extends AbstractIncrementingRenderer {
buf.setLength(0);
RuleViolation rv = violations.next();
buf.append(determineFileName(rv.getFilename()));
buf.append(':').append(Integer.toString(rv.getBeginLine()));
buf.append(':').append(rv.getBeginLine());
buf.append(":\t").append(rv.getDescription()).append(PMD.EOL);
writer.write(buf.toString());
}
@ -44,7 +44,7 @@ public class TextRenderer extends AbstractIncrementingRenderer {
@Override
public void end() throws IOException {
StringBuilder buf = new StringBuilder(500);
for (Report.ProcessingError error : errors) {
buf.setLength(0);
buf.append(determineFileName(error.getFile()));
@ -54,13 +54,15 @@ public class TextRenderer extends AbstractIncrementingRenderer {
for (Report.SuppressedViolation excluded : suppressed) {
buf.setLength(0);
buf.append(excluded.getRuleViolation().getRule().getName());
buf.append(" rule violation suppressed by ");
buf.append(excluded.suppressedByNOPMD() ? "//NOPMD" : "Annotation");
buf.append(" in ").append(determineFileName(excluded.getRuleViolation().getFilename())).append(PMD.EOL);
buf.append(excluded.getRuleViolation().getRule().getName())
.append(" rule violation suppressed by ")
.append(excluded.getSuppressor().getId())
.append(" in ")
.append(determineFileName(excluded.getRuleViolation().getFilename()))
.append(PMD.EOL);
writer.write(buf.toString());
}
for (Report.ConfigurationError error : configErrors) {
buf.setLength(0);
buf.append(error.rule().getName());

View File

@ -8,6 +8,7 @@ import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.PMDVersion;
@ -135,7 +136,7 @@ public class XMLRenderer extends AbstractIncrementingRenderer {
buf.append("<suppressedviolation ").append("filename=\"");
StringUtil.appendXmlEscaped(buf, determineFileName(s.getRuleViolation().getFilename()), useUTF8);
buf.append("\" suppressiontype=\"");
StringUtil.appendXmlEscaped(buf, s.suppressedByNOPMD() ? "nopmd" : "annotation", useUTF8);
StringUtil.appendXmlEscaped(buf, s.getSuppressor().getId().toLowerCase(Locale.ROOT), useUTF8);
buf.append("\" msg=\"");
StringUtil.appendXmlEscaped(buf, s.getRuleViolation().getDescription(), useUTF8);
buf.append("\" usermsg=\"");
@ -144,7 +145,7 @@ public class XMLRenderer extends AbstractIncrementingRenderer {
writer.write(buf.toString());
}
}
// config errors
for (final Report.ConfigurationError ce : configErrors) {
buf.setLength(0);

View File

@ -19,9 +19,11 @@ import org.junit.Test;
import net.sourceforge.pmd.lang.DummyLanguageModule;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.DummyRoot;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.AbstractRule;
import net.sourceforge.pmd.lang.rule.ParametricRuleViolation;
import net.sourceforge.pmd.lang.rule.impl.DefaultRuleViolationFactory;
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyFactory;
import net.sourceforge.pmd.properties.StringProperty;
@ -110,9 +112,8 @@ public class AbstractRuleTest {
ctx.setLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getDefaultVersion());
ctx.setReport(new Report());
ctx.setSourceCodeFile(new File("filename"));
DummyNode s = new DummyNode(1);
s.testingOnlySetBeginColumn(5);
s.testingOnlySetBeginLine(5);
DummyNode s = new DummyRoot();
s.setCoords(5, 1, 6, 0);
s.setImage("TestImage");
r.addViolation(ctx, s);
RuleViolation rv = ctx.getReport().getViolationTree().iterator().next();
@ -124,15 +125,12 @@ public class AbstractRuleTest {
MyRule r = new MyRule();
RuleContext ctx = new RuleContext();
Map<Integer, String> m = new HashMap<>();
m.put(Integer.valueOf(5), "");
ctx.setReport(new Report());
ctx.getReport().suppress(m);
m.put(5, "");
ctx.setSourceCodeFile(new File("filename"));
DummyNode n = new DummyNode(1);
n.testingOnlySetBeginColumn(5);
n.testingOnlySetBeginLine(5);
RuleViolation rv = new ParametricRuleViolation<>(r, ctx, n, "specificdescription");
ctx.getReport().addRuleViolation(rv);
DummyRoot n = new DummyRoot(m);
n.setCoords(5, 1, 6, 0);
DefaultRuleViolationFactory.defaultInstance().addViolation(ctx, r, n, "specificdescription", new Object[0]);
assertTrue(ctx.getReport().isEmpty());
}
@ -210,7 +208,7 @@ public class AbstractRuleTest {
assertEquals("Rules with different messages are still equal", r1, r2);
assertEquals("Rules that are equal must have the an equal hashcode", r1.hashCode(), r2.hashCode());
}
@Test
public void testDeepCopyRule() {
MyRule r1 = new MyRule();

View File

@ -30,6 +30,7 @@ import net.sourceforge.pmd.lang.Dummy2LanguageModule;
import net.sourceforge.pmd.lang.DummyLanguageModule;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.DummyRoot;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.MockRule;
import net.sourceforge.pmd.lang.rule.RuleReference;
@ -501,9 +502,8 @@ public class RuleSetTest {
private List<Node> makeCompilationUnits() {
List<Node> nodes = new ArrayList<>();
DummyNode node = new DummyNode(1);
node.testingOnlySetBeginLine(1);
node.testingOnlySetBeginColumn(1);
DummyNode node = new DummyRoot();
node.setCoords(1, 1, 10, 1);
node.setImage("Foo");
nodes.add(node);
return nodes;

View File

@ -7,21 +7,19 @@ package net.sourceforge.pmd.lang;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.ast.DummyAstStages;
import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.DummyRoot;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.ParseException;
import net.sourceforge.pmd.lang.ast.RootNode;
import net.sourceforge.pmd.lang.rule.AbstractRuleChainVisitor;
import net.sourceforge.pmd.lang.rule.AbstractRuleViolationFactory;
import net.sourceforge.pmd.lang.rule.ParametricRuleViolation;
import net.sourceforge.pmd.lang.rule.impl.DefaultRuleViolationFactory;
/**
* Dummy language used for testing PMD.
@ -80,18 +78,12 @@ public class DummyLanguageModule extends BaseLanguageModule {
return new AbstractParser(parserOptions) {
@Override
public Node parse(String fileName, Reader source) throws ParseException {
DummyNode node = new DummyRootNode(1);
node.testingOnlySetBeginLine(1);
node.testingOnlySetBeginColumn(1);
DummyNode node = new DummyRoot();
node.setCoords(1, 1, 2, 10);
node.setImage("Foo");
return node;
}
@Override
public Map<Integer, String> getSuppressMap() {
return Collections.emptyMap();
}
@Override
protected TokenManager createTokenManager(Reader source) {
return null;
@ -100,15 +92,7 @@ public class DummyLanguageModule extends BaseLanguageModule {
}
}
private static class DummyRootNode extends DummyNode implements RootNode {
DummyRootNode(int id) {
super(id);
}
}
public static class RuleViolationFactory extends AbstractRuleViolationFactory {
public static class RuleViolationFactory extends DefaultRuleViolationFactory {
@Override
protected RuleViolation createRuleViolation(Rule rule, RuleContext ruleContext, Node node, String message) {
return createRuleViolation(rule, ruleContext, node, message, 0, 0);
@ -118,6 +102,7 @@ public class DummyLanguageModule extends BaseLanguageModule {
protected RuleViolation createRuleViolation(Rule rule, RuleContext ruleContext, Node node, String message,
int beginLine, int endLine) {
ParametricRuleViolation<Node> rv = new ParametricRuleViolation<Node>(rule, ruleContext, node, message) {
@Override
public String getPackageName() {
this.packageName = "foo"; // just for testing variable expansion
return super.getPackageName();

Some files were not shown because too many files have changed in this diff Show More