Skip to content

Commit

Permalink
Merge pull request #3971 from adangel:filecollector-language
Browse files Browse the repository at this point in the history
[core] Remember language when using FileCollector.addFile #3971
  • Loading branch information
adangel committed Aug 30, 2022
2 parents 814ee91 + b232ea4 commit bdde4b7
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 3 deletions.
2 changes: 2 additions & 0 deletions docs/pages/release_notes.md
Expand Up @@ -18,6 +18,8 @@ This is a {{ site.pmd.release_type }} release.

* apex
* [#4096](https://github.com/pmd/pmd/issues/4096): \[apex] ApexAssertionsShouldIncludeMessage and ApexUnitTestClassShouldHaveAsserts: support new Assert class (introduced with Apex v56.0)
* core
* [#3970](https://github.com/pmd/pmd/issues/3970): \[core] FileCollector.addFile ignores language parameter
* java-codestyle
* [#4082](https://github.com/pmd/pmd/issues/4082): \[java] UnnecessaryImport false positive for on-demand imports of nested classes

Expand Down
Expand Up @@ -18,6 +18,7 @@
import net.sourceforge.pmd.util.IOUtil;
import net.sourceforge.pmd.util.datasource.DataSource;
import net.sourceforge.pmd.util.datasource.FileDataSource;
import net.sourceforge.pmd.util.datasource.internal.LanguageAwareDataSource;

/**
* A {@link TextFile} backed by a file in some {@link FileSystem}.
Expand Down Expand Up @@ -73,7 +74,7 @@ public String readContents() throws IOException {

@Override
public DataSource toDataSourceCompat() {
return new FileDataSource(path.toFile());
return new LanguageAwareDataSource(new FileDataSource(path.toFile()), languageVersion);
}

@Override
Expand Down
Expand Up @@ -12,6 +12,7 @@
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.util.datasource.DataSource;
import net.sourceforge.pmd.util.datasource.ReaderDataSource;
import net.sourceforge.pmd.util.datasource.internal.LanguageAwareDataSource;

/**
* Read-only view on a string.
Expand Down Expand Up @@ -64,9 +65,10 @@ public String readContents() {

@Override
public DataSource toDataSourceCompat() {
return new ReaderDataSource(
return new LanguageAwareDataSource(new ReaderDataSource(
new StringReader(content),
pathId
pathId),
languageVersion
);
}

Expand Down
Expand Up @@ -21,6 +21,7 @@
import net.sourceforge.pmd.benchmark.TimeTracker;
import net.sourceforge.pmd.renderers.Renderer;
import net.sourceforge.pmd.util.datasource.DataSource;
import net.sourceforge.pmd.util.datasource.internal.LanguageAwareDataSource;

/**
*
Expand Down Expand Up @@ -82,6 +83,9 @@ public Report call() {

try (InputStream stream = new BufferedInputStream(dataSource.getInputStream())) {
tc.ruleContext.setLanguageVersion(null);
if (dataSource instanceof LanguageAwareDataSource) {
tc.ruleContext.setLanguageVersion(((LanguageAwareDataSource) dataSource).getLanguageVersion());
}
sourceCodeProcessor.processSourceCode(stream, tc.ruleSets, tc.ruleContext);
} catch (PMDException pmde) {
addError(report, pmde, "Error while processing file: " + fileName);
Expand Down
@@ -0,0 +1,42 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/

package net.sourceforge.pmd.util.datasource.internal;

import java.io.IOException;
import java.io.InputStream;

import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.util.datasource.DataSource;

@InternalApi
public class LanguageAwareDataSource implements DataSource {
private final DataSource base; // delegate DataSource methods to this
private final LanguageVersion version;

public LanguageAwareDataSource(DataSource base, LanguageVersion version) {
this.base = base;
this.version = version;
}

public LanguageVersion getLanguageVersion() {
return version;
}

@Override
public InputStream getInputStream() throws IOException {
return base.getInputStream();
}

@Override
public String getNiceFileName(boolean shortNames, String inputFileName) {
return base.getNiceFileName(shortNames, inputFileName);
}

@Override
public void close() throws IOException {
base.close();
}
}
58 changes: 58 additions & 0 deletions pmd-core/src/test/java/net/sourceforge/pmd/PmdAnalysisTest.java
Expand Up @@ -14,10 +14,18 @@
import static org.mockito.Mockito.verify;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;
import org.mockito.ArgumentMatchers;

import net.sourceforge.pmd.lang.Dummy2LanguageModule;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.document.SimpleTestTextFile;
import net.sourceforge.pmd.lang.rule.AbstractRule;
import net.sourceforge.pmd.renderers.Renderer;

/**
Expand Down Expand Up @@ -72,4 +80,54 @@ public void testRulesetWhenSomeoneHasAnError() {
}
}

@Test
public void testFileWithSpecificLanguage() {
final Language language = Dummy2LanguageModule.getInstance();
PMDConfiguration config = new PMDConfiguration();
config.setIgnoreIncrementalAnalysis(true);
RuleSet ruleset = RuleSet.forSingleRule(new TestRule());

try (PmdAnalysis pmd = PmdAnalysis.create(config)) {
pmd.addRuleSet(ruleset);
pmd.files().addFile(Paths.get("src", "test", "resources", "sample-source", "dummy", "foo.txt"), language);
Report report = pmd.performAnalysisAndCollectReport();
for (Report.ProcessingError error : report.getProcessingErrors()) {
System.out.println("error = " + error.getMsg() + ": " + error.getDetail());
}
Assert.assertEquals(0, report.getProcessingErrors().size());
Assert.assertEquals(1, report.getViolations().size());
}
}

@Test
public void testTextFileWithSpecificLanguage() {
final Language language = Dummy2LanguageModule.getInstance();
PMDConfiguration config = new PMDConfiguration();
config.setIgnoreIncrementalAnalysis(true);
RuleSet ruleset = RuleSet.forSingleRule(new TestRule());

try (PmdAnalysis pmd = PmdAnalysis.create(config)) {
pmd.addRuleSet(ruleset);
pmd.files().addFile(new SimpleTestTextFile("test content foo", "foo.txt", "foo.txt", language.getDefaultVersion()));
Report report = pmd.performAnalysisAndCollectReport();
for (Report.ProcessingError error : report.getProcessingErrors()) {
System.out.println("error = " + error.getMsg() + ": " + error.getDetail());
}
Assert.assertEquals(0, report.getProcessingErrors().size());
Assert.assertEquals(1, report.getViolations().size());
}
}

public static class TestRule extends AbstractRule {
public TestRule() {
setLanguage(Dummy2LanguageModule.getInstance());
setMessage("dummy 2 test rule");
}

@Override
public void apply(List<? extends Node> nodes, RuleContext ctx) {
ctx.addViolation(nodes.get(0));
}
}

}
Expand Up @@ -16,4 +16,8 @@ public Dummy2LanguageModule() {
super(NAME, null, TERSE_NAME, "dummy2");
addVersion("1.0", new DummyLanguageModule.Handler(), true);
}

public static Language getInstance() {
return LanguageRegistry.getLanguage(NAME);
}
}
@@ -0,0 +1,17 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/

package net.sourceforge.pmd.lang.document;

import net.sourceforge.pmd.lang.LanguageVersion;

/**
* Makes {@link StringTextFile} publicly available for unit tests.
*/
public class SimpleTestTextFile extends StringTextFile {

public SimpleTestTextFile(String content, String pathId, String displayName, LanguageVersion languageVersion) {
super(content, pathId, displayName, languageVersion);
}
}
1 change: 1 addition & 0 deletions pmd-core/src/test/resources/sample-source/dummy/foo.txt
@@ -0,0 +1 @@
A dummy file with file extension txt.

0 comments on commit bdde4b7

Please sign in to comment.