Skip to content

Commit

Permalink
[core] Store languageVersion in DataSource
Browse files Browse the repository at this point in the history
in order to support FileCollector.addFile with language

Fixes pmd#3970
  • Loading branch information
adangel committed Jul 29, 2022
1 parent 2cfdc9c commit 815242a
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 33 deletions.
Expand Up @@ -222,7 +222,7 @@ private void determineLanguage(RuleContext ctx) {
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);
}
}
Expand Down
Expand Up @@ -5,16 +5,13 @@
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;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;

import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.internal.util.AssertionUtil;

/**
Expand All @@ -27,8 +24,6 @@ public class LanguageVersionDiscoverer {

private LanguageVersion forcedVersion;

private Map<String, LanguageVersion> forcedVersionByFile = new HashMap<>();

public LanguageVersionDiscoverer() {
this(null);
}
Expand Down Expand Up @@ -102,13 +97,10 @@ public LanguageVersion getDefaultLanguageVersionForFile(File sourceFile) {
* 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;
}
Expand Down Expand Up @@ -150,16 +142,4 @@ private String getExtension(String fileName) {
}



@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);
}
}
Expand Up @@ -155,10 +155,8 @@ public boolean addFile(Path file, Language language) {
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;
}

Expand Down
Expand Up @@ -17,7 +17,7 @@
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}.
Expand Down Expand Up @@ -73,7 +73,7 @@ public String readContents() throws IOException {

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

@Override
Expand Down
Expand Up @@ -11,7 +11,7 @@
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.
Expand Down Expand Up @@ -64,9 +64,10 @@ public String readContents() {

@Override
public DataSource toDataSourceCompat() {
return new ReaderDataSource(
return new ReaderDataSourceWithLanguage(
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,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;
}
}
23 changes: 23 additions & 0 deletions pmd-core/src/test/java/net/sourceforge/pmd/PmdAnalysisTest.java
Expand Up @@ -24,6 +24,7 @@
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 @@ -90,6 +91,28 @@ public void testFileWithSpecificLanguage() {
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());
}
Expand Down
@@ -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);
}
}

0 comments on commit 815242a

Please sign in to comment.