Analysis listener

Big cleanup of RuleContext, RuleViolationFactory API

Somewhat depends on text documents (FileLocation actually)
This commit is contained in:
Clément Fournier
2020-07-29 17:38:26 +02:00
parent 08b19dbcdd
commit dafe49f84a
31 changed files with 393 additions and 374 deletions

View File

@ -4,6 +4,8 @@
package net.sourceforge.pmd;
import static java.util.Collections.synchronizedList;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
@ -12,6 +14,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sourceforge.pmd.lang.ast.FileAnalysisException;
import net.sourceforge.pmd.renderers.AbstractAccumulatingRenderer;
/**
@ -23,10 +26,10 @@ public class Report {
private final List<ThreadSafeReportListener> listeners = new ArrayList<>();
private final List<RuleViolation> violations = new ArrayList<>();
private final List<SuppressedViolation> suppressedRuleViolations = new ArrayList<>();
private final List<ProcessingError> errors = new ArrayList<>();
private final List<ConfigurationError> configErrors = new ArrayList<>();
private final List<RuleViolation> violations = synchronizedList(new ArrayList<>());
private final List<SuppressedViolation> suppressedRuleViolations = synchronizedList(new ArrayList<>());
private final List<ProcessingError> errors = synchronizedList(new ArrayList<>());
private final List<ConfigurationError> configErrors = synchronizedList(new ArrayList<>());
/**
* Creates a new, initialized, empty report for the given file name.
@ -52,6 +55,7 @@ public class Report {
* Represents a configuration error.
*/
public static class ConfigurationError {
private final Rule rule;
private final String issue;
@ -91,6 +95,7 @@ public class Report {
* Represents a processing error, such as a parse error.
*/
public static class ProcessingError {
private final Throwable error;
private final String file;
@ -113,7 +118,7 @@ public class Report {
public String getDetail() {
try (StringWriter stringWriter = new StringWriter();
PrintWriter writer = new PrintWriter(stringWriter)) {
PrintWriter writer = new PrintWriter(stringWriter)) {
error.printStackTrace(writer);
return stringWriter.toString();
} catch (IOException e) {
@ -135,6 +140,7 @@ public class Report {
* Represents a violation, that has been suppressed.
*/
public static class SuppressedViolation {
private final RuleViolation rv;
private final String userMessage;
private final ViolationSuppressor suppressor;
@ -277,10 +283,48 @@ public class Report {
/**
* Adds all given listeners to this report
*
* @param allListeners
* the report listeners
* @param allListeners the report listeners
*/
public void addListeners(List<ThreadSafeReportListener> allListeners) {
listeners.addAll(allListeners);
}
public static class ReportBuilderListener implements ThreadSafeAnalysisListener {
private final Report report = new Report();
private boolean done;
/**
* Returns the final report.
*
* @throws IllegalStateException If {@link #finish()} has not been called yet
*/
public Report getReport() {
if (!done) {
throw new IllegalStateException("Reporting not done");
}
return report;
}
@Override
public void onRuleViolation(RuleViolation violation) {
report.addRuleViolation(violation);
}
@Override
public void onSuppressedRuleViolation(SuppressedViolation violation) {
report.addSuppressedViolation(violation);
}
@Override
public void onError(FileAnalysisException exception) {
report.addError(new ProcessingError(exception, exception.getFileName()));
}
@Override
public void finish() {
done = true;
}
}
}

View File

@ -5,9 +5,19 @@
package net.sourceforge.pmd;
import java.io.File;
import java.text.MessageFormat;
import java.util.Objects;
import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.NonNull;
import net.sourceforge.pmd.Report.ProcessingError;
import net.sourceforge.pmd.Report.SuppressedViolation;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.ParametricRuleViolation;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
/**
* The RuleContext provides access to Rule processing state. This information
@ -25,7 +35,9 @@ import net.sourceforge.pmd.lang.LanguageVersion;
* between calls to difference source files. Failure to do so, may result in
* undefined behavior.
*/
public class RuleContext {
public class RuleContext implements AutoCloseable {
private static final Object[] NO_ARGS = new Object[0];
private static final Logger LOG = Logger.getLogger(RuleContext.class.getName());
@ -34,25 +46,88 @@ public class RuleContext {
private LanguageVersion languageVersion;
private boolean ignoreExceptions = true;
private final ThreadSafeAnalysisListener listener;
/**
* Default constructor.
*/
public RuleContext() {
// nothing to do
listener = ThreadSafeAnalysisListener.noop();
}
/**
* Constructor which shares attributes and report listeners with the given
* RuleContext.
*
* @param ruleContext
* the context from which the values are shared
* @param ruleContext the context from which the values are shared
*/
public RuleContext(RuleContext ruleContext) {
this.report.addListeners(ruleContext.getReport().getListeners());
this.listener = ruleContext.listener;
this.setIgnoreExceptions(ruleContext.ignoreExceptions);
}
public RuleContext(ThreadSafeAnalysisListener listener) {
this.listener = listener;
}
@Override
public void close() throws Exception {
listener.finish();
}
public void addError(ProcessingError error) {
}
public void addViolation(Rule rule, Node location) {
addViolationWithMessage(rule, location, rule.getMessage(), NO_ARGS);
}
public void addViolation(Rule rule, Node location, Object... formatArgs) {
addViolationWithMessage(rule, location, rule.getMessage(), formatArgs);
}
public void addViolationWithMessage(Rule rule, Node location, String message) {
addViolationWithPosition(rule, location, -1, -1, message, NO_ARGS);
}
public void addViolationWithMessage(Rule rule, Node location, String message, Object... formatArgs) {
addViolationWithPosition(rule, location, -1, -1, message, formatArgs);
}
public void addViolationWithPosition(Rule rule, Node location, int beginLine, int endLine, String message, Object... formatArgs) {
Objects.requireNonNull(rule);
Objects.requireNonNull(location);
Objects.requireNonNull(message);
Objects.requireNonNull(formatArgs);
RuleViolationFactory fact = getLanguageVersion().getLanguageVersionHandler().getRuleViolationFactory();
RuleViolation violation = fact.createViolation(rule, location, getSourceCodeFilename(), makeMessage(message, formatArgs));
if (beginLine != -1 && endLine != -1) {
// fixme, this is needed until we have actual Location objects
((ParametricRuleViolation<?>) violation).setLines(beginLine, endLine);
}
SuppressedViolation suppressed = fact.suppressOrNull(location, violation);
if (suppressed != null) {
listener.onSuppressedRuleViolation(suppressed);
} else {
listener.onRuleViolation(violation);
}
}
private String makeMessage(@NonNull String message, Object[] args) {
// 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);
}
/**
* Get the Report to which Rule Violations are sent.
*

View File

@ -0,0 +1,82 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd;
import net.sourceforge.pmd.Report.ReportBuilderListener;
import net.sourceforge.pmd.Report.SuppressedViolation;
import net.sourceforge.pmd.lang.ast.FileAnalysisException;
import net.sourceforge.pmd.renderers.Renderer;
/**
* A handler for analysis events. This must be thread safe.
*/
public interface ThreadSafeAnalysisListener {
/**
* Handle a new violation (not suppressed).
*/
default void onRuleViolation(RuleViolation violation) {
}
/**
* Handle a new suppressed violation.
*/
default void onSuppressedRuleViolation(SuppressedViolation violation) {
}
/**
* Handle an error that occurred while processing a file.
*/
default void onError(FileAnalysisException exception) {
}
/**
* All files have been processed.
*/
default void finish() throws Exception {
}
static ThreadSafeAnalysisListener noop() {
return new ThreadSafeAnalysisListener() {};
}
static ThreadSafeAnalysisListener forReporter(Renderer renderer) {
ReportBuilderListener reportBuilder = new ReportBuilderListener();
return new ThreadSafeAnalysisListener() {
@Override
public void onRuleViolation(RuleViolation violation) {
reportBuilder.onRuleViolation(violation);
}
@Override
public void onSuppressedRuleViolation(SuppressedViolation violation) {
reportBuilder.onSuppressedRuleViolation(violation);
}
@Override
public void onError(FileAnalysisException exception) {
reportBuilder.onError(exception);
}
@Override
public void finish() throws Exception {
reportBuilder.finish();
renderer.renderFileReport(reportBuilder.getReport());
renderer.end();
renderer.flush();
}
};
}
}

View File

@ -59,7 +59,7 @@ public abstract class JavaCCTokenizer implements Tokenizer {
currentToken = tokenFilter.getNextToken();
}
} catch (TokenMgrError e) {
throw e.withFileName(sourceCode.getFileName());
throw e.setFileName(sourceCode.getFileName());
} finally {
tokenEntries.add(TokenEntry.getEOF());
}

View File

@ -4,7 +4,8 @@
package net.sourceforge.pmd.lang;
import java.util.Collections;
import static java.util.Collections.emptyList;
import java.util.List;
import net.sourceforge.pmd.annotation.Experimental;
@ -41,7 +42,7 @@ public interface LanguageVersionHandler {
*/
@Experimental
default List<? extends AstProcessingStage<?>> getProcessingStages() {
return Collections.emptyList();
return emptyList();
}

View File

@ -4,6 +4,10 @@
package net.sourceforge.pmd.lang.ast;
import java.util.Objects;
import org.checkerframework.checker.nullness.qual.NonNull;
/**
* An exception that occurs while processing a file. Subtypes include
* <ul>
@ -15,6 +19,9 @@ package net.sourceforge.pmd.lang.ast;
*/
public class FileAnalysisException extends RuntimeException {
protected static final String UNKNOWN_FNAME = "(unknown file)";
private String filename = UNKNOWN_FNAME;
public FileAnalysisException() {
super();
}
@ -26,8 +33,24 @@ public class FileAnalysisException extends RuntimeException {
public FileAnalysisException(Throwable cause) {
super(cause);
}
public FileAnalysisException(String message, Throwable cause) {
super(message, cause);
}
FileAnalysisException setFileName(String filename) {
this.filename = Objects.requireNonNull(filename);
return this;
}
protected boolean hasFileName() {
return !UNKNOWN_FNAME.equals(filename);
}
/**
* The name of the file in which the error occurred.
*/
public @NonNull String getFileName() {
return filename;
}
}

View File

@ -16,14 +16,13 @@ public final class TokenMgrError extends FileAnalysisException {
private final int line;
private final int column;
private final String filename;
/**
* Create a new exception.
*
* @param line Line number
* @param column Column number
* @param filename Filename. If unknown, it can be completed with {@link #withFileName(String)} later
* @param filename Filename. If unknown, it can be completed with {@link #setFileName(String)} later
* @param message Message of the error
* @param cause Cause of the error, if any
*/
@ -31,7 +30,9 @@ public final class TokenMgrError extends FileAnalysisException {
super(message, cause);
this.line = line;
this.column = column;
this.filename = filename;
if (filename != null) {
super.setFileName(filename);
}
}
/**
@ -42,7 +43,6 @@ public final class TokenMgrError extends FileAnalysisException {
super(makeReason(eofSeen, lexStateName, errorAfter, curChar));
line = errorLine;
column = errorColumn;
filename = null; // may be replaced with #withFileName
}
public int getLine() {
@ -53,14 +53,11 @@ public final class TokenMgrError extends FileAnalysisException {
return column;
}
public @Nullable String getFilename() {
return filename;
}
@Override
public String getMessage() {
String leader = filename != null ? "Lexical error in file " + filename : "Lexical error";
String leader = hasFileName() ? "Lexical error in file " + getFileName() : "Lexical error";
return leader + " at line " + line + ", column " + column + ". Encountered: " + super.getMessage();
}
@ -71,8 +68,9 @@ public final class TokenMgrError extends FileAnalysisException {
*
* @return A new exception
*/
public TokenMgrError withFileName(String filename) {
return new TokenMgrError(this.line, this.column, filename, this.getMessage(), this.getCause());
public TokenMgrError setFileName(String filename) {
super.setFileName(filename);
return this;
}
private static String makeReason(boolean eofseen, String lexStateName, String errorAfter, char curChar) {

View File

@ -36,7 +36,7 @@ public abstract class JjtreeParserAdapter<R extends RootNode> implements Parser
try {
return parseImpl(charStream, task.getCommentMarker());
} catch (TokenMgrError tme) {
throw tme.withFileName(task.getFileDisplayName());
throw tme.setFileName(task.getFileDisplayName());
}
}

View File

@ -288,63 +288,35 @@ public abstract class AbstractRule extends AbstractPropertySource implements Rul
}
/**
* @see RuleViolationFactory#addViolation(RuleContext, Rule, Node, String,
* Object[])
* @see RuleContext#addViolation(Rule, Node, Object...)
*/
public void addViolation(Object data, Node node) {
RuleContext ruleContext = (RuleContext) data;
ruleContext.getLanguageVersion().getLanguageVersionHandler().getRuleViolationFactory().addViolation(ruleContext,
this, node, this.getMessage(), null);
((RuleContext) data).addViolation(this, node);
}
/**
* @see RuleViolationFactory#addViolation(RuleContext, Rule, Node, String,
* Object[])
* @see RuleContext#addViolation(Rule, Node, Object...)
*/
public void addViolation(Object data, Node node, String arg) {
RuleContext ruleContext = (RuleContext) data;
ruleContext.getLanguageVersion().getLanguageVersionHandler().getRuleViolationFactory().addViolation(ruleContext,
this, node, this.getMessage(), new Object[]{arg});
public void addViolation(Object data, Node node, Object... args) {
((RuleContext) data).addViolation(this, node, args);
}
/**
* @see RuleViolationFactory#addViolation(RuleContext, Rule, Node, String,
* Object[])
*/
public void addViolation(Object data, Node node, Object[] args) {
RuleContext ruleContext = (RuleContext) data;
ruleContext.getLanguageVersion().getLanguageVersionHandler().getRuleViolationFactory().addViolation(ruleContext,
this, node, this.getMessage(), args);
}
/**
* @see RuleViolationFactory#addViolation(RuleContext, Rule, Node, String,
* Object[])
* @see RuleContext#addViolationWithMessage(Rule, Node, String, Object...)
*/
public void addViolationWithMessage(Object data, Node node, String message) {
RuleContext ruleContext = (RuleContext) data;
ruleContext.getLanguageVersion().getLanguageVersionHandler().getRuleViolationFactory().addViolation(ruleContext,
this, node, message, null);
((RuleContext) data).addViolationWithMessage(this, node, message);
}
/**
* @see RuleViolationFactory#addViolation(RuleContext, Rule, Node, String,
* Object[])
*/
public void addViolationWithMessage(Object data, Node node, String message, int beginLine, int endLine) {
RuleContext ruleContext = (RuleContext) data;
ruleContext.getLanguageVersion().getLanguageVersionHandler().getRuleViolationFactory().addViolation(ruleContext,
this, node, message, beginLine, endLine, null);
((RuleContext) data).addViolationWithPosition(this, node, beginLine, endLine, message);
}
/**
* @see RuleViolationFactory#addViolation(RuleContext, Rule, Node, String,
* Object[])
* @see RuleContext#addViolationWithMessage(Rule, Node, String, Object...)
*/
public void addViolationWithMessage(Object data, Node node, String message, Object[] args) {
RuleContext ruleContext = (RuleContext) data;
ruleContext.getLanguageVersion().getLanguageVersionHandler().getRuleViolationFactory().addViolation(ruleContext,
this, node, message, args);
((RuleContext) data).addViolationWithMessage(this, node, message, args);
}
/**

View File

@ -4,10 +4,7 @@
package net.sourceforge.pmd.lang.rule;
import java.io.File;
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.properties.PropertyDescriptor;
@ -34,16 +31,11 @@ public class ParametricRuleViolation<T extends Node> implements RuleViolation {
// 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) {
public ParametricRuleViolation(Rule theRule, String filename, T node, String message) {
rule = theRule;
description = message;
this.filename = filename == null ? "" : filename;
File file = ctx.getSourceCodeFile();
if (file != null) {
filename = file.getPath();
} else {
filename = "";
}
if (node != null) {
beginLine = node.getBeginLine();
beginColumn = node.getBeginColumn();

View File

@ -4,38 +4,26 @@
package net.sourceforge.pmd.lang.rule;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.NonNull;
import net.sourceforge.pmd.Report.SuppressedViolation;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.LanguageVersionHandler;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.ast.Node;
/**
* This class handles of producing a Language specific RuleViolation and adding
* to a Report.
* Creates violations and controls suppression behavior for a language.
*
* <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()}.
* TODO split this into violation decorators + violation suppressors.
* There is no need to have language-specific violation classes.
*/
public interface RuleViolationFactory {
/**
* Adds a violation to the report.
*
* @param ruleContext
* the RuleContext
* @param rule
* the rule
* @param node
* the node that produces the violation
* @param message
* specific message to put in the report
* @param args
* arguments to embed in the rule violation message
*/
void addViolation(RuleContext ruleContext, Rule rule, @Nullable Node node, String message, Object[] args);
void addViolation(RuleContext ruleContext, Rule rule, @Nullable Node node, String message, int beginLine, int endLine, Object[] args);
RuleViolation createViolation(Rule rule, @NonNull Node location, String filename, String formattedMessage);
SuppressedViolation suppressOrNull(Node location, RuleViolation violation);
}

View File

@ -4,18 +4,15 @@
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 org.checkerframework.checker.nullness.qual.NonNull;
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;
@ -31,58 +28,23 @@ import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
*/
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);
public RuleViolation createViolation(Rule rule, @NonNull Node location, String filename, String formattedMessage) {
return new ParametricRuleViolation<>(rule, filename, location, formattedMessage);
}
@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;
}
public final SuppressedViolation suppressOrNull(Node location, RuleViolation violation) {
for (ViolationSuppressor suppressor : getAllSuppressors()) {
SuppressedViolation suppressed = suppressor.suppressOrNull(violation, location);
if (suppressed != null) {
return suppressed;
}
}
ruleContext.getReport().addRuleViolation(rv);
return null;
}
/**
@ -93,17 +55,6 @@ public class DefaultRuleViolationFactory implements RuleViolationFactory {
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

View File

@ -62,7 +62,7 @@ public class RuleApplicator {
rcto.close(1);
} catch (RuntimeException e) {
if (ctx.isIgnoreExceptions()) {
ctx.getReport().addError(new ProcessingError(e, ctx.getSourceCodeFilename()));
ctx.addError(new ProcessingError(e, ctx.getSourceCodeFilename()));
if (LOG.isLoggable(Level.WARNING)) {
LOG.log(Level.WARNING, "Exception applying rule " + rule.getName() + " on file "

View File

@ -7,14 +7,16 @@ package net.sourceforge.pmd;
import static net.sourceforge.pmd.properties.constraints.NumericConstraints.inRange;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.util.HashMap;
import java.util.Collections;
import java.util.Map;
import org.junit.Test;
import net.sourceforge.pmd.Report.ReportBuilderListener;
import net.sourceforge.pmd.Report.SuppressedViolation;
import net.sourceforge.pmd.lang.DummyLanguageModule;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.ast.DummyNode;
@ -73,11 +75,9 @@ public class AbstractRuleTest {
public void testCreateRV() {
MyRule r = new MyRule();
r.setRuleSetName("foo");
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
DummyNode s = new DummyNode();
s.setCoords(5, 5, 5, 10);
RuleViolation rv = new ParametricRuleViolation(r, ctx, s, r.getMessage());
RuleViolation rv = new ParametricRuleViolation<>(r, "filename", s, r.getMessage());
assertEquals("Line number mismatch!", 5, rv.getBeginLine());
assertEquals("Filename mismatch!", "filename", rv.getFilename());
assertEquals("Rule object mismatch!", r, rv.getRule());
@ -88,11 +88,9 @@ public class AbstractRuleTest {
@Test
public void testCreateRV2() {
MyRule r = new MyRule();
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
DummyNode s = new DummyNode();
s.setCoords(5, 5, 5, 10);
RuleViolation rv = new ParametricRuleViolation<>(r, ctx, s, "specificdescription");
RuleViolation rv = new ParametricRuleViolation<>(r, "filename", s, "specificdescription");
assertEquals("Line number mismatch!", 5, rv.getBeginLine());
assertEquals("Filename mismatch!", "filename", rv.getFilename());
assertEquals("Rule object mismatch!", r, rv.getRule());
@ -100,34 +98,32 @@ public class AbstractRuleTest {
}
@Test
public void testRuleWithVariableInMessage() {
public void testRuleWithVariableInMessage() throws Exception {
MyRule r = new MyRule();
r.definePropertyDescriptor(PropertyFactory.intProperty("testInt").desc("description").require(inRange(0, 100)).defaultValue(10).build());
r.setMessage("Message ${packageName} ${className} ${methodName} ${variableName} ${testInt} ${noSuchProperty}");
RuleContext ctx = new RuleContext();
ctx.setLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getDefaultVersion());
ctx.setReport(new Report());
ctx.setSourceCodeFile(new File("filename"));
DummyNode s = new DummyRoot();
s.setCoords(5, 1, 6, 1);
s.setImage("TestImage");
r.addViolation(ctx, s);
RuleViolation rv = ctx.getReport().getViolations().get(0);
ReportBuilderListener listener = new ReportBuilderListener();
try (RuleContext ctx = new RuleContext(listener)) {
ctx.setLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getDefaultVersion());
ctx.setSourceCodeFile(new File("filename"));
DummyNode s = new DummyRoot();
s.setCoords(5, 1, 6, 1);
s.setImage("TestImage");
r.addViolation(ctx, s);
}
RuleViolation rv = listener.getReport().getViolations().get(0);
assertEquals("Message foo 10 ${noSuchProperty}", rv.getDescription());
}
@Test
public void testRuleSuppress() {
MyRule r = new MyRule();
RuleContext ctx = new RuleContext();
Map<Integer, String> m = new HashMap<>();
m.put(5, "");
ctx.setSourceCodeFile(new File("filename"));
Map<Integer, String> m = Collections.singletonMap(5, "");
DummyRoot n = new DummyRoot(m);
n.setCoords(5, 1, 6, 1);
DefaultRuleViolationFactory.defaultInstance().addViolation(ctx, r, n, "specificdescription", new Object[0]);
RuleViolation violation = DefaultRuleViolationFactory.defaultInstance().createViolation(new MyRule(), n, "file", "specificdescription");
SuppressedViolation suppressed = DefaultRuleViolationFactory.defaultInstance().suppressOrNull(n, violation);
assertTrue(ctx.getReport().getViolations().isEmpty());
assertNotNull(suppressed);
}
@Test

View File

@ -7,7 +7,6 @@ package net.sourceforge.pmd;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringWriter;
@ -38,15 +37,12 @@ public class ReportTest implements ThreadSafeReportListener {
@Test
public void testSortedReportFile() throws IOException {
Report r = new Report();
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("foo"));
Node s = getNode(10, 5);
Rule rule1 = new MockRule("name", "desc", "msg", "rulesetname");
r.addRuleViolation(new ParametricRuleViolation<>(rule1, ctx, s, rule1.getMessage()));
ctx.setSourceCodeFile(new File("bar"));
r.addRuleViolation(new ParametricRuleViolation<>(rule1, "foo", s, rule1.getMessage()));
Node s1 = getNode(10, 5);
Rule rule2 = new MockRule("name", "desc", "msg", "rulesetname");
r.addRuleViolation(new ParametricRuleViolation<>(rule2, ctx, s1, rule2.getMessage()));
r.addRuleViolation(new ParametricRuleViolation<>(rule2, "bar", s1, rule2.getMessage()));
Renderer rend = new XMLRenderer();
String result = render(rend, r);
assertTrue("sort order wrong", result.indexOf("bar") < result.indexOf("foo"));
@ -55,16 +51,13 @@ public class ReportTest implements ThreadSafeReportListener {
@Test
public void testSortedReportLine() throws IOException {
Report r = new Report();
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("foo1")); // same file!!
Node node1 = getNode(20, 5); // line 20: after rule2 violation
Rule rule1 = new MockRule("rule1", "rule1", "msg", "rulesetname");
r.addRuleViolation(new ParametricRuleViolation<>(rule1, ctx, node1, rule1.getMessage()));
r.addRuleViolation(new ParametricRuleViolation<>(rule1, "foo1", node1, rule1.getMessage()));
ctx.setSourceCodeFile(new File("foo1")); // same file!!
Node node2 = getNode(10, 5); // line 10: before rule1 violation
Rule rule2 = new MockRule("rule2", "rule2", "msg", "rulesetname");
r.addRuleViolation(new ParametricRuleViolation<>(rule2, ctx, node2, rule2.getMessage()));
r.addRuleViolation(new ParametricRuleViolation<>(rule2, "foo1", node2, rule2.getMessage())); // same file!!
Renderer rend = new XMLRenderer();
String result = render(rend, r);
assertTrue("sort order wrong", result.indexOf("rule2") < result.indexOf("rule1"));
@ -75,23 +68,20 @@ public class ReportTest implements ThreadSafeReportListener {
Report rpt = new Report();
rpt.addListener(this);
violationSemaphore = false;
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("file"));
Node s = getNode(5, 5);
Rule rule1 = new MockRule("name", "desc", "msg", "rulesetname");
rpt.addRuleViolation(new ParametricRuleViolation<>(rule1, ctx, s, rule1.getMessage()));
rpt.addRuleViolation(new ParametricRuleViolation<>(rule1, "file", s, rule1.getMessage()));
assertTrue(violationSemaphore);
}
@Test
public void testIterator() {
Report r = new Report();
RuleContext ctx = new RuleContext();
Rule rule = new MockRule("name", "desc", "msg", "rulesetname");
Node node1 = getNode(5, 5, true);
r.addRuleViolation(new ParametricRuleViolation<>(rule, ctx, node1, rule.getMessage()));
r.addRuleViolation(new ParametricRuleViolation<>(rule, "", node1, rule.getMessage()));
Node node2 = getNode(5, 6, true);
r.addRuleViolation(new ParametricRuleViolation<>(rule, ctx, node2, rule.getMessage()));
r.addRuleViolation(new ParametricRuleViolation<>(rule, "", node2, rule.getMessage()));
assertEquals(2, r.getViolations().size());
}

View File

@ -9,8 +9,12 @@ import static org.junit.Assert.assertNull;
import java.io.File;
import org.junit.Assert;
import org.junit.Test;
import net.sourceforge.pmd.Report.ReportBuilderListener;
import net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil;
import junit.framework.JUnit4TestAdapter;
public class RuleContextTest {
@ -33,6 +37,29 @@ public class RuleContextTest {
assertEquals("filename mismatch", "foo.java", ctx.getSourceCodeFilename());
}
@Test
public void testMessage() throws Exception {
ReportBuilderListener listener = new ReportBuilderListener();
try (RuleContext ctx = new RuleContext(listener)) {
ctx.addViolationWithMessage(new FooRule(), DummyTreeUtil.tree(DummyTreeUtil::root), "message with \"'{'\"");
}
RuleViolation violation = listener.getReport().getViolations().get(0);
Assert.assertEquals("message with \"{\"", violation.getDescription());
}
@Test
public void testMessageArgs() throws Exception {
ReportBuilderListener listener = new ReportBuilderListener();
try (RuleContext ctx = new RuleContext(listener)) {
ctx.addViolationWithMessage(new FooRule(), DummyTreeUtil.tree(DummyTreeUtil::root), "message with 1 argument: \"{0}\"", "testarg1");
}
RuleViolation violation = listener.getReport().getViolations().get(0);
Assert.assertEquals("message with 1 argument: \"testarg1\"", violation.getDescription());
}
@Test
public void testSourceCodeFile() {
RuleContext ctx = new RuleContext();

View File

@ -7,7 +7,6 @@ package net.sourceforge.pmd;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -71,10 +70,8 @@ public class RuleViolationComparatorTest {
private RuleViolation createJavaRuleViolation(Rule rule, String fileName, int beginLine, String description,
int beginColumn, int endLine, int endColumn) {
RuleContext ruleContext = new RuleContext();
ruleContext.setSourceCodeFile(new File(fileName));
DummyNode simpleNode = new DummyNode();
simpleNode.setCoords(beginLine, beginColumn, endLine, endColumn);
return new ParametricRuleViolation<Node>(rule, ruleContext, simpleNode, description);
return new ParametricRuleViolation<Node>(rule, fileName, simpleNode, description);
}
}

View File

@ -7,8 +7,6 @@ package net.sourceforge.pmd;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import org.junit.Ignore;
import org.junit.Test;
@ -24,11 +22,9 @@ public class RuleViolationTest {
@Test
public void testConstructor1() {
Rule rule = new MockRule("name", "desc", "msg", "rulesetname");
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
DummyNode s = new DummyNode();
s.setCoords(2, 1, 2, 3);
RuleViolation r = new ParametricRuleViolation<Node>(rule, ctx, s, rule.getMessage());
RuleViolation r = new ParametricRuleViolation<Node>(rule, "filename", s, rule.getMessage());
assertEquals("object mismatch", rule, r.getRule());
assertEquals("line number is wrong", 2, r.getBeginLine());
assertEquals("filename is wrong", "filename", r.getFilename());
@ -37,11 +33,9 @@ public class RuleViolationTest {
@Test
public void testConstructor2() {
Rule rule = new MockRule("name", "desc", "msg", "rulesetname");
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
DummyNode s = new DummyNode();
s.setCoords(2, 1, 2, 3);
RuleViolation r = new ParametricRuleViolation<Node>(rule, ctx, s, "description");
RuleViolation r = new ParametricRuleViolation<Node>(rule, "filename", s, "description");
assertEquals("object mismatch", rule, r.getRule());
assertEquals("line number is wrong", 2, r.getBeginLine());
assertEquals("filename is wrong", "filename", r.getFilename());
@ -52,15 +46,12 @@ public class RuleViolationTest {
public void testComparatorWithDifferentFilenames() {
Rule rule = new MockRule("name", "desc", "msg", "rulesetname");
RuleViolationComparator comp = RuleViolationComparator.INSTANCE;
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename1"));
DummyNode s = new DummyNode();
s.setCoords(10, 1, 11, 3);
RuleViolation r1 = new ParametricRuleViolation<Node>(rule, ctx, s, "description");
ctx.setSourceCodeFile(new File("filename2"));
RuleViolation r1 = new ParametricRuleViolation<Node>(rule, "filename1", s, "description");
DummyNode s1 = new DummyNode();
s1.setCoords(10, 1, 11, 3);
RuleViolation r2 = new ParametricRuleViolation<Node>(rule, ctx, s1, "description");
RuleViolation r2 = new ParametricRuleViolation<Node>(rule, "filename2", s1, "description");
assertEquals(-1, comp.compare(r1, r2));
assertEquals(1, comp.compare(r2, r1));
}
@ -69,14 +60,12 @@ public class RuleViolationTest {
public void testComparatorWithSameFileDifferentLines() {
Rule rule = new MockRule("name", "desc", "msg", "rulesetname");
RuleViolationComparator comp = RuleViolationComparator.INSTANCE;
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
DummyNode s = new DummyNode();
s.setCoords(10, 1, 15, 10);
DummyNode s1 = new DummyNode();
s1.setCoords(20, 1, 25, 10);
RuleViolation r1 = new ParametricRuleViolation<Node>(rule, ctx, s, "description");
RuleViolation r2 = new ParametricRuleViolation<Node>(rule, ctx, s1, "description");
RuleViolation r1 = new ParametricRuleViolation<Node>(rule, "filename", s, "description");
RuleViolation r2 = new ParametricRuleViolation<Node>(rule, "filename", s1, "description");
assertTrue(comp.compare(r1, r2) < 0);
assertTrue(comp.compare(r2, r1) > 0);
}
@ -86,14 +75,12 @@ public class RuleViolationTest {
public void testComparatorWithSameFileSameLines() {
Rule rule = new MockRule("name", "desc", "msg", "rulesetname");
RuleViolationComparator comp = RuleViolationComparator.INSTANCE;
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
DummyNode s = new DummyNode();
s.setCoords(10, 1, 15, 10);
DummyNode s1 = new DummyNode();
s.setCoords(10, 1, 15, 10);
RuleViolation r1 = new ParametricRuleViolation<Node>(rule, ctx, s, "description");
RuleViolation r2 = new ParametricRuleViolation<Node>(rule, ctx, s1, "description");
RuleViolation r1 = new ParametricRuleViolation<Node>(rule, "filename", s, "description");
RuleViolation r2 = new ParametricRuleViolation<Node>(rule, "filename", s1, "description");
assertEquals(1, comp.compare(r1, r2));
assertEquals(1, comp.compare(r2, r1));
}

View File

@ -4,8 +4,9 @@
package net.sourceforge.pmd.lang;
import org.checkerframework.checker.nullness.qual.NonNull;
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.DummyRoot;
@ -58,26 +59,14 @@ public class DummyLanguageModule extends BaseLanguageModule {
}
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);
}
@Override
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) {
public RuleViolation createViolation(Rule rule, @NonNull Node location, String filename, String formattedMessage) {
return new ParametricRuleViolation<Node>(rule, filename, location, formattedMessage) {
{
this.packageName = "foo"; // just for testing variable expansion
}
@Override
public String getPackageName() {
return super.getPackageName();
}
};
rv.setLines(beginLine, endLine);
return rv;
}
}
}

View File

@ -5,17 +5,16 @@
package net.sourceforge.pmd.lang.rule;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.ast.DummyRoot;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil;
import net.sourceforge.pmd.lang.rule.impl.DefaultRuleViolationFactory;
public class DefaultRuleViolationFactoryTest {
private RuleContext ruleContext;
private RuleViolationFactory factory = DefaultRuleViolationFactory.defaultInstance();
private static class TestRule extends AbstractRule {
@Override
@ -24,24 +23,11 @@ public class DefaultRuleViolationFactoryTest {
}
}
@Before
public void setup() {
ruleContext = new RuleContext();
}
@Test
public void testMessage() {
factory.addViolation(ruleContext, new TestRule(), null, "message with \"'{'\"", null);
RuleViolation violation = DefaultRuleViolationFactory.defaultInstance().createViolation(new TestRule(), DummyTreeUtil.tree(DummyRoot::new), "file", "Some message");
RuleViolation violation = ruleContext.getReport().getViolations().get(0);
Assert.assertEquals("message with \"{\"", violation.getDescription());
Assert.assertEquals("Some message", violation.getDescription());
}
@Test
public void testMessageArgs() {
factory.addViolation(ruleContext, new TestRule(), null, "message with 1 argument: \"{0}\"", new Object[] {"testarg1"});
RuleViolation violation = ruleContext.getReport().getViolations().get(0);
Assert.assertEquals("message with 1 argument: \"testarg1\"", violation.getDescription());
}
}

View File

@ -6,8 +6,6 @@ package net.sourceforge.pmd.renderers;
import static org.junit.Assert.assertEquals;
import java.io.File;
import org.junit.Test;
import net.sourceforge.pmd.FooRule;
@ -15,7 +13,6 @@ import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.Report.ConfigurationError;
import net.sourceforge.pmd.Report.ProcessingError;
import net.sourceforge.pmd.ReportTest;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.RuleWithProperties;
import net.sourceforge.pmd.lang.ast.DummyNode;
@ -76,9 +73,7 @@ public abstract class AbstractRendererTest {
protected RuleViolation newRuleViolation(int endColumn) {
DummyNode node = createNode(endColumn);
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File(getSourceCodeFilename()));
return new ParametricRuleViolation<Node>(new FooRule(), ctx, node, "blah");
return new ParametricRuleViolation<Node>(new FooRule(), getSourceCodeFilename(), node, "blah");
}
protected static DummyNode createNode(int endColumn) {
@ -90,13 +85,11 @@ public abstract class AbstractRendererTest {
@Test
public void testRuleWithProperties() throws Exception {
DummyNode node = createNode(1);
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File(getSourceCodeFilename()));
Report report = new Report();
RuleWithProperties theRule = new RuleWithProperties();
theRule.setProperty(RuleWithProperties.STRING_PROPERTY_DESCRIPTOR,
"the string value\nsecond line with \"quotes\"");
report.addRuleViolation(new ParametricRuleViolation<Node>(theRule, ctx, node, "blah"));
report.addRuleViolation(new ParametricRuleViolation<Node>(theRule, getSourceCodeFilename(), node, "blah"));
String rendered = ReportTest.render(getRenderer(), report);
assertEquals(filter(getExpectedWithProperties()), filter(rendered));
}

View File

@ -6,14 +6,11 @@ package net.sourceforge.pmd.renderers;
import static org.junit.Assert.assertEquals;
import java.io.File;
import org.junit.Test;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.ReportTest;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.ParametricRuleViolation;
@ -92,8 +89,6 @@ public class CodeClimateRendererTest extends AbstractRendererTest {
@Test
public void testXPathRule() throws Exception {
DummyNode node = createNode(1);
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File(getSourceCodeFilename()));
Report report = new Report();
XPathRule theRule = new XPathRule(XPathVersion.XPATH_3_1, "//dummyNode");
@ -101,7 +96,7 @@ public class CodeClimateRendererTest extends AbstractRendererTest {
theRule.setDescription("desc");
theRule.setName("Foo");
report.addRuleViolation(new ParametricRuleViolation<Node>(theRule, ctx, node, "blah"));
report.addRuleViolation(new ParametricRuleViolation<Node>(theRule, getSourceCodeFilename(), node, "blah"));
String rendered = ReportTest.render(getRenderer(), report);
// Output should be the exact same as for non xpath rules

View File

@ -6,7 +6,7 @@ package net.sourceforge.pmd.renderers;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Collections;
import java.util.Map;
import org.junit.Test;
@ -16,10 +16,12 @@ import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.Report.ConfigurationError;
import net.sourceforge.pmd.Report.ProcessingError;
import net.sourceforge.pmd.Report.ReportBuilderListener;
import net.sourceforge.pmd.ReportTest;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.DummyLanguageModule;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.ast.DummyRoot;
import net.sourceforge.pmd.lang.rule.impl.DefaultRuleViolationFactory;
public class SummaryHTMLRendererTest extends AbstractRendererTest {
@ -146,13 +148,15 @@ public class SummaryHTMLRendererTest extends AbstractRendererTest {
assertEquals(getExpectedEmpty(), actual);
}
private Report createEmptyReportWithSuppression() {
Map<Integer, String> suppressions = new HashMap<>();
suppressions.put(1, "test");
RuleContext ctx = new RuleContext();
DummyRoot root = new DummyRoot(suppressions);
root.setCoords(1, 10, 4, 5);
DefaultRuleViolationFactory.defaultInstance().addViolation(ctx, new FooRule(), root, "suppress test", 1, 1, new Object[0]);
return ctx.getReport();
private Report createEmptyReportWithSuppression() throws Exception {
Map<Integer, String> suppressions = Collections.singletonMap(1, "test");
ReportBuilderListener listener = new ReportBuilderListener();
try (RuleContext ctx = new RuleContext(listener)) {
ctx.setLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getDefaultVersion());
DummyRoot root = new DummyRoot(suppressions);
root.setCoords(1, 10, 4, 5);
ctx.addViolationWithPosition(new FooRule(), root, 1, 1, "suppress test");
}
return listener.getReport();
}
}

View File

@ -4,7 +4,6 @@
package net.sourceforge.pmd.renderers;
import java.io.File;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@ -25,7 +24,6 @@ import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.Report.ConfigurationError;
import net.sourceforge.pmd.Report.ProcessingError;
import net.sourceforge.pmd.ReportTest;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.Node;
@ -87,9 +85,7 @@ public class XMLRendererTest extends AbstractRendererTest {
private RuleViolation createRuleViolation(String description) {
DummyNode node = new DummyNode();
node.setCoords(1, 1, 1, 1);
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File(getSourceCodeFilename()));
return new ParametricRuleViolation<Node>(new FooRule(), ctx, node, description);
return new ParametricRuleViolation<Node>(new FooRule(), getSourceCodeFilename(), node, description);
}
private void verifyXmlEscaping(Renderer renderer, String shouldContain, Charset charset) throws Exception {

View File

@ -10,7 +10,6 @@ import org.junit.Test;
import net.sourceforge.pmd.FooRule;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.ReportTest;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.Node;
@ -24,8 +23,7 @@ public class XSLTRendererTest {
Report report = new Report();
DummyNode node = new DummyNode();
node.setCoords(1, 1, 1, 2);
RuleViolation rv = new ParametricRuleViolation<Node>(new FooRule(), new RuleContext(), node,
"violation message");
RuleViolation rv = new ParametricRuleViolation<Node>(new FooRule(), "file", node, "violation message");
report.addRuleViolation(rv);
String result = ReportTest.render(renderer, report);
Assert.assertTrue(result.contains("violation message"));

View File

@ -25,7 +25,6 @@ import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.Report.ConfigurationError;
import net.sourceforge.pmd.Report.ProcessingError;
import net.sourceforge.pmd.ReportTest;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.Node;
@ -70,9 +69,7 @@ public class YAHTMLRendererTest extends AbstractRendererTest {
private RuleViolation newRuleViolation(int endColumn, final String packageNameArg, final String classNameArg) {
DummyNode node = createNode(endColumn);
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File(getSourceCodeFilename()));
return new ParametricRuleViolation<Node>(new FooRule(), ctx, node, "blah") {
return new ParametricRuleViolation<Node>(new FooRule(), getSourceCodeFilename(), node, "blah") {
{
packageName = packageNameArg;
className = classNameArg;

View File

@ -7,8 +7,9 @@ package net.sourceforge.pmd.lang.java.rule;
import java.util.Iterator;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.NonNull;
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.java.ast.ASTAnyTypeDeclaration;
@ -43,32 +44,24 @@ import net.sourceforge.pmd.lang.symboltable.Scope;
@Deprecated
public class JavaRuleViolation extends ParametricRuleViolation<JavaNode> {
public JavaRuleViolation(Rule rule, RuleContext ctx, JavaNode node, String message, int beginLine, int endLine) {
this(rule, ctx, node, message);
public JavaRuleViolation(Rule rule, @NonNull JavaNode node, String filename, String message) {
super(rule, filename, node, message);
setLines(beginLine, endLine);
}
final Scope scope = node.getScope();
final SourceFileScope sourceFileScope = scope.getEnclosingScope(SourceFileScope.class);
public JavaRuleViolation(Rule rule, RuleContext ctx, JavaNode node, String message) {
super(rule, ctx, node, message);
// Package name is on SourceFileScope
packageName = sourceFileScope.getPackageName() == null ? "" : sourceFileScope.getPackageName();
if (node != null) {
final Scope scope = node.getScope();
final SourceFileScope sourceFileScope = scope.getEnclosingScope(SourceFileScope.class);
// Class name is built from enclosing ClassScopes
setClassNameFrom(node);
// Package name is on SourceFileScope
packageName = sourceFileScope.getPackageName() == null ? "" : sourceFileScope.getPackageName();
// Class name is built from enclosing ClassScopes
setClassNameFrom(node);
// Method name comes from 1st enclosing MethodScope
if (scope.getEnclosingScope(MethodScope.class) != null) {
methodName = scope.getEnclosingScope(MethodScope.class).getName();
}
// Variable name node specific
setVariableNameIfExists(node);
// Method name comes from 1st enclosing MethodScope
if (scope.getEnclosingScope(MethodScope.class) != null) {
methodName = scope.getEnclosingScope(MethodScope.class).getName();
}
// Variable name node specific
setVariableNameIfExists(node);
}
/**

View File

@ -12,7 +12,6 @@ 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.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.ViolationSuppressor;
import net.sourceforge.pmd.lang.ast.Node;
@ -49,14 +48,8 @@ public final class JavaRuleViolationFactory extends DefaultRuleViolationFactory
}
@Override
protected RuleViolation createRuleViolation(Rule rule, RuleContext ruleContext, Node node, String message) {
return new JavaRuleViolation(rule, ruleContext, (JavaNode) node, message);
}
@Override
protected RuleViolation createRuleViolation(Rule rule, RuleContext ruleContext, Node node, String message,
int beginLine, int endLine) {
return new JavaRuleViolation(rule, ruleContext, (JavaNode) node, message, beginLine, endLine);
public RuleViolation createViolation(Rule rule, @NonNull Node location, String filename, String formattedMessage) {
return new JavaRuleViolation(rule, (JavaNode) location, filename, formattedMessage);
}
}

View File

@ -1,26 +0,0 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.rule;
import org.junit.Test;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.java.rule.codestyle.DuplicateImportsRule;
import net.sourceforge.pmd.lang.java.rule.internal.JavaRuleViolationFactory;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
/**
* @author guofei
*
*/
public class JavaRuleViolationFactoryTest {
@Test
public void messageWithSingleBrace() {
RuleViolationFactory factory = JavaRuleViolationFactory.INSTANCE;
factory.addViolation(new RuleContext(), new DuplicateImportsRule(), null, "message with \"'{'\"", null);
}
}

View File

@ -23,7 +23,7 @@ public class ReportTest extends RuleTst {
Rule rule = new AbstractEcmascriptRule() {
@Override
public Object visit(ASTFunctionNode node, Object data) {
EcmascriptLanguageModule.defaultHandler().getRuleViolationFactory().addViolation((RuleContext) data, this, node, "Test", null);
addViolationWithMessage(data, node, "Test");
return super.visit(node, data);
}
};

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