From 094ce26227e7f064dc7b462ce952b41f3bc8cf5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 29 Jul 2020 23:53:08 +0200 Subject: [PATCH] Make nodes have access to file name --- antlr4-wrapper.xml | 2 +- .../pmd/lang/apex/ast/ASTApexFile.java | 12 ++- .../pmd/lang/apex/ast/ApexParser.java | 2 +- .../main/java/net/sourceforge/pmd/PMD.java | 2 +- .../net/sourceforge/pmd/PMDConfiguration.java | 2 + .../main/java/net/sourceforge/pmd/Report.java | 18 ---- .../java/net/sourceforge/pmd/RuleContext.java | 94 +------------------ .../java/net/sourceforge/pmd/RuleSets.java | 14 +-- .../pmd/ant/internal/PMDTaskImpl.java | 6 +- .../java/net/sourceforge/pmd/lang/Parser.java | 19 ++-- .../net/sourceforge/pmd/lang/ast/Node.java | 11 +++ .../sourceforge/pmd/lang/ast/RootNode.java | 4 + .../lang/ast/impl/antlr4/AntlrBaseParser.java | 4 +- .../ast/impl/javacc/JjtreeParserAdapter.java | 5 +- .../lang/rule/internal/RuleApplicator.java | 5 +- .../pmd/processor/GlobalAnalysisListener.java | 49 ---------- .../pmd/processor/MonoThreadProcessor.java | 6 -- .../pmd/processor/PmdRunnable.java | 16 ++-- .../processor/ThreadSafeAnalysisListener.java | 24 +++-- .../sourceforge/pmd/renderers/Renderer.java | 61 ++++++++++++ .../net/sourceforge/pmd/AbstractRuleTest.java | 4 +- .../net/sourceforge/pmd/RuleContextTest.java | 23 ----- .../java/net/sourceforge/pmd/RuleSetTest.java | 37 +++----- .../net/sourceforge/pmd/ant/PMDTaskTest.java | 2 +- .../pmd/lang/DummyLanguageModule.java | 3 +- .../sourceforge/pmd/lang/ast/DummyRoot.java | 13 ++- .../processor/MultiThreadProcessorTest.java | 13 +-- .../renderers/SummaryHTMLRendererTest.java | 2 +- .../pmd/lang/java/ast/ASTCompilationUnit.java | 13 ++- .../pmd/lang/java/ast/JavaParser.java | 9 +- .../pmd/lang/ecmascript/ast/ASTAstRoot.java | 12 ++- .../lang/ecmascript/ast/EcmascriptParser.java | 2 +- .../pmd/lang/jsp/ast/ASTCompilationUnit.java | 13 ++- .../pmd/lang/jsp/ast/JspParser.java | 5 +- .../modelica/ast/ASTStoredDefinition.java | 13 ++- .../pmd/lang/modelica/ast/ModelicaParser.java | 5 +- .../pmd/lang/plsql/ast/ASTInput.java | 13 ++- .../pmd/lang/plsql/ast/PLSQLParser.java | 5 +- .../pmd/lang/scala/ast/ASTSource.java | 13 ++- .../pmd/lang/scala/ast/ScalaParser.java | 2 +- .../pmd/lang/swift/ast/PmdSwiftParser.java | 6 +- .../pmd/lang/swift/ast/SwiftRootNode.java | 43 +++++++++ .../pmd/test/lang/DummyLanguageModule.java | 5 + .../pmd/testframework/RuleTst.java | 8 +- .../pmd/lang/vf/ast/ASTCompilationUnit.java | 12 ++- .../sourceforge/pmd/lang/vf/ast/VfParser.java | 5 +- .../pmd/lang/vm/ast/ASTTemplate.java | 12 ++- .../sourceforge/pmd/lang/vm/ast/VmParser.java | 5 +- .../lang/xml/ast/internal/XmlParserImpl.java | 13 ++- 49 files changed, 352 insertions(+), 315 deletions(-) create mode 100644 pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftRootNode.java diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml index f6a221708b..3cf2e32366 100644 --- a/antlr4-wrapper.xml +++ b/antlr4-wrapper.xml @@ -39,7 +39,7 @@ + value="${root-node-name}Context extends ${lang-name}RootNode"/> diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java index d95cc39255..d69b3e5fbf 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java @@ -10,6 +10,7 @@ import java.util.Map; import org.checkerframework.checker.nullness.qual.NonNull; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.Parser.ParserTask; import net.sourceforge.pmd.lang.ast.RootNode; import net.sourceforge.pmd.lang.ast.SourceCodePositioner; @@ -19,13 +20,15 @@ import apex.jorje.semantic.ast.compilation.Compilation; public final class ASTApexFile extends AbstractApexNode implements RootNode { private final LanguageVersion languageVersion; + private final String file; private Map suppressMap = Collections.emptyMap(); ASTApexFile(SourceCodePositioner source, - LanguageVersion languageVersion, + ParserTask task, AbstractApexNode child) { super(child.getNode()); - this.languageVersion = languageVersion; + this.languageVersion = task.getLanguageVersion(); + this.file = task.getFileDisplayName(); addChild(child, 0); this.beginLine = 1; this.endLine = source.getLastLine(); @@ -39,6 +42,11 @@ public final class ASTApexFile extends AbstractApexNode implements Root return languageVersion; } + @Override + public String getSourceCodeFile() { + return file; + } + @Override public double getApexVersion() { return getNode().getDefiningType().getCodeUnitDetails().getVersion().getExternal(); diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java index 9ee158bc54..8a2df01527 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java @@ -35,7 +35,7 @@ public final class ApexParser implements Parser { SourceCodePositioner positioner = new SourceCodePositioner(sourceCode); final ApexTreeBuilder treeBuilder = new ApexTreeBuilder(sourceCode, task.getCommentMarker(), positioner); AbstractApexNode treeRoot = treeBuilder.build(astRoot); - ASTApexFile fileNode = new ASTApexFile(positioner, task.getLanguageVersion(), treeRoot); + ASTApexFile fileNode = new ASTApexFile(positioner, task, treeRoot); fileNode.setNoPmdComments(treeBuilder.getSuppressMap()); return fileNode; } catch (apex.jorje.services.exception.ParseException e) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java index a264a81ea0..47757a1693 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java @@ -187,7 +187,7 @@ public class PMD { ReportBuilderListener reportBuilder = new ReportBuilderListener(); - try (GlobalAnalysisListener listener = GlobalAnalysisListener.forReporter(renderer)) { + try (GlobalAnalysisListener listener = renderer.newListener()) { try (TimedOperation to = TimeTracker.startOperation(TimedOperationCategory.FILE_PROCESSING)) { encourageToUseIncrementalAnalysis(configuration); processFiles(configuration, ruleSetFactory, files, listener); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java index 694519e344..b0cc7e5f81 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -8,6 +8,7 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Properties; import net.sourceforge.pmd.cache.AnalysisCache; @@ -124,6 +125,7 @@ public class PMDConfiguration extends AbstractConfiguration { * The suppress marker to use. */ public void setSuppressMarker(String suppressMarker) { + Objects.requireNonNull(suppressMarker, "Suppress marker was null"); this.suppressMarker = suppressMarker; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/Report.java b/pmd-core/src/main/java/net/sourceforge/pmd/Report.java index 8d86391cd7..78de174149 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/Report.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/Report.java @@ -6,7 +6,6 @@ package net.sourceforge.pmd; import static java.util.Collections.synchronizedList; -import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; @@ -31,23 +30,6 @@ public class Report { private final List errors = synchronizedList(new ArrayList<>()); private final List configErrors = synchronizedList(new ArrayList<>()); - /** - * Creates a new, initialized, empty report for the given file name. - * - * @param ctx - * The context to use to connect to the report - * @param fileName - * the filename used to report any violations - * @return the new report - */ - public static Report createReport(RuleContext ctx, String fileName) { - Report report = new Report(); - - ctx.setReport(report); - ctx.setSourceCodeFile(new File(fileName)); - return report; - } - /** * Represents a configuration error. */ diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java index ab8cff7598..74933758b2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java @@ -4,10 +4,8 @@ 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; @@ -39,10 +37,6 @@ public class RuleContext implements AutoCloseable { private static final Object[] NO_ARGS = new Object[0]; - private static final Logger LOG = Logger.getLogger(RuleContext.class.getName()); - - private Report report = new Report(); - private File sourceCodeFile; private boolean ignoreExceptions = true; private final ThreadSafeAnalysisListener listener; @@ -52,18 +46,7 @@ public class RuleContext implements AutoCloseable { */ @Deprecated public RuleContext() { - listener = ThreadSafeAnalysisListener.noop(); - } - - /** - * Constructor which shares attributes and report listeners with the given - * RuleContext. - * - * @param ruleContext the context from which the values are shared - */ - public RuleContext(RuleContext ruleContext) { - this.listener = ruleContext.listener; - this.setIgnoreExceptions(ruleContext.ignoreExceptions); + this(ThreadSafeAnalysisListener.noop()); } public RuleContext(ThreadSafeAnalysisListener listener) { @@ -110,7 +93,7 @@ public class RuleContext implements AutoCloseable { // at some point each Node will know its language version RuleViolationFactory fact = location.getLanguageVersion().getLanguageVersionHandler().getRuleViolationFactory(); - RuleViolation violation = fact.createViolation(rule, location, getSourceCodeFilename(), makeMessage(message, formatArgs)); + RuleViolation violation = fact.createViolation(rule, location, location.getSourceCodeFile(), makeMessage(message, formatArgs)); if (beginLine != -1 && endLine != -1) { // fixme, this is needed until we have actual Location objects ((ParametricRuleViolation) violation).setLines(beginLine, endLine); @@ -133,79 +116,6 @@ public class RuleContext implements AutoCloseable { } - /** - * Get the Report to which Rule Violations are sent. - * - * @return The Report. - */ - public Report getReport() { - return report; - } - - /** - * Set the Report to which Rule Violations are sent. - * - * @param report - * The Report. - */ - public void setReport(Report report) { - this.report = report; - } - - /** - * Get the File associated with the current source file. - * - * @return The File. - */ - public File getSourceCodeFile() { - return sourceCodeFile; - } - - /** - * Set the File associated with the current source file. While this may be - * set to null, the exclude/include facilities will not work - * properly without a File. - * - * @param sourceCodeFile - * The File. - */ - public void setSourceCodeFile(File sourceCodeFile) { - this.sourceCodeFile = sourceCodeFile; - } - - /** - * Get the file name associated with the current source file. - * If there is no source file, then an empty string is returned. - * - * @return The file name. - * - * @deprecated Will be replaced by the document API. Nodes will - * have access to their document. - */ - @Deprecated - public String getSourceCodeFilename() { - if (sourceCodeFile != null) { - return sourceCodeFile.getName(); - } - return ""; - } - - /** - * Set the file name associated with the current source file. - * - * @param filename - * The file name. - * @deprecated This method will be removed. The file should only be - * set with {@link #setSourceCodeFile(File)}. Setting the filename here - * has no effect. - */ - @Deprecated - public void setSourceCodeFilename(String filename) { - // ignored, does nothing. - LOG.warning("The method RuleContext::setSourceCodeFilename(String) has been deprecated and will be removed." - + "Setting the filename here has no effect. Use RuleContext::setSourceCodeFile(File) instead."); - } - /** * Configure whether exceptions during applying a rule should be ignored or * not. If set to true then such exceptions are logged as diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSets.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSets.java index f27776f7d8..a8bd319714 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSets.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSets.java @@ -136,13 +136,15 @@ public class RuleSets { this.ruleApplicator = prepareApplicator(); } - try (TimedOperation to = TimeTracker.startOperation(TimedOperationCategory.RULE_AST_INDEXATION)) { - ruleApplicator.index(acuList); - } + for (Node node : acuList) { + try (TimedOperation to = TimeTracker.startOperation(TimedOperationCategory.RULE_AST_INDEXATION)) { + ruleApplicator.index(Collections.singletonList(node)); + } - for (RuleSet ruleSet : ruleSets) { - if (ruleSet.applies(ctx.getSourceCodeFile())) { - ruleApplicator.apply(ruleSet.getRules(), ctx); + for (RuleSet ruleSet : ruleSets) { + if (ruleSet.applies(new File(node.getSourceCodeFile()))) { + ruleApplicator.apply(ruleSet.getRules(), ctx); + } } } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java index 7b9c157885..56fc639fff 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java @@ -65,7 +65,9 @@ public class PMDTaskImpl { public PMDTaskImpl(PMDTask task) { configuration.setReportShortNames(task.isShortFilenames()); - configuration.setSuppressMarker(task.getSuppressMarker()); + if (task.getSuppressMarker() != null) { + configuration.setSuppressMarker(task.getSuppressMarker()); + } this.failOnError = task.isFailOnError(); this.failOnRuleViolation = task.isFailOnRuleViolation(); this.maxRuleViolations = task.getMaxRuleViolations(); @@ -166,7 +168,7 @@ public class PMDTaskImpl { renderers.add(renderer); } - GlobalAnalysisListener listener = GlobalAnalysisListener.tee(renderers.stream().map(GlobalAnalysisListener::forReporter).collect(Collectors.toList())); + GlobalAnalysisListener listener = GlobalAnalysisListener.tee(renderers.stream().map(Renderer::newListener).collect(Collectors.toList())); try { PMD.processFiles(configuration, ruleSetFactory, files, listener); } catch (RuntimeException pmde) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Parser.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Parser.java index f1b964bc4f..d66fb3b9ca 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Parser.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Parser.java @@ -4,6 +4,10 @@ package net.sourceforge.pmd.lang; +import java.util.Objects; + +import org.checkerframework.checker.nullness.qual.NonNull; + import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.lang.ast.FileAnalysisException; import net.sourceforge.pmd.lang.ast.RootNode; @@ -56,11 +60,11 @@ public interface Parser { } public ParserTask(LanguageVersion lv, String filepath, String sourceText, SemanticErrorReporter reporter, String commentMarker) { - this.lv = lv; - this.filepath = filepath; - this.sourceText = sourceText; - this.reporter = reporter; - this.commentMarker = commentMarker; + this.lv = Objects.requireNonNull(lv, "lv was null"); + this.filepath = Objects.requireNonNull(filepath, "filepath was null"); + this.sourceText = Objects.requireNonNull(sourceText, "sourceText was null"); + this.reporter = Objects.requireNonNull(reporter, "reporter was null"); + this.commentMarker = Objects.requireNonNull(commentMarker, "commentMarker was null"); } @@ -90,7 +94,10 @@ public interface Parser { return reporter; } - public String getCommentMarker() { + /** + * The suppression marker for comments. + */ + public @NonNull String getCommentMarker() { return commentMarker; } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java index 30bc73e5cd..1923bd6277 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java @@ -17,6 +17,7 @@ import net.sourceforge.pmd.lang.ast.NodeStream.DescendantNodeStream; import net.sourceforge.pmd.lang.ast.internal.StreamImpl; import net.sourceforge.pmd.lang.rule.xpath.Attribute; import net.sourceforge.pmd.lang.rule.xpath.DeprecatedAttribute; +import net.sourceforge.pmd.lang.rule.xpath.NoAttribute; import net.sourceforge.pmd.lang.rule.xpath.XPathVersion; import net.sourceforge.pmd.lang.rule.xpath.impl.AttributeAxisIterator; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathHandler; @@ -304,6 +305,16 @@ public interface Node { } + /** + * @deprecated This is simply a placeholder until we have TextDocuments + */ + @Deprecated + @NoAttribute + default String getSourceCodeFile() { + return getRoot().getSourceCodeFile(); + } + + /** * Gets the name of the node that is used to match it with XPath queries. * diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java index a56efa49bd..786c97d72a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java @@ -41,4 +41,8 @@ public interface RootNode extends Node { @Override LanguageVersion getLanguageVersion(); + + + @Override + String getSourceCodeFile(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java index 25e30602f3..e616fd1163 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java @@ -34,10 +34,10 @@ public abstract class AntlrBaseParser< @Override public R parse(ParserTask task) throws ParseException { CharStream cs = CharStreams.fromString(task.getSourceText(), task.getFileDisplayName()); - return parse(getLexer(cs)); + return parse(getLexer(cs), task); } - protected abstract R parse(Lexer parser); + protected abstract R parse(Lexer parser, ParserTask task); protected abstract Lexer getLexer(CharStream source); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java index 81ac66b6da..b5d6b0e0ae 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.ast.impl.javacc; -import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.Parser; import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.ParseException; @@ -35,13 +34,13 @@ public abstract class JjtreeParserAdapter implements Parser CharStream charStream = newCharStream(doc); try { - return parseImpl(charStream, task.getCommentMarker(), task.getLanguageVersion()); + return parseImpl(charStream, task); } catch (TokenMgrError tme) { throw tme.setFileName(task.getFileDisplayName()); } } - protected abstract R parseImpl(CharStream cs, String suppressMarker, LanguageVersion languageVersion) throws ParseException; + protected abstract R parseImpl(CharStream cs, ParserTask task) throws ParseException; @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleApplicator.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleApplicator.java index 67da779d6f..3f4a8e1bad 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleApplicator.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleApplicator.java @@ -62,11 +62,12 @@ public class RuleApplicator { rcto.close(1); } catch (RuntimeException e) { if (ctx.isIgnoreExceptions()) { - ctx.reportError(new ProcessingError(e, ctx.getSourceCodeFilename())); + String filename = node.getSourceCodeFile(); + ctx.reportError(new ProcessingError(e, filename)); if (LOG.isLoggable(Level.WARNING)) { LOG.log(Level.WARNING, "Exception applying rule " + rule.getName() + " on file " - + ctx.getSourceCodeFilename() + ", continuing with next rule", e); + + filename + ", continuing with next rule", e); } } else { throw e; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/processor/GlobalAnalysisListener.java b/pmd-core/src/main/java/net/sourceforge/pmd/processor/GlobalAnalysisListener.java index 2acd3f1779..f03b76ec36 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/processor/GlobalAnalysisListener.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/processor/GlobalAnalysisListener.java @@ -12,14 +12,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import net.sourceforge.pmd.Report.ProcessingError; -import net.sourceforge.pmd.Report.ReportBuilderListener; -import net.sourceforge.pmd.Report.SuppressedViolation; -import net.sourceforge.pmd.RuleViolation; -import net.sourceforge.pmd.benchmark.TimeTracker; -import net.sourceforge.pmd.benchmark.TimedOperation; -import net.sourceforge.pmd.benchmark.TimedOperationCategory; -import net.sourceforge.pmd.renderers.Renderer; import net.sourceforge.pmd.util.CollectionUtil; import net.sourceforge.pmd.util.datasource.DataSource; @@ -61,45 +53,4 @@ public interface GlobalAnalysisListener extends AutoCloseable { } - static GlobalAnalysisListener forReporter(Renderer renderer) { - - return new GlobalAnalysisListener() { - @Override - public ThreadSafeAnalysisListener startFileAnalysis(DataSource file) { - renderer.startFileAnalysis(file); - return new ThreadSafeAnalysisListener() { - final ReportBuilderListener reportBuilder = new ReportBuilderListener(); - - @Override - public void onRuleViolation(RuleViolation violation) { - reportBuilder.onRuleViolation(violation); - } - - @Override - public void onSuppressedRuleViolation(SuppressedViolation violation) { - reportBuilder.onSuppressedRuleViolation(violation); - } - - @Override - public void onError(ProcessingError error) { - reportBuilder.onError(error); - } - - @Override - public void close() throws Exception { - reportBuilder.close(); - renderer.renderFileReport(reportBuilder.getReport()); - } - }; - } - - @Override - public void close() throws Exception { - try (TimedOperation to = TimeTracker.startOperation(TimedOperationCategory.REPORTING)) { - renderer.end(); - renderer.flush(); - } - } - }; - } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/processor/MonoThreadProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/processor/MonoThreadProcessor.java index 572c7307ed..0b55b37a41 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/processor/MonoThreadProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/processor/MonoThreadProcessor.java @@ -4,11 +4,7 @@ package net.sourceforge.pmd.processor; -import java.util.ArrayList; -import java.util.List; - import net.sourceforge.pmd.PMDConfiguration; -import net.sourceforge.pmd.Report; /** * @author Romain Pelisse <belaran@gmail.com> @@ -16,8 +12,6 @@ import net.sourceforge.pmd.Report; */ final class MonoThreadProcessor extends AbstractPMDProcessor { - private final List reports = new ArrayList<>(); - public MonoThreadProcessor(PMDConfiguration configuration) { super(configuration); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/processor/PmdRunnable.java b/pmd-core/src/main/java/net/sourceforge/pmd/processor/PmdRunnable.java index c3251c0c5c..97e06f25d7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/processor/PmdRunnable.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/processor/PmdRunnable.java @@ -84,9 +84,9 @@ public class PmdRunnable implements Runnable { tc = new ThreadContext(ruleSetMaker.get()); LOCAL_THREAD_CONTEXT.set(tc); } + try (RuleContext ruleCtx = new RuleContext(ruleContext.startFileAnalysis(dataSource))) { LanguageVersion langVersion = configuration.getLanguageVersionOfFile(file.getPath()); - ruleCtx.setSourceCodeFile(file); if (LOG.isLoggable(Level.FINE)) { LOG.fine("Processing " + file); @@ -95,7 +95,7 @@ public class PmdRunnable implements Runnable { // Coarse check to see if any RuleSet applies to file, will need to do a finer RuleSet specific check later if (tc.ruleSets.applies(file)) { if (configuration.getAnalysisCache().isUpToDate(file)) { - reportCachedRuleViolations(ruleCtx); + reportCachedRuleViolations(ruleCtx, file); } else { try { processSource(ruleCtx, langVersion, tc.ruleSets); @@ -126,10 +126,11 @@ public class PmdRunnable implements Runnable { try (InputStream stream = dataSource.getInputStream()) { fullSource = IOUtils.toString(stream, configuration.getSourceEncoding()); } + String filename = dataSource.getNiceFileName(false, null); try { ruleSets.start(ruleCtx); - processSource(fullSource, ruleSets, ruleCtx, languageVersion); + processSource(fullSource, ruleSets, ruleCtx, languageVersion, filename); } finally { ruleSets.end(ruleCtx); } @@ -137,8 +138,8 @@ public class PmdRunnable implements Runnable { } - private void reportCachedRuleViolations(final RuleContext ctx) { - for (final RuleViolation rv : configuration.getAnalysisCache().getCachedViolations(ctx.getSourceCodeFile())) { + private void reportCachedRuleViolations(final RuleContext ctx, File file) { + for (final RuleViolation rv : configuration.getAnalysisCache().getCachedViolations(file)) { ctx.addViolationNoSuppress(rv); } } @@ -153,11 +154,12 @@ public class PmdRunnable implements Runnable { private void processSource(String sourceCode, RuleSets ruleSets, RuleContext ctx, - LanguageVersion languageVersion) throws FileAnalysisException, IOException { + LanguageVersion languageVersion, + String filename) throws FileAnalysisException, IOException { ParserTask task = new ParserTask( languageVersion, - String.valueOf(ctx.getSourceCodeFile()), + filename, sourceCode, SemanticErrorReporter.noop(), configuration.getSuppressMarker() diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/processor/ThreadSafeAnalysisListener.java b/pmd-core/src/main/java/net/sourceforge/pmd/processor/ThreadSafeAnalysisListener.java index 6c438809a2..8163a28188 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/processor/ThreadSafeAnalysisListener.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/processor/ThreadSafeAnalysisListener.java @@ -26,16 +26,14 @@ public interface ThreadSafeAnalysisListener extends AutoCloseable { /** * Handle a new violation (not suppressed). */ - default void onRuleViolation(RuleViolation violation) { - - } + void onRuleViolation(RuleViolation violation); /** * Handle a new suppressed violation. */ default void onSuppressedRuleViolation(SuppressedViolation violation) { - + // by default do nothing } @@ -43,21 +41,33 @@ public interface ThreadSafeAnalysisListener extends AutoCloseable { * Handle an error that occurred while processing a file. */ default void onError(ProcessingError error) { - + // by default do nothing } @Override default void close() throws Exception { - + // by default do nothing } + /** + * A listener that does nothing. + */ static ThreadSafeAnalysisListener noop() { - return new ThreadSafeAnalysisListener() {}; + return violation -> { /* do nothing*/}; } + /** + * Produce an analysis listener that forwards all events to the given + * listeners. + * + * @param listeners Listeners + * + * @return A new listener + */ + @SuppressWarnings("PMD.CloseResource") static ThreadSafeAnalysisListener tee(Collection listeners) { List list = Collections.unmodifiableList(new ArrayList<>(listeners)); return new ThreadSafeAnalysisListener() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/Renderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/Renderer.java index 3a2d8f8601..a377c693bb 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/Renderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/Renderer.java @@ -9,7 +9,16 @@ import java.io.Writer; import java.util.List; import net.sourceforge.pmd.Report; +import net.sourceforge.pmd.Report.ProcessingError; +import net.sourceforge.pmd.Report.ReportBuilderListener; +import net.sourceforge.pmd.Report.SuppressedViolation; +import net.sourceforge.pmd.RuleViolation; import net.sourceforge.pmd.annotation.Experimental; +import net.sourceforge.pmd.benchmark.TimeTracker; +import net.sourceforge.pmd.benchmark.TimedOperation; +import net.sourceforge.pmd.benchmark.TimedOperationCategory; +import net.sourceforge.pmd.processor.GlobalAnalysisListener; +import net.sourceforge.pmd.processor.ThreadSafeAnalysisListener; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertySource; import net.sourceforge.pmd.util.datasource.DataSource; @@ -177,4 +186,56 @@ public interface Renderer extends PropertySource { */ @Experimental void setReportFile(String reportFilename); + + + + /** + * Returns a new analysis listener, that handles violations by rendering + * them in an implementation-defined way. + */ + // TODO the default implementation matches the current behavior, + // ie violations are batched by file and forwarded to the renderer + // when the file is done. Many renderers could directly handle + // violations as they come though. + default GlobalAnalysisListener newListener() { + + return new GlobalAnalysisListener() { + @Override + public ThreadSafeAnalysisListener startFileAnalysis(DataSource file) { + Renderer.this.startFileAnalysis(file); + return new ThreadSafeAnalysisListener() { + final ReportBuilderListener reportBuilder = new ReportBuilderListener(); + + @Override + public void onRuleViolation(RuleViolation violation) { + reportBuilder.onRuleViolation(violation); + } + + @Override + public void onSuppressedRuleViolation(SuppressedViolation violation) { + reportBuilder.onSuppressedRuleViolation(violation); + } + + @Override + public void onError(ProcessingError error) { + reportBuilder.onError(error); + } + + @Override + public void close() throws Exception { + reportBuilder.close(); + renderFileReport(reportBuilder.getReport()); + } + }; + } + + @Override + public void close() throws Exception { + try (TimedOperation to = TimeTracker.startOperation(TimedOperationCategory.REPORTING)) { + end(); + flush(); + } + } + }; + } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java index bc0d632b54..4b5fc4ff33 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java @@ -9,7 +9,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import java.io.File; import java.util.Collections; import java.util.Map; @@ -102,8 +101,7 @@ public class AbstractRuleTest { r.setMessage("Message ${packageName} ${className} ${methodName} ${variableName} ${testInt} ${noSuchProperty}"); ReportBuilderListener listener = new ReportBuilderListener(); try (RuleContext ctx = new RuleContext(listener)) { - ctx.setSourceCodeFile(new File("filename")); - DummyNode s = new DummyRoot(); + DummyNode s = new DummyRoot().withFileName("filename"); s.setCoords(5, 1, 6, 1); s.setImage("TestImage"); r.addViolation(ctx, s); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleContextTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleContextTest.java index a4cdf96ce8..0229ccaf80 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleContextTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleContextTest.java @@ -4,11 +4,6 @@ package net.sourceforge.pmd; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import java.io.File; - import org.junit.Assert; import org.junit.Test; @@ -19,15 +14,6 @@ import junit.framework.JUnit4TestAdapter; public class RuleContextTest { - @Test - public void testSourceCodeFilename() { - RuleContext ctx = new RuleContext(); - assertEquals("filename should be empty", "", ctx.getSourceCodeFilename()); - ctx.setSourceCodeFile(new File("dir/foo.java")); - assertEquals("filename mismatch", "foo.java", ctx.getSourceCodeFilename()); - } - - @Test public void testMessage() throws Exception { ReportBuilderListener listener = new ReportBuilderListener(); @@ -50,15 +36,6 @@ public class RuleContextTest { Assert.assertEquals("message with 1 argument: \"testarg1\"", violation.getDescription()); } - @Test - public void testSourceCodeFile() { - RuleContext ctx = new RuleContext(); - assertNull("file should be null", ctx.getSourceCodeFile()); - ctx.setSourceCodeFile(new File("somefile.java")); - assertEquals("filename mismatch", new File("somefile.java"), ctx.getSourceCodeFile()); - } - - public static junit.framework.Test suite() { return new JUnit4TestAdapter(RuleContextTest.class); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java index 724ccbfca9..3c6b70ff8e 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java @@ -17,6 +17,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -34,11 +35,11 @@ import net.sourceforge.pmd.lang.Dummy2LanguageModule; import net.sourceforge.pmd.lang.DummyLanguageModule; import net.sourceforge.pmd.lang.Language; 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.RuleReference; import net.sourceforge.pmd.lang.rule.RuleTargetSelector; +import net.sourceforge.pmd.processor.ThreadSafeAnalysisListener; public class RuleSetTest { @@ -401,24 +402,18 @@ public class RuleSetTest { @Test public void testIncludeExcludeMultipleRuleSetWithRuleChainApplies() throws Exception { - File file = new File("C:\\myworkspace\\project\\some\\random\\package\\RandomClass.java"); - Rule rule = new FooRule(); rule.setName("FooRule1"); - RuleSet ruleSet1 = createRuleSetBuilder("RuleSet1") - .addRule(rule) - .build(); + rule.setLanguage(LanguageRegistry.getLanguage(DummyLanguageModule.NAME)); - RuleSet ruleSet2 = createRuleSetBuilder("RuleSet2") - .addRule(rule) - .build(); + RuleSet ruleSet1 = createRuleSetBuilder("RuleSet1").addRule(rule).build(); + RuleSet ruleSet2 = createRuleSetBuilder("RuleSet2").addRule(rule).build(); RuleSets ruleSets = new RuleSets(listOf(ruleSet1, ruleSet2)); // Two violations ReportBuilderListener reportBuilder = new ReportBuilderListener(); try (RuleContext ctx = new RuleContext(reportBuilder)) { - ctx.setSourceCodeFile(file); ruleSets.apply(makeCompilationUnits(), ctx); } assertEquals("Violations", 2, reportBuilder.getReport().getViolations().size()); @@ -432,10 +427,8 @@ public class RuleSetTest { ruleSets = new RuleSets(listOf(ruleSet1, ruleSet2)); reportBuilder = new ReportBuilderListener(); - try (RuleContext ctx = new RuleContext(reportBuilder)) { - ctx.setSourceCodeFile(file); - ruleSets.apply(makeCompilationUnits(), ctx); + ruleSets.apply(makeCompilationUnits("C:\\myworkspace\\project\\some\\random\\package\\RandomClass.java"), ctx); } assertEquals("Violations", 1, reportBuilder.getReport().getViolations().size()); } @@ -478,12 +471,15 @@ public class RuleSetTest { } private List makeCompilationUnits() { - List nodes = new ArrayList<>(); - DummyNode node = new DummyRoot(); + return makeCompilationUnits("sampleFile.dummy"); + } + + private List makeCompilationUnits(String filename) { + DummyRoot node = new DummyRoot(); node.setCoords(1, 1, 10, 1); node.setImage("Foo"); - nodes.add(node); - return nodes; + node.withFileName(filename); + return Collections.singletonList(node); } @Test @@ -498,7 +494,6 @@ public class RuleSetTest { .build(); ReportBuilderListener reportBuilder = new ReportBuilderListener(); try (RuleContext context = new RuleContext(reportBuilder)) { - context.setSourceCodeFile(new File("foo.dummy")); context.setIgnoreExceptions(true); // the default ruleset.apply(makeCompilationUnits(), context); } @@ -520,9 +515,7 @@ public class RuleSetTest { } }) .build(); - RuleContext context = new RuleContext(); - context.setReport(new Report()); - context.setSourceCodeFile(new File(RuleSetTest.class.getName() + ".ruleExceptionShouldBeThrownIfNotIgnored")); + RuleContext context = new RuleContext(ThreadSafeAnalysisListener.noop()); context.setIgnoreExceptions(false); ruleset.apply(makeCompilationUnits(), context); } @@ -542,7 +535,6 @@ public class RuleSetTest { }).build(); ReportBuilderListener reportBuilder = new ReportBuilderListener(); try (RuleContext context = new RuleContext(reportBuilder)) { - context.setSourceCodeFile(new File("foo.dummy")); context.setIgnoreExceptions(true); // the default ruleset.apply(makeCompilationUnits(), context); } @@ -584,7 +576,6 @@ public class RuleSetTest { ReportBuilderListener reportBuilder = new ReportBuilderListener(); try (RuleContext context = new RuleContext(reportBuilder)) { - context.setSourceCodeFile(new File("foo.dummy")); context.setIgnoreExceptions(true); // the default rulesets.apply(makeCompilationUnits(), context); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java index 396bda7876..d227a14d84 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java @@ -78,7 +78,7 @@ public class PMDTaskTest { String actual = IOUtils.toString(in, StandardCharsets.UTF_8); // remove any trailing newline actual = actual.replaceAll("\n|\r", ""); - Assert.assertEquals("sample.dummy:0:\tTest Rule 2", actual); + Assert.assertEquals("sample.dummy:1:\tTest Rule 2", actual); } } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java index 3090e4f3b4..d6dc0474e8 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java @@ -50,9 +50,10 @@ public class DummyLanguageModule extends BaseLanguageModule { @Override public Parser getParser(ParserOptions parserOptions) { return task -> { - DummyRoot node = new DummyRoot(); + DummyRoot node = new DummyRoot(task.getLanguageVersion()); node.setCoords(1, 1, 2, 10); node.setImage("Foo"); + node.withFileName(task.getFileDisplayName()); return node; }; } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyRoot.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyRoot.java index 6d477640d4..ac86e23fde 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyRoot.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyRoot.java @@ -16,6 +16,7 @@ public class DummyRoot extends DummyNode implements GenericNode, Root private final Map suppressMap; private LanguageVersion languageVersion; + private String filename = "sample.dummy"; public DummyRoot(Map suppressMap, LanguageVersion languageVersion) { super(); @@ -41,11 +42,21 @@ public class DummyRoot extends DummyNode implements GenericNode, Root return languageVersion; } - public DummyRoot setLanguageVersion(LanguageVersion languageVersion) { + @Override + public String getSourceCodeFile() { + return filename; + } + + public DummyRoot withLanguage(LanguageVersion languageVersion) { this.languageVersion = languageVersion; return this; } + public DummyRoot withFileName(String filename) { + this.filename = filename; + return this; + } + @Override public Map getNoPmdComments() { return suppressMap; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/processor/MultiThreadProcessorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/processor/MultiThreadProcessorTest.java index 0b8c43a292..92c66dc789 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/processor/MultiThreadProcessorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/processor/MultiThreadProcessorTest.java @@ -6,10 +6,6 @@ package net.sourceforge.pmd.processor; import static net.sourceforge.pmd.util.CollectionUtil.listOf; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -38,9 +34,10 @@ public class MultiThreadProcessorTest { public RuleSets setUpForTest(final String ruleset) throws RuleSetNotFoundException { configuration = new PMDConfiguration(); configuration.setThreads(2); - files = new ArrayList<>(); - files.add(DataSource.forString("abc", "file1-violation.dummy")); - files.add(DataSource.forString("DEF", "file2-foo.dummy")); + files = listOf( + DataSource.forString("abc", "file1-violation.dummy"), + DataSource.forString("DEF", "file2-foo.dummy") + ); reportListener = new SimpleReportListener(); listener = GlobalAnalysisListener.tee(listOf( @@ -96,7 +93,7 @@ public class MultiThreadProcessorTest { public void apply(Node target, RuleContext ctx) { count.incrementAndGet(); - if (ctx.getSourceCodeFilename().contains("violation")) { + if (target.getSourceCodeFile().contains("violation")) { hasViolation = true; } else { letTheOtherThreadRun(10); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java index 11c28463f6..4258a2e38e 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java @@ -150,7 +150,7 @@ public class SummaryHTMLRendererTest extends AbstractRendererTest { Map suppressions = Collections.singletonMap(1, "test"); ReportBuilderListener listener = new ReportBuilderListener(); try (RuleContext ctx = new RuleContext(listener)) { - DummyRoot root = new DummyRoot(suppressions); + DummyRoot root = new DummyRoot(suppressions).withFileName(""); root.setCoords(1, 10, 4, 5); ctx.addViolationWithPosition(new FooRule(), root, 1, 1, "suppress test"); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java index f16cc0f410..0d8ec021c4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java @@ -12,6 +12,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.Parser.ParserTask; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.RootNode; import net.sourceforge.pmd.lang.ast.impl.GenericNode; @@ -24,6 +25,7 @@ public class ASTCompilationUnit extends AbstractJavaTypeNode implements JavaNode private List comments; private Map noPmdComments = Collections.emptyMap(); private LanguageVersion languageVersion; + private String filename; @InternalApi @Deprecated @@ -41,8 +43,15 @@ public class ASTCompilationUnit extends AbstractJavaTypeNode implements JavaNode return languageVersion; } - void setLanguageVersion(LanguageVersion languageVersion) { - this.languageVersion = languageVersion; + + @Override + public String getSourceCodeFile() { + return filename; + } + + void addTaskInfo(ParserTask languageVersion) { + this.languageVersion = languageVersion.getLanguageVersion(); + this.filename = languageVersion.getFileDisplayName(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParser.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParser.java index 3c39d2d6a6..8d202c31af 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParser.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParser.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.java.ast; -import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaCharStream; @@ -38,17 +37,15 @@ public class JavaParser extends JjtreeParserAdapter { } @Override - protected ASTCompilationUnit parseImpl(CharStream cs, String suppressMarker, LanguageVersion languageVersion) throws ParseException { + protected ASTCompilationUnit parseImpl(CharStream cs, ParserTask task) throws ParseException { JavaParserImpl parser = new JavaParserImpl(cs); - if (suppressMarker != null) { - parser.setSuppressMarker(suppressMarker); - } + parser.setSuppressMarker(task.getCommentMarker()); parser.setJdkVersion(checker.getJdkVersion()); parser.setPreview(checker.isPreviewEnabled()); ASTCompilationUnit acu = parser.CompilationUnit(); acu.setNoPmdComments(parser.getSuppressMap()); - acu.setLanguageVersion(languageVersion); + acu.addTaskInfo(task); checker.check(acu); return acu; } diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTAstRoot.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTAstRoot.java index f8c6194af5..3637c894ae 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTAstRoot.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTAstRoot.java @@ -10,12 +10,14 @@ import java.util.Map; import org.mozilla.javascript.ast.AstRoot; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.Parser.ParserTask; import net.sourceforge.pmd.lang.ast.RootNode; public final class ASTAstRoot extends AbstractEcmascriptNode implements RootNode { private Map noPmdComments = Collections.emptyMap(); private LanguageVersion languageVersion; + private String filename; public ASTAstRoot(AstRoot astRoot) { super(astRoot); @@ -26,8 +28,14 @@ public final class ASTAstRoot extends AbstractEcmascriptNode implements return languageVersion; } - void setLanguageVersion(LanguageVersion languageVersion) { - this.languageVersion = languageVersion; + @Override + public String getSourceCodeFile() { + return filename; + } + + void addTaskInfo(ParserTask languageVersion) { + this.languageVersion = languageVersion.getLanguageVersion(); + this.filename = languageVersion.getFileDisplayName(); } @Override diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParser.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParser.java index 11e458c81b..9418431d60 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParser.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParser.java @@ -56,7 +56,7 @@ public class EcmascriptParser { final AstRoot astRoot = parseEcmascript(sourceCode, parseProblems); final EcmascriptTreeBuilder treeBuilder = new EcmascriptTreeBuilder(sourceCode, parseProblems); ASTAstRoot tree = (ASTAstRoot) treeBuilder.build(astRoot); - tree.setLanguageVersion(task.getLanguageVersion()); + tree.addTaskInfo(task); String suppressMarker = task.getCommentMarker(); Map suppressMap = new HashMap<>(); diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/ASTCompilationUnit.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/ASTCompilationUnit.java index b504899846..ad65090897 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/ASTCompilationUnit.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/ASTCompilationUnit.java @@ -5,11 +5,13 @@ package net.sourceforge.pmd.lang.jsp.ast; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.Parser.ParserTask; import net.sourceforge.pmd.lang.ast.RootNode; public final class ASTCompilationUnit extends AbstractJspNode implements RootNode { private LanguageVersion languageVersion; + private String filename; ASTCompilationUnit(int id) { super(id); @@ -20,8 +22,15 @@ public final class ASTCompilationUnit extends AbstractJspNode implements RootNod return languageVersion; } - ASTCompilationUnit setLanguageVersion(LanguageVersion languageVersion) { - this.languageVersion = languageVersion; + + @Override + public String getSourceCodeFile() { + return filename; + } + + ASTCompilationUnit addTaskInfo(ParserTask languageVersion) { + this.languageVersion = languageVersion.getLanguageVersion(); + this.filename = languageVersion.getFileDisplayName(); return this; } diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/JspParser.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/JspParser.java index bef51acd48..0ce7dbefa9 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/JspParser.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/JspParser.java @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.jsp.ast; import org.checkerframework.checker.nullness.qual.Nullable; -import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccTokenDocument; @@ -28,8 +27,8 @@ public final class JspParser extends JjtreeParserAdapter { } @Override - protected ASTCompilationUnit parseImpl(CharStream cs, String suppressMarker, LanguageVersion languageVersion) throws ParseException { - return new JspParserImpl(cs).CompilationUnit().setLanguageVersion(languageVersion); + protected ASTCompilationUnit parseImpl(CharStream cs, ParserTask task) throws ParseException { + return new JspParserImpl(cs).CompilationUnit().addTaskInfo(task); } } diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTStoredDefinition.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTStoredDefinition.java index 6220b055a0..f83db2959f 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTStoredDefinition.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTStoredDefinition.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.modelica.ast; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.Parser.ParserTask; import net.sourceforge.pmd.lang.ast.RootNode; import net.sourceforge.pmd.lang.modelica.resolver.CompositeName; @@ -14,6 +15,7 @@ import net.sourceforge.pmd.lang.modelica.resolver.CompositeName; public class ASTStoredDefinition extends AbstractModelicaNode implements RootNode { private boolean hasBOM = false; private LanguageVersion languageVersion; + private String filename; ASTStoredDefinition(int id) { super(id); @@ -33,11 +35,18 @@ public class ASTStoredDefinition extends AbstractModelicaNode implements RootNod return languageVersion; } - ASTStoredDefinition setLanguageVersion(LanguageVersion languageVersion) { - this.languageVersion = languageVersion; + @Override + public String getSourceCodeFile() { + return filename; + } + + ASTStoredDefinition addTaskInfo(ParserTask languageVersion) { + this.languageVersion = languageVersion.getLanguageVersion(); + this.filename = languageVersion.getFileDisplayName(); return this; } + /** * Returns whether this source file contains Byte Order Mark. */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaParser.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaParser.java index aef19b525d..c1c29a8f2a 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaParser.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaParser.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.modelica.ast; -import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccTokenDocument; @@ -19,8 +18,8 @@ public class ModelicaParser extends JjtreeParserAdapter { } @Override - protected ASTStoredDefinition parseImpl(CharStream cs, String suppressMarker, LanguageVersion languageVersion) throws ParseException { - return new ModelicaParserImpl(cs).StoredDefinition().setLanguageVersion(languageVersion); + protected ASTStoredDefinition parseImpl(CharStream cs, ParserTask task) throws ParseException { + return new ModelicaParserImpl(cs).StoredDefinition().addTaskInfo(task); } } diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/ASTInput.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/ASTInput.java index c900c57c00..81936c0cf0 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/ASTInput.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/ASTInput.java @@ -5,11 +5,13 @@ package net.sourceforge.pmd.lang.plsql.ast; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.Parser.ParserTask; import net.sourceforge.pmd.lang.ast.RootNode; public final class ASTInput extends AbstractPLSQLNode implements RootNode { private LanguageVersion languageVersion; + private String filename; ASTInput(int id) { super(id); @@ -20,11 +22,18 @@ public final class ASTInput extends AbstractPLSQLNode implements RootNode { return languageVersion; } - ASTInput setLanguageVersion(LanguageVersion languageVersion) { - this.languageVersion = languageVersion; + @Override + public String getSourceCodeFile() { + return filename; + } + + ASTInput addTaskInfo(ParserTask languageVersion) { + this.languageVersion = languageVersion.getLanguageVersion(); + this.filename = languageVersion.getFileDisplayName(); return this; } + @Override public Object jjtAccept(PLSQLParserVisitor visitor, Object data) { return visitor.visit(this, data); diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParser.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParser.java index e3be5d4ab6..c15ab94e8d 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParser.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParser.java @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.plsql.ast; import org.checkerframework.checker.nullness.qual.Nullable; -import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccTokenDocument; @@ -25,8 +24,8 @@ public class PLSQLParser extends JjtreeParserAdapter { } @Override - protected ASTInput parseImpl(CharStream cs, String suppressMarker, LanguageVersion languageVersion) throws ParseException { - return new PLSQLParserImpl(cs).Input().setLanguageVersion(languageVersion); + protected ASTInput parseImpl(CharStream cs, ParserTask task) throws ParseException { + return new PLSQLParserImpl(cs).Input().addTaskInfo(task); } } diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTSource.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTSource.java index a19f70bfda..242ff9117b 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTSource.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTSource.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.scala.ast; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.Parser.ParserTask; import net.sourceforge.pmd.lang.ast.RootNode; import scala.meta.Source; @@ -15,6 +16,7 @@ import scala.meta.Source; public final class ASTSource extends AbstractScalaNode implements RootNode { private LanguageVersion languageVersion; + private String filename; ASTSource(Source scalaNode) { super(scalaNode); @@ -25,8 +27,15 @@ public final class ASTSource extends AbstractScalaNode implements RootNo return languageVersion; } - void setLanguageVersion(LanguageVersion languageVersion) { - this.languageVersion = languageVersion; + + @Override + public String getSourceCodeFile() { + return filename; + } + + void addTaskInfo(ParserTask languageVersion) { + this.languageVersion = languageVersion.getLanguageVersion(); + this.filename = languageVersion.getFileDisplayName(); } @Override diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaParser.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaParser.java index 6c6d2c0641..187151ee9d 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaParser.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaParser.java @@ -39,7 +39,7 @@ public final class ScalaParser implements Parser { Input.VirtualFile virtualFile = new Input.VirtualFile(task.getFileDisplayName(), task.getSourceText()); Source src = new ScalametaParser(virtualFile, dialect).parseSource(); ASTSource root = (ASTSource) new ScalaTreeBuilder().build(src); - root.setLanguageVersion(task.getLanguageVersion()); + root.addTaskInfo(task); return root; } diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java index 2cba64edc8..6366a692ad 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java @@ -22,9 +22,11 @@ public final class PmdSwiftParser extends AntlrBaseParser } @Override - protected SwTopLevel parse(final Lexer lexer) { + protected SwTopLevel parse(final Lexer lexer, ParserTask task) { SwiftParser parser = new SwiftParser(new CommonTokenStream(lexer)); - return parser.topLevel(); + SwTopLevel swTopLevel = parser.topLevel(); + swTopLevel.addTaskInfo(task); + return swTopLevel; } @Override diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftRootNode.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftRootNode.java new file mode 100644 index 0000000000..64058dc613 --- /dev/null +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftRootNode.java @@ -0,0 +1,43 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + +import org.antlr.v4.runtime.ParserRuleContext; + +import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.Parser.ParserTask; +import net.sourceforge.pmd.lang.ast.RootNode; + +// package private base class +abstract class SwiftRootNode extends SwiftInnerNode implements RootNode { + + private String filename; + private LanguageVersion languageVersion; + + SwiftRootNode() { + super(); + } + + SwiftRootNode(ParserRuleContext parent, int invokingStateNumber) { + super(parent, invokingStateNumber); + } + + + @Override + public String getSourceCodeFile() { + return filename; + } + + @Override + public LanguageVersion getLanguageVersion() { + return languageVersion; + } + + void addTaskInfo(ParserTask languageVersion) { + this.languageVersion = languageVersion.getLanguageVersion(); + this.filename = languageVersion.getFileDisplayName(); + } + +} diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/DummyLanguageModule.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/DummyLanguageModule.java index 3ca6d7389e..acd12a7e7c 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/DummyLanguageModule.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/DummyLanguageModule.java @@ -62,6 +62,11 @@ public class DummyLanguageModule extends BaseLanguageModule { return languageVersion; } + @Override + public String getSourceCodeFile() { + return "someFile.dummy"; + } + public DummyRootNode setLanguageVersion(LanguageVersion languageVersion) { this.languageVersion = languageVersion; return this; diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/testframework/RuleTst.java b/pmd-test/src/main/java/net/sourceforge/pmd/testframework/RuleTst.java index d582d9b058..a25e24da09 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/testframework/RuleTst.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/testframework/RuleTst.java @@ -249,9 +249,7 @@ public abstract class RuleTst { } private Report processUsingStringReader(TestDescriptor test, Rule rule) throws PMDException { - Report report = new Report(); - runTestFromString(test, rule); - return report; + return runTestFromString(test, rule); } /** @@ -305,8 +303,8 @@ public abstract class RuleTst { } } - public void runTestFromString(TestDescriptor test, Rule rule) { - runTestFromString(test.getCode(), rule, test.getLanguageVersion(), test.isUseAuxClasspath()); + public Report runTestFromString(TestDescriptor test, Rule rule) { + return runTestFromString(test.getCode(), rule, test.getLanguageVersion(), test.isUseAuxClasspath()); } /** diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/ASTCompilationUnit.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/ASTCompilationUnit.java index 7dede888f9..6c427e019c 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/ASTCompilationUnit.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/ASTCompilationUnit.java @@ -5,11 +5,13 @@ package net.sourceforge.pmd.lang.vf.ast; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.Parser.ParserTask; import net.sourceforge.pmd.lang.ast.RootNode; public final class ASTCompilationUnit extends AbstractVfNode implements RootNode { private LanguageVersion languageVersion; + private String filename; ASTCompilationUnit(int id) { super(id); @@ -20,8 +22,14 @@ public final class ASTCompilationUnit extends AbstractVfNode implements RootNode return languageVersion; } - ASTCompilationUnit setLanguageVersion(LanguageVersion languageVersion) { - this.languageVersion = languageVersion; + @Override + public String getSourceCodeFile() { + return filename; + } + + ASTCompilationUnit addTaskInfo(ParserTask languageVersion) { + this.languageVersion = languageVersion.getLanguageVersion(); + this.filename = languageVersion.getFileDisplayName(); return this; } diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParser.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParser.java index b28525735c..639a583bc2 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParser.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParser.java @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.vf.ast; import org.checkerframework.checker.nullness.qual.Nullable; -import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccTokenDocument; @@ -28,8 +27,8 @@ public final class VfParser extends JjtreeParserAdapter { } @Override - protected ASTCompilationUnit parseImpl(CharStream cs, String suppressMarker, LanguageVersion languageVersion) throws ParseException { - return new VfParserImpl(cs).CompilationUnit().setLanguageVersion(languageVersion); + protected ASTCompilationUnit parseImpl(CharStream cs, ParserTask task) throws ParseException { + return new VfParserImpl(cs).CompilationUnit().addTaskInfo(task); } } diff --git a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/ASTTemplate.java b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/ASTTemplate.java index 5985079b84..75cdb91dc8 100644 --- a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/ASTTemplate.java +++ b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/ASTTemplate.java @@ -5,11 +5,13 @@ package net.sourceforge.pmd.lang.vm.ast; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.Parser.ParserTask; import net.sourceforge.pmd.lang.ast.RootNode; public final class ASTTemplate extends AbstractVmNode implements RootNode { private LanguageVersion languageVersion; + private String filename; public ASTTemplate(int id) { super(id); @@ -20,8 +22,14 @@ public final class ASTTemplate extends AbstractVmNode implements RootNode { return languageVersion; } - ASTTemplate setLanguageVersion(LanguageVersion languageVersion) { - this.languageVersion = languageVersion; + @Override + public String getSourceCodeFile() { + return filename; + } + + ASTTemplate addTaskInfo(ParserTask languageVersion) { + this.languageVersion = languageVersion.getLanguageVersion(); + this.filename = languageVersion.getFileDisplayName(); return this; } diff --git a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/VmParser.java b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/VmParser.java index b55be62bf2..ceb5a36baa 100644 --- a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/VmParser.java +++ b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/VmParser.java @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.vm.ast; import org.checkerframework.checker.nullness.qual.Nullable; -import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; @@ -24,8 +23,8 @@ public class VmParser extends JjtreeParserAdapter { } @Override - protected ASTTemplate parseImpl(CharStream cs, String suppressMarker, LanguageVersion languageVersion) throws ParseException { - return new VmParserImpl(cs).Template().setLanguageVersion(languageVersion); + protected ASTTemplate parseImpl(CharStream cs, ParserTask task) throws ParseException { + return new VmParserImpl(cs).Template().addTaskInfo(task); } diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java index 762fc9cdcc..db7bee1201 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java @@ -62,7 +62,7 @@ public class XmlParserImpl { public RootXmlNode parse(ParserTask task) { String xmlData = task.getSourceText(); Document document = parseDocument(xmlData); - RootXmlNode root = new RootXmlNode(this, document, task.getLanguageVersion()); + RootXmlNode root = new RootXmlNode(this, document, task); DOMLineNumbers lineNumbers = new DOMLineNumbers(root, xmlData); lineNumbers.determine(); nodeCache.put(document, root); @@ -93,16 +93,23 @@ public class XmlParserImpl { public static class RootXmlNode extends XmlNodeWrapper implements RootNode { private final LanguageVersion languageVersion; + private final String filename; - RootXmlNode(XmlParserImpl parser, Node domNode, LanguageVersion languageVersion) { + RootXmlNode(XmlParserImpl parser, Node domNode, ParserTask task) { super(parser, domNode); - this.languageVersion = languageVersion; + this.languageVersion = task.getLanguageVersion(); + this.filename = task.getFileDisplayName(); } @Override public LanguageVersion getLanguageVersion() { return languageVersion; } + + @Override + public String getSourceCodeFile() { + return filename; + } } }