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 5690591011..9d9672ac0c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java @@ -100,7 +100,7 @@ public class RuleContext { */ public String getSourceCodeFilename() { if (sourceCodeFile != null) { - return sourceCodeFile.getName(); + return sourceCodeFile.getAbsolutePath(); } return ""; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java index fec1de009d..64b9cb8fb4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java @@ -138,36 +138,6 @@ public class SourceCodeProcessor { private void processSource(Reader reader, RuleSets ruleSets, RuleContext ctx) throws IOException { - - // basically: - // 1. make the union of all stage dependencies of each rule, by language, for the Rulesets - // 2. order them by dependency - // 3. run them and time them if needed - - // The problem is the first two steps need only be done once. - // They're probably costly and if we do this here without changing anything, - // they'll be done on each file! Btw currently the "usesDfa" and such are nested loops testing - // all rules of all rulesets, but they're run on each file too! - - // FIXME - this implementation is a hack to wire-in stages without - // needing to change RuleSet immediately - - // With mutable RuleSets, caching of the value can't be guaranteed to be accurate... - // The approach I'd like to take is either - // * to create a new RunnableRulesets class which is immutable, and performs all these preliminary - // computations upon construction. - // * or to modify Ruleset and Rulesets to be immutable. This IMO is a better option because it makes - // these objects easier to reason about and pass around from thread to thread. It also avoid creating - // a new class, and breaking SourceCodeProcessor's API too much. - // - // The "preliminary computations" also include: - // * removing dysfunctional rules - // * separating rulechain rules from normal rules - // * grouping rules by language/ file extension - // * etc. - - - LanguageVersion languageVersion = ctx.getLanguageVersion(); String filename = ctx.getSourceCodeFilename(); String sourceCode = IOUtils.toString(reader); @@ -179,6 +149,8 @@ public class SourceCodeProcessor { SemanticErrorReporter.noop() // TODO ); + languageVersion.getLanguageVersionHandler().declareParserTaskProperties(task.getProperties()); + task.getProperties().setProperty(ParserTask.COMMENT_MARKER, configuration.getSuppressMarker()); Parser parser = languageVersion.getLanguageVersionHandler().getParser(); 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 da91fbd95a..5ef524ebfd 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 @@ -5,6 +5,7 @@ package net.sourceforge.pmd.processor; import java.io.BufferedInputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.List; @@ -82,6 +83,7 @@ public class PmdRunnable implements Callable { try (InputStream stream = new BufferedInputStream(dataSource.getInputStream())) { tc.ruleContext.setLanguageVersion(null); + tc.ruleContext.setSourceCodeFile(new File(dataSource.getNiceFileName(false, null))); sourceCodeProcessor.processSourceCode(stream, tc.ruleSets, tc.ruleContext); } catch (PMDException pmde) { addError(report, pmde, "Error while processing file: " + fileName); 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 ba5534e574..69d3ff192d 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleContextTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleContextTest.java @@ -22,7 +22,7 @@ import net.sourceforge.pmd.lang.ast.RootNode; import junit.framework.JUnit4TestAdapter; public class RuleContextTest { - public static Report getReport(Consumer sideEffects) throws Exception { + public static Report getReport(Consumer sideEffects) { Report report = new Report(); RuleContext ctx = new RuleContext(); ctx.setSourceCodeFile(new File("test.dummy")); @@ -58,8 +58,9 @@ public class RuleContextTest { 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()); + File file = new File("dir/foo.java"); + ctx.setSourceCodeFile(file); + assertEquals("filename mismatch", file.getAbsolutePath(), ctx.getSourceCodeFilename()); } @Test diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/Lub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/Lub.java index e39c71baf6..154db01020 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/Lub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/Lub.java @@ -356,12 +356,6 @@ final class Lub { } } - private static void checkGlbComponent(Collection types, JTypeMirror ci) { - if (ci.isPrimitive() || ci instanceof JWildcardType || ci instanceof JIntersectionType) { - throw new IllegalArgumentException("Bad intersection type component: " + ci + " in " + types); - } - } - private static @NonNull List flattenRemoveTrivialBound(Collection types) { List bounds = new ArrayList<>(types.size()); diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt index e4f63e1de5..97c30f713b 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt @@ -120,13 +120,13 @@ abstract class BaseParsingHelper, T : RootNode * so. */ @JvmOverloads - fun parse(sourceCode: String, version: String? = null): T { + fun parse(sourceCode: String, version: String? = null, filename: String = FileAnalysisException.NO_FILE_NAME): T { val lversion = if (version == null) defaultVersion else getVersion(version) val handler = lversion.languageVersionHandler val parser = handler.parser - val source = DataSource.forString(sourceCode, FileAnalysisException.NO_FILE_NAME) + val source = DataSource.forString(sourceCode, filename) val toString = DataSource.readToString(source, StandardCharsets.UTF_8) - val task = Parser.ParserTask(lversion, FileAnalysisException.NO_FILE_NAME, toString, SemanticErrorReporter.noop()) + val task = Parser.ParserTask(lversion, filename, toString, SemanticErrorReporter.noop()) task.properties.also { handler.declareParserTaskProperties(it) params.configureParser(it) @@ -176,7 +176,7 @@ abstract class BaseParsingHelper, T : RootNode */ @JvmOverloads open fun parseFile(path: Path, version: String? = null): T = - parse(IOUtils.toString(Files.newBufferedReader(path)), version) + parse(IOUtils.toString(Files.newBufferedReader(path)), version, filename = path.toAbsolutePath().toString()) /** * Fetches the source of the given [clazz]. diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/SalesforceFieldTypes.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/SalesforceFieldTypes.java index 3cbf975533..e1514cd42f 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/SalesforceFieldTypes.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/SalesforceFieldTypes.java @@ -55,6 +55,7 @@ abstract class SalesforceFieldTypes { // The expression has been previously requested, but was not found return null; } else { + // fixme getting a Path from the display name is just wrong. Path vfFilePath = Paths.get(vfFileName); List resolvedPaths = new ArrayList<>(); for (String metadataDirectory : metadataDirectories) { diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/rule/security/VfUnescapeElTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/rule/security/VfUnescapeElTest.java index 4ddf634b29..d9fc3f2254 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/rule/security/VfUnescapeElTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/rule/security/VfUnescapeElTest.java @@ -8,31 +8,22 @@ import static net.sourceforge.pmd.util.CollectionUtil.listOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Test; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.PMDConfiguration; -import net.sourceforge.pmd.PMDException; import net.sourceforge.pmd.Report; import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.RuleSet; import net.sourceforge.pmd.RuleViolation; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.ast.Parser; -import net.sourceforge.pmd.lang.ast.Parser.ParserTask; -import net.sourceforge.pmd.lang.ast.SemanticErrorReporter; import net.sourceforge.pmd.lang.vf.VFTestUtils; -import net.sourceforge.pmd.lang.vf.VfLanguageModule; +import net.sourceforge.pmd.lang.vf.ast.VfParsingHelper; import net.sourceforge.pmd.testframework.PmdRuleTst; import net.sourceforge.pmd.util.datasource.FileDataSource; @@ -43,7 +34,7 @@ public class VfUnescapeElTest extends PmdRuleTst { * Verify that CustomFields stored in sfdx project format are correctly parsed */ @Test - public void testSfdxCustomFields() throws IOException, PMDException { + public void testSfdxCustomFields() { Path vfPagePath = VFTestUtils.getMetadataPath(this, VFTestUtils.MetadataFormat.SFDX, VFTestUtils.MetadataType.Vf) .resolve("StandardAccount.page"); @@ -68,7 +59,7 @@ public class VfUnescapeElTest extends PmdRuleTst { * Verify that CustomFields stored in mdapi format are correctly parsed */ @Test - public void testMdapiCustomFields() throws IOException, PMDException { + public void testMdapiCustomFields() { Path vfPagePath = VFTestUtils.getMetadataPath(this, VFTestUtils.MetadataFormat.MDAPI, VFTestUtils.MetadataType.Vf).resolve("StandardAccount.page"); Report report = runRule(vfPagePath); @@ -86,7 +77,7 @@ public class VfUnescapeElTest extends PmdRuleTst { * Tests a page with a single Apex controller */ @Test - public void testApexController() throws IOException, PMDException { + public void testApexController() { Path vfPagePath = VFTestUtils.getMetadataPath(this, VFTestUtils.MetadataFormat.SFDX, VFTestUtils.MetadataType.Vf).resolve("ApexController.page"); Report report = runRule(vfPagePath); @@ -105,7 +96,7 @@ public class VfUnescapeElTest extends PmdRuleTst { * Tests a page with a standard controller and two Apex extensions */ @Test - public void testExtensions() throws IOException, PMDException { + public void testExtensions() { Path vfPagePath = VFTestUtils.getMetadataPath(this, VFTestUtils.MetadataFormat.SFDX, VFTestUtils.MetadataType.Vf) .resolve(Paths.get("StandardAccountWithExtensions.page")); @@ -123,20 +114,11 @@ public class VfUnescapeElTest extends PmdRuleTst { /** * Runs a rule against a Visualforce page on the file system. */ - private Report runRule(Path vfPagePath) throws IOException { - LanguageVersion languageVersion = LanguageRegistry.getLanguage(VfLanguageModule.NAME).getDefaultVersion(); - ParserTask task = new ParserTask(languageVersion, - vfPagePath.toString(), - IOUtils.toString(Files.newBufferedReader(vfPagePath)), - SemanticErrorReporter.noop()); - - Parser parser = languageVersion.getLanguageVersionHandler().getParser(); - - Node node = parser.parse(task); + private Report runRule(Path vfPagePath) { + Node node = VfParsingHelper.DEFAULT.parseFile(vfPagePath); assertNotNull(node); PMDConfiguration config = new PMDConfiguration(); - config.setDefaultLanguageVersion(languageVersion); config.setIgnoreIncrementalAnalysis(true); // simple class loader, that doesn't delegate to parent. // this allows us in the tests to simulate PMD run without @@ -156,7 +138,7 @@ public class VfUnescapeElTest extends PmdRuleTst { return PMD.processFiles( config, listOf(RuleSet.forSingleRule(rule)), - listOf(new FileDataSource(vfPagePath.toFile())), + listOf(new FileDataSource(vfPagePath.toAbsolutePath().toFile())), Collections.emptyList() ); } diff --git a/pmd-xml/src/test/resources/net/sourceforge/pmd/lang/xml/ast/testdata/sampleNs.xml b/pmd-xml/src/test/resources/net/sourceforge/pmd/lang/xml/ast/testdata/sampleNs.xml index 776a795cd1..3d242f0de8 100644 --- a/pmd-xml/src/test/resources/net/sourceforge/pmd/lang/xml/ast/testdata/sampleNs.xml +++ b/pmd-xml/src/test/resources/net/sourceforge/pmd/lang/xml/ast/testdata/sampleNs.xml @@ -1,8 +1,4 @@ - -