[core] Store languageVersion in DataSource

in order to support FileCollector.addFile with language

Fixes #3970
This commit is contained in:
Andreas Dangel committed 2022-07-29 12:21:11 +02:00
1 parent 2cfdc9c6aa
commit 815242a39a
11 files changed
+121 -33

No files matched your search

@@ -222,7 +222,7 @@ public class SourceCodeProcessor {
ctx.setLanguageVersion(forceLanguage);
} else {
// otherwise determine by file extension
LanguageVersion languageVersion = configuration.getLanguageVersionOfFile(ctx.getSourceCodeFile().toString());
LanguageVersion languageVersion = configuration.getLanguageVersionOfFile(ctx.getSourceCodeFilename());
ctx.setLanguageVersion(languageVersion);
}
}
@@ -5,8 +5,6 @@
package net.sourceforge.pmd.lang;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -14,7 +12,6 @@ import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.internal.util.AssertionUtil;
/**
@@ -27,8 +24,6 @@ public class LanguageVersionDiscoverer {
private LanguageVersion forcedVersion;
private Map<String, LanguageVersion> forcedVersionByFile = new HashMap<>();
public LanguageVersionDiscoverer() {
this(null);
}
@@ -102,13 +97,10 @@ public class LanguageVersionDiscoverer {
* file.
*/
public LanguageVersion getDefaultLanguageVersionForFile(String fileName) {
LanguageVersion languageVersion = forcedVersionByFile.get(fileName);
if (languageVersion == null) {
List<Language> languages = getLanguagesForFile(fileName);
if (!languages.isEmpty()) {
languageVersion = getDefaultLanguageVersion(languages.get(0));
}
List<Language> languages = getLanguagesForFile(fileName);
LanguageVersion languageVersion = null;
if (!languages.isEmpty()) {
languageVersion = getDefaultLanguageVersion(languages.get(0));
}
return languageVersion;
}
@@ -150,16 +142,4 @@ public class LanguageVersionDiscoverer {
}
@InternalApi
@Deprecated
public void recordLanguageVersionForFile(Path file, LanguageVersion languageVersion) {
String fileName;
try {
fileName = file.toRealPath().toString();
} catch (IOException e) {
fileName = file.toAbsolutePath().toString();
}
forcedVersionByFile.put(fileName, languageVersion);
}
}
@@ -155,10 +155,8 @@ public final class FileCollector implements AutoCloseable {
reporter.error("Not a regular file {0}", file);
return false;
}
LanguageVersion languageVersion = discoverer.getDefaultLanguageVersion(language);
NioTextFile nioTextFile = new NioTextFile(file, charset, languageVersion, getDisplayName(file));
NioTextFile nioTextFile = new NioTextFile(file, charset, discoverer.getDefaultLanguageVersion(language), getDisplayName(file));
addFileImpl(nioTextFile);
discoverer.recordLanguageVersionForFile(file, languageVersion);
return true;
}
@@ -17,7 +17,7 @@ import net.sourceforge.pmd.internal.util.AssertionUtil;
import net.sourceforge.pmd.lang.LanguageVersion;
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.FileDataSourceWithLanguage;
/**
* A {@link TextFile} backed by a file in some {@link FileSystem}.
@@ -73,7 +73,7 @@ class NioTextFile implements TextFile {
@Override
public DataSource toDataSourceCompat() {
return new FileDataSource(path.toFile());
return new FileDataSourceWithLanguage(path.toFile(), languageVersion);
}
@Override
@@ -11,7 +11,7 @@ import net.sourceforge.pmd.annotation.Experimental;
import net.sourceforge.pmd.internal.util.AssertionUtil;
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.ReaderDataSourceWithLanguage;
/**
* Read-only view on a string.
@@ -64,9 +64,10 @@ class StringTextFile implements TextFile {
@Override
public DataSource toDataSourceCompat() {
return new ReaderDataSource(
return new ReaderDataSourceWithLanguage(
new StringReader(content),
pathId
pathId,
languageVersion
);
}
@@ -21,6 +21,7 @@ import net.sourceforge.pmd.annotation.InternalApi;
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;
/**
*
@@ -82,6 +83,9 @@ public class PmdRunnable implements Callable<Report> {
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);
@@ -0,0 +1,26 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.util.datasource.internal;
import java.io.File;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.util.datasource.FileDataSource;
@InternalApi
public class FileDataSourceWithLanguage extends FileDataSource implements LanguageAwareDataSource {
private final LanguageVersion languageVersion;
public FileDataSourceWithLanguage(File file, LanguageVersion languageVersion) {
super(file);
this.languageVersion = languageVersion;
}
@Override
public LanguageVersion getLanguageVersion() {
return languageVersion;
}
}
@@ -0,0 +1,13 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.util.datasource.internal;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.LanguageVersion;
@InternalApi
public interface LanguageAwareDataSource {
LanguageVersion getLanguageVersion();
}
@@ -0,0 +1,26 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.util.datasource.internal;
import java.io.Reader;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.util.datasource.ReaderDataSource;
@InternalApi
public class ReaderDataSourceWithLanguage extends ReaderDataSource implements LanguageAwareDataSource {
private final LanguageVersion languageVersion;
public ReaderDataSourceWithLanguage(Reader reader, String dataSourceName, LanguageVersion languageVersion) {
super(reader, dataSourceName);
this.languageVersion = languageVersion;
}
@Override
public LanguageVersion getLanguageVersion() {
return languageVersion;
}
}
@@ -24,6 +24,7 @@ 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;
@@ -90,6 +91,28 @@ public class PmdAnalysisTest {
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());
}
@@ -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);
}
}