diff --git a/docs/pages/pmd/userdocs/migrating_to_pmd7.md b/docs/pages/pmd/userdocs/migrating_to_pmd7.md index f7e1b9d203..50049d0ef8 100644 --- a/docs/pages/pmd/userdocs/migrating_to_pmd7.md +++ b/docs/pages/pmd/userdocs/migrating_to_pmd7.md @@ -4,6 +4,7 @@ tags: [pmd, userdocs] summary: "Migrating to PMD 7 from PMD 6.x" permalink: pmd_userdocs_migrating_to_pmd7.html author: Andreas Dangel +last_updated: June 2024 (7.3.0) --- {% include important.html content=" @@ -3363,8 +3364,9 @@ See the use case [I'm using only built-in rules](#im-using-only-built-in-rules) #### Maven -* Due to some changes in PMD's API, you can't simply pull in the new PMD 7 dependency. -* See [Using PMD 7 with maven-pmd-plugin](pmd_userdocs_tools_maven.html#using-pmd-7-with-maven-pmd-plugin). +* Since maven-pmd-plugin 3.22.0, PMD 7 is supported directly. +* See [MPMD-379](https://issues.apache.org/jira/browse/MPMD-379) +* See [Using PMD 7 with maven-pmd-plugin](pmd_userdocs_tools_maven.html#using-pmd-7-with-maven-pmd-plugin) #### Gradle diff --git a/docs/pages/pmd/userdocs/tools/maven.md b/docs/pages/pmd/userdocs/tools/maven.md index be76561367..73e7562ee9 100644 --- a/docs/pages/pmd/userdocs/tools/maven.md +++ b/docs/pages/pmd/userdocs/tools/maven.md @@ -2,8 +2,8 @@ title: Maven PMD Plugin tags: [userdocs, tools] permalink: pmd_userdocs_tools_maven.html -last_updated: February 2024 -mpmd_version: 3.21.2 +last_updated: June 2024 (7.3.0) +mpmd_version: 3.23.0 author: > Miguel Griffa , Romain PELISSE , @@ -72,7 +72,7 @@ This will add an entry to the 'project reports' section with the PMD report when To run PMD on a Maven project without adding it as a report, simply run - mvn pmd:pmd + mvn complile pmd:pmd The PMD plugin writes the report in XML which will then be formatted into more readable HTML. @@ -241,47 +241,25 @@ Maven plugin will use and benefit from the latest bugfixes and enhancements: #### Using PMD 7 with maven-pmd-plugin -The Maven PMD plugin comes with a specific PMD version, which is documented on the +Since version 3.22.0 ([MPMD-379](https://issues.apache.org/jira/browse/MPMD-379)), maven-pmd-plugin uses +by default now PMD 7.0.0 and no extra configuration is required. + +The specific PMD version used by maven-pmd-plugin might change. The exact version is documented on the [plugin project page](https://maven.apache.org/plugins/maven-pmd-plugin/index.html). -This might not support PMD 7 out of the box. -Since PMD 7 is a major release which breaks compatibility in various ways, the solution described -above in [Upgrading the PMD version at runtime](#upgrading-the-pmd-version-at-runtime) doesn't work -directly. +In order to use newer versions of PMD 7, you can simply follow the guide +[Upgrading PMD at Runtime](https://maven.apache.org/plugins/maven-pmd-plugin/examples/upgrading-PMD-at-runtime.html). -In order to use PMD 7 with [maven-pmd-plugin](https://maven.apache.org/plugins/maven-pmd-plugin/) a new -compatibility module has been created. This allows to use PMD 7 by simply adding one additional dependency: - -1. Follow the guide [Upgrading PMD at Runtime](https://maven.apache.org/plugins/maven-pmd-plugin/examples/upgrading-PMD-at-runtime.html) -2. Add additionally the following dependency: - -```xml - - net.sourceforge.pmd - pmd-compat6 - ${pmdVersion} - -``` - -It is important to add this dependency as the **first** in the list, so that maven-pmd-plugin sees the (old) -compatible versions of some classes. - -This module is available beginning with version 7.0.0-rc4 and will be there at least for the first -final version PMD 7 (7.0.0). It's not decided yet, whether we will keep updating it, after PMD 7 is finally -released. - -Note: This compatibility module only works for the built-in rules, that are still available in PMD 7. E.g. you need -to review your rulesets and look out for deprecated rules and such. See the use case -[I'm using only built-in rules](pmd_userdocs_migrating_to_pmd7.html#im-using-only-built-in-rules) -in the [Migration Guide for PMD 7](pmd_userdocs_migrating_to_pmd7.html). +Note: If you upgrade from Maven PMD Plugin before 3.22.0 you are most likely updating from PMD 6 to PMD 7. +This upgrade is a major version change. If you use the default ruleset from Maven PMD Plugin, then everything should +just work. But if you use a custom ruleset, you most likely need to review your ruleset and migrate it to PMD 7. +Rules might have been renamed or replaced. See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html) +and [Migration Guide for PMD 7](pmd_userdocs_migrating_to_pmd7.html). As PMD 7 revamped the Java module, if you have custom rules, you need to migrate these rules. See the use case [I'm using custom rules](pmd_userdocs_migrating_to_pmd7.html#im-using-custom-rules) in the Migration Guide. - - - ### Reference For more information, please see the well documented PMD plugin project page here: diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 04bd9ce62d..95d26be8a9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -4,6 +4,12 @@ permalink: pmd_release_notes.html keywords: changelog, release notes --- +{% if is_release_notes_processor %} +{% capture baseurl %}https://docs.pmd-code.org/pmd-doc-{{ site.pmd.version }}/{% endcapture %} +{% else %} +{% assign baseurl = "" %} +{% endif %} + ## {{ site.pmd.date | date: "%d-%B-%Y" }} - {{ site.pmd.version }} The PMD team is pleased to announce PMD {{ site.pmd.version }}. @@ -18,6 +24,17 @@ This is a {{ site.pmd.release_type }} release. * The new Java rule {%rule java/bestpractices/UseEnumCollections %} reports usages for `HashSet` and `HashMap` when the keys are of an enum type. The specialized enum collections are more space- and time-efficient. +#### 💥 pmd-compat6 removed (breaking) + +The already deprecated PMD 6 compatibility module (pmd-compat6) has been removed. It was intended to be used with +older versions of the maven-pmd-plugin, but since maven-pmd-plugin 3.22.0, PMD 7 is supported directly and this +module is not needed anymore. + +If you currently use this dependency (`net.sourceforge.pmd:pmd-compat6`), remove it and upgrade maven-pmd-plugin +to the latest version (3.23.0 or newer). + +See also [Maven PMD Plugin]({{ baseurl }}pmd_userdocs_tools_maven.html). + ### 🐛 Fixed Issues * cli * [#2827](https://github.com/pmd/pmd/issues/2827): \[cli] Consider processing errors in exit status @@ -100,6 +117,11 @@ read the XML format should be updated. patterns don't declare a pattern variable for the whole pattern, but rather for individual record components, which can be accessed via {%jdoc java::lang.java.ast.ASTRecordPattern#getComponentPatterns() %}. +#### Breaking changes: pmd-compat6 removed + +The already deprecated PMD 6 compatibility module (pmd-compat6) has been removed. +See above for details. + ### ✨ External Contributions {% endtocmaker %} diff --git a/pmd-compat6/README.md b/pmd-compat6/README.md deleted file mode 100644 index 4a11803caa..0000000000 --- a/pmd-compat6/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# pmd-compat6 - -This module contains classes from PMD6, that have been removed in PMD7 and also restores -some removed methods. - -The goal is, that PMD7 can be used with [Maven PMD Plugin](https://maven.apache.org/plugins/maven-pmd-plugin) -without any further changes to the plugin. - -The maven-pmd-plugin uses by default PMD Version 6.55.0, but it can be configured to -[Use a new PMD version at runtime](https://maven.apache.org/plugins/maven-pmd-plugin/examples/upgrading-PMD-at-runtime.html). - -Since PMD7 introduces many incompatible changes, another module is needed to restore -compatibility. This is this module. - -In order to use this compatibility module, it needs to be added as the _first_ dependency -when configuring maven-pmd-plugin. - -It is as simple as adding: - -```xml - - net.sourceforge.pmd - pmd-compat6 - ${pmdVersion} - -``` - -Note: The dependency "pmd-compat6" must be listed _first_ before pmd-core, pmd-java, and the others. - -Note: Once the default version of PMD is upgraded to PMD7 in maven-pmd-plugin -(see [MPMD-379](https://issues.apache.org/jira/projects/MPMD/issues/MPMD-379)), this -compatibility module is no longer needed. The module pmd-compat6 might not be maintaned then -any further, hence it is already declared as deprecated. - -The primary goal for this module is, to get maven-pmd-plugin working with PMD7. It might -be useful in other contexts, too, but no guarantee is given, that is works. - -No guarantee is given, that the (deprecated) module pmd-compat6 is being maintained over the -whole lifetime of PMD 7. diff --git a/pmd-compat6/pom.xml b/pmd-compat6/pom.xml deleted file mode 100644 index cf0c893b26..0000000000 --- a/pmd-compat6/pom.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - 4.0.0 - - - net.sourceforge.pmd - pmd - 7.3.0-SNAPSHOT - - - pmd-compat6 - PMD Compatibility Classes for PMD6 (deprecated) - - - ${project.version} - 3.21.2 - - - - - net.sourceforge.pmd - pmd-core - ${project.version} - - - net.sourceforge.pmd - pmd-java - ${project.version} - - - net.sourceforge.pmd - pmd-javascript - ${project.version} - - - net.sourceforge.pmd - pmd-jsp - ${project.version} - - - net.sourceforge.pmd - pmd-cs - ${project.version} - - - - - - - org.jboss.bridger - bridger - 1.6.Final - - - weave - process-classes - - transform - - - - - - org.apache.maven.plugins - maven-invoker-plugin - 3.6.0 - - ${project.build.directory}/it - src/it/settings.xml - ${project.build.directory}/local-repo - verify.bsh - true - - - - integration-test - - install - run - - - - - - - diff --git a/pmd-compat6/src/it/cpd-for-csharp/invoker.properties b/pmd-compat6/src/it/cpd-for-csharp/invoker.properties deleted file mode 100644 index 0d92d959f3..0000000000 --- a/pmd-compat6/src/it/cpd-for-csharp/invoker.properties +++ /dev/null @@ -1,2 +0,0 @@ -invoker.goals = verify -invoker.buildResult = failure diff --git a/pmd-compat6/src/it/cpd-for-csharp/pom.xml b/pmd-compat6/src/it/cpd-for-csharp/pom.xml deleted file mode 100644 index d324ef4634..0000000000 --- a/pmd-compat6/src/it/cpd-for-csharp/pom.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - 4.0.0 - - net.sourceforge.pmd.pmd-compat6.it - cpd-for-csharp - 1.0-SNAPSHOT - - - 11 - 11 - UTF-8 - - - - - - org.apache.maven.plugins - maven-pmd-plugin - @maven-pmd-plugin.version.for.integrationtest@ - - - csharp-cpd-check - - cpd-check - - - - - cs - 10 - - **/*.cs - - - ${basedir}/src/main/cs - - true - false - - - - net.sourceforge.pmd - pmd-compat6 - @project.version@ - - - net.sourceforge.pmd - pmd-core - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-java - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-javascript - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-jsp - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-cs - @pmd.version.for.integrationtest@ - - - - - - diff --git a/pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings1.cs b/pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings1.cs deleted file mode 100644 index b36845bb8a..0000000000 --- a/pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings1.cs +++ /dev/null @@ -1,12 +0,0 @@ -class Foo { - void bar() { - - var test = $@"test"; - var test2 = @$"test"; - - String query = - @"SELECT foo, bar - FROM table - WHERE id = 42"; - } -} diff --git a/pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings2.cs b/pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings2.cs deleted file mode 100644 index b36845bb8a..0000000000 --- a/pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings2.cs +++ /dev/null @@ -1,12 +0,0 @@ -class Foo { - void bar() { - - var test = $@"test"; - var test2 = @$"test"; - - String query = - @"SELECT foo, bar - FROM table - WHERE id = 42"; - } -} diff --git a/pmd-compat6/src/it/cpd-for-csharp/verify.bsh b/pmd-compat6/src/it/cpd-for-csharp/verify.bsh deleted file mode 100644 index f5db9350bd..0000000000 --- a/pmd-compat6/src/it/cpd-for-csharp/verify.bsh +++ /dev/null @@ -1,46 +0,0 @@ -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; - -String readFile(File file) throws IOException { - StringBuilder content = new StringBuilder(); - for (String line : Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)) { - content.append(line).append(System.lineSeparator()); - } - return content.toString(); -} - -File buildLogPath = new File(basedir, "build.log"); -String buildLog = readFile(buildLogPath); -if (buildLog.contains("An API incompatibility was encountered while")) { - throw new RuntimeException("Executing failed due to API incompatibility"); -} - -if (!buildLog.contains("[INFO] CPD Failure: Found 12 lines of duplicated code at locations:")) { - throw new RuntimeException("No CPD failures detected, did CPD run?"); -} -File classA = new File("cpd-for-csharp/src/main/cs/strings1.cs"); -if (!buildLog.contains(classA + " line 1")) { - throw new RuntimeException("No CPD failures detected, did CPD run?"); -} -File classB = new File("cpd-for-csharp/src/main/cs/strings2.cs"); -if (!buildLog.contains(classA + " line 1")) { - throw new RuntimeException("No CPD failures detected, did CPD run?"); -} - -File cpdXmlReport = new File(basedir, "target/cpd.xml"); -if (!cpdXmlReport.exists()) { - throw new FileNotFoundException("Could not find cpd xml report: " + cpdXmlReport); -} -String cpdXml = readFile(cpdXmlReport); -if (!cpdXml.contains("")) { - throw new RuntimeException("Expected duplication has not been reported"); -} -if (!cpdXml.contains(classA + "\"/>")) { - throw new RuntimeException("Expected duplication has not been reported"); -} -if (!cpdXml.contains(classB + "\"/>")) { - throw new RuntimeException("Expected duplication has not been reported"); -} diff --git a/pmd-compat6/src/it/cpd-for-java/invoker.properties b/pmd-compat6/src/it/cpd-for-java/invoker.properties deleted file mode 100644 index a6149b5b14..0000000000 --- a/pmd-compat6/src/it/cpd-for-java/invoker.properties +++ /dev/null @@ -1,4 +0,0 @@ -invoker.goals.1 = verify -invoker.goals.2 = pmd:cpd-check -Dformat=csv -invoker.goals.3 = pmd:cpd-check -Dformat=txt -invoker.buildResult = failure diff --git a/pmd-compat6/src/it/cpd-for-java/pom.xml b/pmd-compat6/src/it/cpd-for-java/pom.xml deleted file mode 100644 index 285c37467b..0000000000 --- a/pmd-compat6/src/it/cpd-for-java/pom.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - 4.0.0 - - net.sourceforge.pmd.pmd-compat6.it - cpd-for-java - 1.0-SNAPSHOT - - - 11 - 11 - UTF-8 - - - - - - org.apache.maven.plugins - maven-pmd-plugin - @maven-pmd-plugin.version.for.integrationtest@ - - - java-cpd-check - - cpd-check - - - - - true - false - 5 - - - - net.sourceforge.pmd - pmd-compat6 - @project.version@ - - - net.sourceforge.pmd - pmd-core - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-java - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-javascript - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-jsp - @pmd.version.for.integrationtest@ - - - - - - diff --git a/pmd-compat6/src/it/cpd-for-java/src/main/java/org/example/ClassA.java b/pmd-compat6/src/it/cpd-for-java/src/main/java/org/example/ClassA.java deleted file mode 100644 index 3df3dde7d9..0000000000 --- a/pmd-compat6/src/it/cpd-for-java/src/main/java/org/example/ClassA.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.example; - -public class ClassA { - public int method1(int a, int b, int c) { - int d = (a + b + c + 1) * 10; - int e = (a + b + c - 1) * 5; - int f = (a + b + c); - return d * e * f + d + e + f; - } -} diff --git a/pmd-compat6/src/it/cpd-for-java/src/main/java/org/example/ClassB.java b/pmd-compat6/src/it/cpd-for-java/src/main/java/org/example/ClassB.java deleted file mode 100644 index 994e917441..0000000000 --- a/pmd-compat6/src/it/cpd-for-java/src/main/java/org/example/ClassB.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.example; - -public class ClassB { - public int method1(int a, int b, int c) { - int d = (a + b + c + 1) * 10; - int e = (a + b + c - 1) * 5; - int f = (a + b + c); - return d * e * f + d + e + f; - } -} diff --git a/pmd-compat6/src/it/cpd-for-java/verify.bsh b/pmd-compat6/src/it/cpd-for-java/verify.bsh deleted file mode 100644 index 8eaad55526..0000000000 --- a/pmd-compat6/src/it/cpd-for-java/verify.bsh +++ /dev/null @@ -1,62 +0,0 @@ -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; - -String readFile(File file) throws IOException { - StringBuilder content = new StringBuilder(); - for (String line : Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)) { - content.append(line).append(System.lineSeparator()); - } - return content.toString(); -} - -File buildLogPath = new File(basedir, "build.log"); -String buildLog = readFile(buildLogPath); -if (buildLog.contains("An API incompatibility was encountered while")) { - throw new RuntimeException("Executing failed due to API incompatibility"); -} -if (!buildLog.contains("[INFO] CPD Failure: Found 8 lines of duplicated code at locations:")) { - throw new RuntimeException("No CPD failures detected, did CPD run?"); -} -File classA = new File("cpd-for-java/src/main/java/org/example/ClassA.java"); -if (!buildLog.contains(classA + " line 3")) { - throw new RuntimeException("No CPD failures detected, did CPD run?"); -} - -File cpdXmlReport = new File(basedir, "target/cpd.xml"); -if (!cpdXmlReport.exists()) { - throw new FileNotFoundException("Could not find cpd xml report: " + cpdXmlReport); -} -String cpdXml = readFile(cpdXmlReport); -if (!cpdXml.contains("")) { - throw new RuntimeException("Expected duplication has not been reported"); -} -if (!cpdXml.contains(classA + "\"/>")) { - throw new RuntimeException("Expected duplication has not been reported"); -} - -File csvReport = new File(basedir, "target/cpd.csv"); -if (!csvReport.exists()) { - throw new FileNotFoundException("Could not find cpd csv report: " + csvReport); -} -String csv = readFile(csvReport); -if (!csv.contains("8,67,2,3,")) { - throw new RuntimeException("Expected duplication in CSV has not been reported"); -} -if (!csv.contains(classA + ",")) { - throw new RuntimeException("Expected duplication in CSV has not been reported"); -} - -File textReport = new File(basedir, "target/cpd.txt"); -if (!textReport.exists()) { - throw new FileNotFoundException("Could not find cpd text report: " + textReport); -} -String text = readFile(textReport); -if (!text.contains("Found a 8 line (67 tokens) duplication in the following files:")) { - throw new RuntimeException("Expected duplication in TXT has not been reported"); -} -if (!text.contains("Starting at line 3 of ") && !text.contains(classA.toString())) { - throw new RuntimeException("Expected duplication in TXT has not been reported"); -} diff --git a/pmd-compat6/src/it/cpd-for-javascript/invoker.properties b/pmd-compat6/src/it/cpd-for-javascript/invoker.properties deleted file mode 100644 index 0d92d959f3..0000000000 --- a/pmd-compat6/src/it/cpd-for-javascript/invoker.properties +++ /dev/null @@ -1,2 +0,0 @@ -invoker.goals = verify -invoker.buildResult = failure diff --git a/pmd-compat6/src/it/cpd-for-javascript/pom.xml b/pmd-compat6/src/it/cpd-for-javascript/pom.xml deleted file mode 100644 index a252b32a34..0000000000 --- a/pmd-compat6/src/it/cpd-for-javascript/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - 4.0.0 - - net.sourceforge.pmd.pmd-compat6.it - cpd-for-javascript - 1.0-SNAPSHOT - - - UTF-8 - - - - - - org.apache.maven.plugins - maven-pmd-plugin - @maven-pmd-plugin.version.for.integrationtest@ - - - javascript-cpd-check - - cpd-check - - - - - true - false - 5 - javascript - - /category/ecmascript/bestpractices.xml - - - **/*.js - - - ${basedir}/src/main/js - - - - - net.sourceforge.pmd - pmd-compat6 - @project.version@ - - - net.sourceforge.pmd - pmd-core - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-java - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-javascript - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-jsp - @pmd.version.for.integrationtest@ - - - - - - diff --git a/pmd-compat6/src/it/cpd-for-javascript/src/main/js/globalVariable.js b/pmd-compat6/src/it/cpd-for-javascript/src/main/js/globalVariable.js deleted file mode 100644 index d9c86cf398..0000000000 --- a/pmd-compat6/src/it/cpd-for-javascript/src/main/js/globalVariable.js +++ /dev/null @@ -1,7 +0,0 @@ -function(arg) { - notDeclaredVariable = 1; // this will create a global variable and trigger the rule - - var someVar = 1; // this is a local variable, that's ok - - window.otherGlobal = 2; // this will not trigger the rule, although it is a global variable. -} diff --git a/pmd-compat6/src/it/cpd-for-javascript/src/main/js/globalVariable2.js b/pmd-compat6/src/it/cpd-for-javascript/src/main/js/globalVariable2.js deleted file mode 100644 index d9c86cf398..0000000000 --- a/pmd-compat6/src/it/cpd-for-javascript/src/main/js/globalVariable2.js +++ /dev/null @@ -1,7 +0,0 @@ -function(arg) { - notDeclaredVariable = 1; // this will create a global variable and trigger the rule - - var someVar = 1; // this is a local variable, that's ok - - window.otherGlobal = 2; // this will not trigger the rule, although it is a global variable. -} diff --git a/pmd-compat6/src/it/cpd-for-javascript/verify.bsh b/pmd-compat6/src/it/cpd-for-javascript/verify.bsh deleted file mode 100644 index e31d6be8ee..0000000000 --- a/pmd-compat6/src/it/cpd-for-javascript/verify.bsh +++ /dev/null @@ -1,36 +0,0 @@ -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; - -String readFile(File file) throws IOException { - StringBuilder content = new StringBuilder(); - for (String line : Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)) { - content.append(line).append(System.lineSeparator()); - } - return content.toString(); -} - -File buildLogPath = new File(basedir, "build.log"); -String buildLog = readFile(buildLogPath); -if (!buildLog.contains("[INFO] CPD Failure: Found 7 lines of duplicated code at locations:")) { - throw new RuntimeException("No CPD failures detected, did CPD run?"); -} -File globalVariable = new File("cpd-for-javascript/src/main/js/globalVariable.js"); -if (!buildLog.contains(globalVariable + " line 1")) { - throw new RuntimeException("No CPD failures detected, did CPD run?"); -} - -File cpdXmlReport = new File(basedir, "target/cpd.xml"); -if(!cpdXmlReport.exists()) -{ - throw new FileNotFoundException("Could not find cpd xml report: " + cpdXmlReport); -} -String cpdXml = readFile(cpdXmlReport); -if (!cpdXml.contains("")) { - throw new RuntimeException("Expected duplication has not been reported"); -} -if (!cpdXml.contains(globalVariable + "\"/>")) { - throw new RuntimeException("Expected duplication has not been reported"); -} diff --git a/pmd-compat6/src/it/cpd-for-jsp/invoker.properties b/pmd-compat6/src/it/cpd-for-jsp/invoker.properties deleted file mode 100644 index 0d92d959f3..0000000000 --- a/pmd-compat6/src/it/cpd-for-jsp/invoker.properties +++ /dev/null @@ -1,2 +0,0 @@ -invoker.goals = verify -invoker.buildResult = failure diff --git a/pmd-compat6/src/it/cpd-for-jsp/pom.xml b/pmd-compat6/src/it/cpd-for-jsp/pom.xml deleted file mode 100644 index 1726d641d5..0000000000 --- a/pmd-compat6/src/it/cpd-for-jsp/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - 4.0.0 - - net.sourceforge.pmd.pmd-compat6.it - cpd-for-jsp - 1.0-SNAPSHOT - - - UTF-8 - - - - - - org.apache.maven.plugins - maven-pmd-plugin - @maven-pmd-plugin.version.for.integrationtest@ - - - jsp-cpd-check - - cpd-check - - - - - true - false - 5 - jsp - - /category/jsp/bestpractices.xml - - - **/*.jsp - - - ${basedir}/src/main/jsp - - - - - net.sourceforge.pmd - pmd-compat6 - @project.version@ - - - net.sourceforge.pmd - pmd-core - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-java - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-javascript - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-jsp - @pmd.version.for.integrationtest@ - - - - - - diff --git a/pmd-compat6/src/it/cpd-for-jsp/src/main/jsp/classAttribute.jsp b/pmd-compat6/src/it/cpd-for-jsp/src/main/jsp/classAttribute.jsp deleted file mode 100644 index c86ca5aa9c..0000000000 --- a/pmd-compat6/src/it/cpd-for-jsp/src/main/jsp/classAttribute.jsp +++ /dev/null @@ -1,3 +0,0 @@ - -

Some text

- diff --git a/pmd-compat6/src/it/cpd-for-jsp/src/main/jsp/classAttribute2.jsp b/pmd-compat6/src/it/cpd-for-jsp/src/main/jsp/classAttribute2.jsp deleted file mode 100644 index c86ca5aa9c..0000000000 --- a/pmd-compat6/src/it/cpd-for-jsp/src/main/jsp/classAttribute2.jsp +++ /dev/null @@ -1,3 +0,0 @@ - -

Some text

- diff --git a/pmd-compat6/src/it/cpd-for-jsp/verify.bsh b/pmd-compat6/src/it/cpd-for-jsp/verify.bsh deleted file mode 100644 index 17420241fe..0000000000 --- a/pmd-compat6/src/it/cpd-for-jsp/verify.bsh +++ /dev/null @@ -1,36 +0,0 @@ -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; - -String readFile(File file) throws IOException { - StringBuilder content = new StringBuilder(); - for (String line : Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)) { - content.append(line).append(System.lineSeparator()); - } - return content.toString(); -} - -File buildLogPath = new File(basedir, "build.log"); -String buildLog = readFile(buildLogPath); -if (!buildLog.contains("[INFO] CPD Failure: Found 3 lines of duplicated code at locations:")) { - throw new RuntimeException("No CPD failures detected, did CPD run?"); -} -File classAttribute = new File("cpd-for-jsp/src/main/jsp/classAttribute.jsp"); -if (!buildLog.contains(classAttribute + " line 1")) { - throw new RuntimeException("No CPD failures detected, did CPD run?"); -} - -File cpdXmlReport = new File(basedir, "target/cpd.xml"); -if(!cpdXmlReport.exists()) -{ - throw new FileNotFoundException("Could not find cpd xml report: " + cpdXmlReport); -} -String cpdXml = readFile(cpdXmlReport); -if (!cpdXml.contains("")) { - throw new RuntimeException("Expected duplication has not been reported"); -} -if (!cpdXml.contains(classAttribute + "\"/>")) { - throw new RuntimeException("Expected duplication has not been reported"); -} diff --git a/pmd-compat6/src/it/pmd-for-java/config_error_ruleset.xml b/pmd-compat6/src/it/pmd-for-java/config_error_ruleset.xml deleted file mode 100644 index 1d646a3073..0000000000 --- a/pmd-compat6/src/it/pmd-for-java/config_error_ruleset.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/pmd-compat6/src/it/pmd-for-java/exception_ruleset.xml b/pmd-compat6/src/it/pmd-for-java/exception_ruleset.xml deleted file mode 100644 index bd7427e5a8..0000000000 --- a/pmd-compat6/src/it/pmd-for-java/exception_ruleset.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - Use this rule to produce a processing error. - 3 - - - - - - - diff --git a/pmd-compat6/src/it/pmd-for-java/invoker.properties b/pmd-compat6/src/it/pmd-for-java/invoker.properties deleted file mode 100644 index d03166a079..0000000000 --- a/pmd-compat6/src/it/pmd-for-java/invoker.properties +++ /dev/null @@ -1,4 +0,0 @@ -invoker.goals.1 = verify -e -invoker.goals.2 = pmd:check -Dformat=csv -invoker.goals.3 = pmd:check -Dformat=txt -invoker.buildResult = failure diff --git a/pmd-compat6/src/it/pmd-for-java/pom.xml b/pmd-compat6/src/it/pmd-for-java/pom.xml deleted file mode 100644 index 13f0485c6f..0000000000 --- a/pmd-compat6/src/it/pmd-for-java/pom.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - 4.0.0 - - net.sourceforge.pmd.pmd-compat6.it - pmd-for-java - 1.0-SNAPSHOT - - - 11 - 11 - UTF-8 - - - - - - org.apache.maven.plugins - maven-pmd-plugin - @maven-pmd-plugin.version.for.integrationtest@ - - - java-check - - check - - - - - true - true - 5 - true - - /rulesets/java/maven-pmd-plugin-default.xml - ${project.basedir}/exception_ruleset.xml - ${project.basedir}/config_error_ruleset.xml - - - - - net.sourceforge.pmd - pmd-compat6 - @project.version@ - - - net.sourceforge.pmd - pmd-core - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-java - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-javascript - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-jsp - @pmd.version.for.integrationtest@ - - - - - - diff --git a/pmd-compat6/src/it/pmd-for-java/src/main/java/org/example/Main.java b/pmd-compat6/src/it/pmd-for-java/src/main/java/org/example/Main.java deleted file mode 100644 index 8b4ddb6e37..0000000000 --- a/pmd-compat6/src/it/pmd-for-java/src/main/java/org/example/Main.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.example; - -public class Main { - public static void main(String[] args) { - String thisIsAUnusedLocalVar = "a"; - System.out.println("Hello world!"); - - String thisIsASuppressedUnusedLocalVar = "b"; // NOPMD suppressed - } -} diff --git a/pmd-compat6/src/it/pmd-for-java/verify.bsh b/pmd-compat6/src/it/pmd-for-java/verify.bsh deleted file mode 100644 index 5e813cab8b..0000000000 --- a/pmd-compat6/src/it/pmd-for-java/verify.bsh +++ /dev/null @@ -1,59 +0,0 @@ -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; - -String readFile(File file) throws IOException { - StringBuilder content = new StringBuilder(); - for (String line : Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)) { - content.append(line).append(System.lineSeparator()); - } - return content.toString(); -} - -File buildLogPath = new File(basedir, "build.log"); -String buildLog = readFile(buildLogPath); -if (buildLog.contains("An API incompatibility was encountered while")) { - throw new RuntimeException("Executing failed due to API incompatibility"); -} -if (!buildLog.contains("[INFO] PMD Failure: org.example.Main:5 Rule:UnusedLocalVariable")) { - throw new RuntimeException("No pmd violation detected, did PMD run?"); -} - -File pmdXmlReport = new File(basedir, "target/pmd.xml"); -if(!pmdXmlReport.exists()) { - throw new FileNotFoundException("Could not find pmd xml report: " + pmdXmlReport); -} -String pmdXml = readFile(pmdXmlReport); -if (!pmdXml.contains("")) { - throw new RuntimeException("Expected violation has not been reported"); -} -if (!pmdXml.contains("")) { - throw new RuntimeException("Configuration error has not been reported"); -} - -File pmdCsvReport = new File(basedir, "target/pmd.csv"); -if (!pmdCsvReport.exists()) { - throw new FileNotFoundException("Could not find pmd CSV report: " + pmdCsvReport); -} -String csvReport = readFile(pmdCsvReport); -if (!csvReport.contains(mainFile + "\",\"3\",\"5\",\"Avoid unused local")) { - throw new RuntimeException("Expected violation has not been reported in CSV"); -} - -File pmdTextReport = new File(basedir, "target/pmd.txt"); -if (!pmdTextReport.exists()) { - throw new FileNotFoundException("Could not find pmd TXT report: " + pmdTextReport); -} -String textReport = readFile(pmdTextReport); -if (!textReport.contains(mainFile + ":5:\tUnusedLocalVariable")) { - throw new RuntimeException("Expected violation has not been reported in TXT"); -} diff --git a/pmd-compat6/src/it/pmd-for-javascript/invoker.properties b/pmd-compat6/src/it/pmd-for-javascript/invoker.properties deleted file mode 100644 index 0d92d959f3..0000000000 --- a/pmd-compat6/src/it/pmd-for-javascript/invoker.properties +++ /dev/null @@ -1,2 +0,0 @@ -invoker.goals = verify -invoker.buildResult = failure diff --git a/pmd-compat6/src/it/pmd-for-javascript/pom.xml b/pmd-compat6/src/it/pmd-for-javascript/pom.xml deleted file mode 100644 index e1fd383e42..0000000000 --- a/pmd-compat6/src/it/pmd-for-javascript/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - 4.0.0 - - net.sourceforge.pmd.pmd-compat6.it - pmd-for-javascript - 1.0-SNAPSHOT - - - UTF-8 - - - - - - org.apache.maven.plugins - maven-pmd-plugin - @maven-pmd-plugin.version.for.integrationtest@ - - - javascript-check - - check - - - - - true - false - 5 - javascript - - /category/ecmascript/bestpractices.xml - - - **/*.js - - - ${basedir}/src/main/js - - - - - net.sourceforge.pmd - pmd-compat6 - @project.version@ - - - net.sourceforge.pmd - pmd-core - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-java - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-javascript - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-jsp - @pmd.version.for.integrationtest@ - - - - - - diff --git a/pmd-compat6/src/it/pmd-for-javascript/src/main/js/globalVariable.js b/pmd-compat6/src/it/pmd-for-javascript/src/main/js/globalVariable.js deleted file mode 100644 index d9c86cf398..0000000000 --- a/pmd-compat6/src/it/pmd-for-javascript/src/main/js/globalVariable.js +++ /dev/null @@ -1,7 +0,0 @@ -function(arg) { - notDeclaredVariable = 1; // this will create a global variable and trigger the rule - - var someVar = 1; // this is a local variable, that's ok - - window.otherGlobal = 2; // this will not trigger the rule, although it is a global variable. -} diff --git a/pmd-compat6/src/it/pmd-for-javascript/verify.bsh b/pmd-compat6/src/it/pmd-for-javascript/verify.bsh deleted file mode 100644 index 0d190f5f00..0000000000 --- a/pmd-compat6/src/it/pmd-for-javascript/verify.bsh +++ /dev/null @@ -1,33 +0,0 @@ -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; - -String readFile(File file) throws IOException { - StringBuilder content = new StringBuilder(); - for (String line : Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)) { - content.append(line).append(System.lineSeparator()); - } - return content.toString(); -} - -File buildLogPath = new File(basedir, "build.log"); -String buildLog = readFile(buildLogPath); -if (!buildLog.contains("[INFO] PMD Failure: globalVariable.js:2 Rule:GlobalVariable")) { - throw new RuntimeException("No pmd violation detected, did PMD run?"); -} - -File pmdXmlReport = new File(basedir, "target/pmd.xml"); -if(!pmdXmlReport.exists()) -{ - throw new FileNotFoundException("Could not find pmd xml report: " + pmdXmlReport); -} -String pmdXml = readFile(pmdXmlReport); -if (!pmdXml.contains("")) { - throw new RuntimeException("Expected violation has not been reported"); -} diff --git a/pmd-compat6/src/it/pmd-for-jsp/invoker.properties b/pmd-compat6/src/it/pmd-for-jsp/invoker.properties deleted file mode 100644 index 0d92d959f3..0000000000 --- a/pmd-compat6/src/it/pmd-for-jsp/invoker.properties +++ /dev/null @@ -1,2 +0,0 @@ -invoker.goals = verify -invoker.buildResult = failure diff --git a/pmd-compat6/src/it/pmd-for-jsp/pom.xml b/pmd-compat6/src/it/pmd-for-jsp/pom.xml deleted file mode 100644 index 3784e88e69..0000000000 --- a/pmd-compat6/src/it/pmd-for-jsp/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - 4.0.0 - - net.sourceforge.pmd.pmd-compat6.it - pmd-for-jsp - 1.0-SNAPSHOT - - - UTF-8 - - - - - - org.apache.maven.plugins - maven-pmd-plugin - @maven-pmd-plugin.version.for.integrationtest@ - - - jsp-check - - check - - - - - true - false - 5 - jsp - - /category/jsp/bestpractices.xml - - - **/*.jsp - - - ${basedir}/src/main/jsp - - - - - net.sourceforge.pmd - pmd-compat6 - @project.version@ - - - net.sourceforge.pmd - pmd-core - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-java - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-javascript - @pmd.version.for.integrationtest@ - - - net.sourceforge.pmd - pmd-jsp - @pmd.version.for.integrationtest@ - - - - - - diff --git a/pmd-compat6/src/it/pmd-for-jsp/src/main/jsp/classAttribute.jsp b/pmd-compat6/src/it/pmd-for-jsp/src/main/jsp/classAttribute.jsp deleted file mode 100644 index c86ca5aa9c..0000000000 --- a/pmd-compat6/src/it/pmd-for-jsp/src/main/jsp/classAttribute.jsp +++ /dev/null @@ -1,3 +0,0 @@ - -

Some text

- diff --git a/pmd-compat6/src/it/pmd-for-jsp/verify.bsh b/pmd-compat6/src/it/pmd-for-jsp/verify.bsh deleted file mode 100644 index 55f734081e..0000000000 --- a/pmd-compat6/src/it/pmd-for-jsp/verify.bsh +++ /dev/null @@ -1,33 +0,0 @@ -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; - -String readFile(File file) throws IOException { - StringBuilder content = new StringBuilder(); - for (String line : Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)) { - content.append(line).append(System.lineSeparator()); - } - return content.toString(); -} - -File buildLogPath = new File(basedir, "build.log"); -String buildLog = readFile(buildLogPath); -if (!buildLog.contains("[INFO] PMD Failure: classAttribute.jsp:2 Rule:NoClassAttribute")) { - throw new RuntimeException("No pmd violation detected, did PMD run?"); -} - -File pmdXmlReport = new File(basedir, "target/pmd.xml"); -if(!pmdXmlReport.exists()) -{ - throw new FileNotFoundException("Could not find pmd xml report: " + pmdXmlReport); -} -String pmdXml = readFile(pmdXmlReport); -if (!pmdXml.contains("")) { - throw new RuntimeException("Expected violation has not been reported"); -} diff --git a/pmd-compat6/src/it/settings.xml b/pmd-compat6/src/it/settings.xml deleted file mode 100644 index b7724658de..0000000000 --- a/pmd-compat6/src/it/settings.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - it-repo - - - local.central - @localRepositoryUrl@ - - true - - - true - - - - - - local.central - @localRepositoryUrl@ - - true - - - true - - - - - - - it-repo - - diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/PMDConfiguration.java deleted file mode 100644 index 57aaaa39aa..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ /dev/null @@ -1,606 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: -// - setSourceEncoding -// - setBenchmark (non-functional) -// - getMinimumPriority - -package net.sourceforge.pmd; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.nio.charset.Charset; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Properties; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.slf4j.LoggerFactory; - -import net.sourceforge.pmd.annotation.DeprecatedUntil700; -import net.sourceforge.pmd.cache.internal.AnalysisCache; -import net.sourceforge.pmd.cache.internal.FileAnalysisCache; -import net.sourceforge.pmd.cache.internal.NoopAnalysisCache; -import net.sourceforge.pmd.internal.util.ClasspathClassLoader; -import net.sourceforge.pmd.lang.Language; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersion; -import net.sourceforge.pmd.lang.rule.RuleSetLoader; -import net.sourceforge.pmd.renderers.Renderer; -import net.sourceforge.pmd.renderers.RendererFactory; -import net.sourceforge.pmd.util.AssertionUtil; -import net.sourceforge.pmd.util.log.internal.SimpleMessageReporter; - -/** - * This class contains the details for the runtime configuration of a - * PMD run. Once configured, use {@link PmdAnalysis#create(PMDConfiguration)} - * in a try-with-resources to execute the analysis (see {@link PmdAnalysis}). - * - *

Rulesets

- * - *
    - *
  • You can configure paths to the rulesets to use with {@link #addRuleSet(String)}. - * These can be file paths or classpath resources.
  • - *
  • Use {@link #setMinimumPriority(RulePriority)} to control the minimum priority a - * rule must have to be included. Defaults to the lowest priority, ie all rules are loaded.
  • - *
  • Use {@link #setRuleSetFactoryCompatibilityEnabled(boolean)} to disable the - * compatibility measures for removed and renamed rules in the rulesets that will - * be loaded. - *
- * - *

Source files

- * - *
    - *
  • The default encoding of source files is the system default as - * returned by System.getProperty("file.encoding"). - * You can set it with {@link #setSourceEncoding(Charset)}.
  • - *
  • The source files to analyze can be given in many ways. See - * {@link #addInputPath(Path)} {@link #setInputFilePath(Path)}, {@link #setInputUri(URI)}. - *
  • Files are assigned a language based on their name. The language - * version of languages can be given with - * {@link #setDefaultLanguageVersion(LanguageVersion)}. - * The default language assignment can be overridden with - * {@link #setForceLanguageVersion(LanguageVersion)}.
  • - *
- * - *

Rendering

- * - *
    - *
  • The renderer format to use for Reports. {@link #getReportFormat()}
  • - *
  • The file to which the Report should render. {@link #getReportFile()}
  • - *
  • Configure the root paths that are used to relativize file names in reports via {@link #addRelativizeRoot(Path)}. - * This enables to get short names in reports.
  • - *
  • The initialization properties to use when creating a Renderer instance. - * {@link #getReportProperties()}
  • - *
  • An indicator of whether to show suppressed Rule violations in Reports. - * {@link #isShowSuppressedViolations()}
  • - *
- * - *

Language configuration

- *
    - *
  • Use {@link #setSuppressMarker(String)} to change the comment marker for suppression comments. Defaults to {@value #DEFAULT_SUPPRESS_MARKER}.
  • - *
  • See {@link #setClassLoader(ClassLoader)} and {@link #prependAuxClasspath(String)} for - * information for how to configure classpath for Java analysis.
  • - *
  • You can set additional language properties with {@link #getLanguageProperties(Language)}
  • - *
- * - *

Miscellaneous

- *
    - *
  • Use {@link #setThreads(int)} to control the parallelism of the analysis. Defaults - * one thread per available processor. {@link #getThreads()}
  • - *
- */ -public class PMDConfiguration extends AbstractConfiguration { - private static final LanguageRegistry DEFAULT_REGISTRY = LanguageRegistry.PMD; - - /** The default suppress marker string. */ - public static final String DEFAULT_SUPPRESS_MARKER = "NOPMD"; - private Path reportFile; - - // General behavior options - private String suppressMarker = DEFAULT_SUPPRESS_MARKER; - private int threads = Runtime.getRuntime().availableProcessors(); - private ClassLoader classLoader = getClass().getClassLoader(); - - // Rule and source file options - private List ruleSets = new ArrayList<>(); - private RulePriority minimumPriority = RulePriority.LOW; - private boolean ruleSetFactoryCompatibilityEnabled = true; - - // Reporting options - private String reportFormat; - private Properties reportProperties = new Properties(); - private boolean showSuppressedViolations = false; - private boolean failOnViolation = true; - - private AnalysisCache analysisCache = new NoopAnalysisCache(); - private boolean ignoreIncrementalAnalysis; - - public PMDConfiguration() { - this(DEFAULT_REGISTRY); - } - - public PMDConfiguration(@NonNull LanguageRegistry languageRegistry) { - super(languageRegistry, new SimpleMessageReporter(LoggerFactory.getLogger(PmdAnalysis.class))); - } - - /** - * Get the suppress marker. This is the source level marker used to indicate - * a RuleViolation should be suppressed. - * - * @return The suppress marker. - */ - public String getSuppressMarker() { - return suppressMarker; - } - - /** - * Set the suppress marker. - * - * @param suppressMarker - * The suppress marker to use. - */ - public void setSuppressMarker(String suppressMarker) { - Objects.requireNonNull(suppressMarker, "Suppress marker was null"); - this.suppressMarker = suppressMarker; - } - - /** - * Get the number of threads to use when processing Rules. - * - * @return The number of threads. - */ - public int getThreads() { - return threads; - } - - /** - * Set the number of threads to use when processing Rules. - * - * @param threads - * The number of threads. - */ - public void setThreads(int threads) { - this.threads = threads; - } - - /** - * Get the ClassLoader being used by PMD when processing Rules. - * - * @return The ClassLoader being used - */ - public ClassLoader getClassLoader() { - return classLoader; - } - - /** - * Set the ClassLoader being used by PMD when processing Rules. Setting a - * value of null will cause the default ClassLoader to be used. - * - * @param classLoader - * The ClassLoader to use - */ - public void setClassLoader(ClassLoader classLoader) { - if (classLoader == null) { - this.classLoader = getClass().getClassLoader(); - } else { - this.classLoader = classLoader; - } - } - - /** - * Prepend the specified classpath like string to the current ClassLoader of - * the configuration. If no ClassLoader is currently configured, the - * ClassLoader used to load the {@link PMDConfiguration} class will be used - * as the parent ClassLoader of the created ClassLoader. - * - *

If the classpath String looks like a URL to a file (i.e. starts with - * file://) the file will be read with each line representing - * an entry on the classpath.

- * - * @param classpath - * The prepended classpath. - * @throws IOException - * if the given classpath is invalid (e.g. does not exist) - * @see PMDConfiguration#setClassLoader(ClassLoader) - * @see ClasspathClassLoader - * - * @deprecated Use {@link #prependAuxClasspath(String)}, which doesn't - * throw a checked {@link IOException} - */ - @Deprecated - public void prependClasspath(String classpath) throws IOException { - try { - prependAuxClasspath(classpath); - } catch (IllegalArgumentException e) { - throw new IOException(e); - } - } - - /** - * Prepend the specified classpath like string to the current ClassLoader of - * the configuration. If no ClassLoader is currently configured, the - * ClassLoader used to load the {@link PMDConfiguration} class will be used - * as the parent ClassLoader of the created ClassLoader. - * - *

If the classpath String looks like a URL to a file (i.e. starts with - * file://) the file will be read with each line representing - * an entry on the classpath.

- * - *

You can specify multiple class paths separated by `:` on Unix-systems or `;` under Windows. - * See {@link File#pathSeparator}. - * - * @param classpath The prepended classpath. - * - * @throws IllegalArgumentException if the given classpath is invalid (e.g. does not exist) - * @see PMDConfiguration#setClassLoader(ClassLoader) - */ - public void prependAuxClasspath(String classpath) { - try { - if (classLoader == null) { - classLoader = PMDConfiguration.class.getClassLoader(); - } - if (classpath != null) { - classLoader = new ClasspathClassLoader(classpath, classLoader); - } - } catch (IOException e) { - // Note: IOExceptions shouldn't appear anymore, they should already be converted - // to IllegalArgumentException in ClasspathClassLoader. - throw new IllegalArgumentException(e); - } - } - - /** - * Get the comma separated list of RuleSet URIs. - * - * @return The RuleSet URIs. - * - * @deprecated Use {@link #getRuleSetPaths()} - */ - @Deprecated - @DeprecatedUntil700 - public @Nullable String getRuleSets() { - if (ruleSets.isEmpty()) { - return null; - } - return String.join(",", ruleSets); - } - - /** - * Returns the list of ruleset URIs. - * - * @see RuleSetLoader#loadFromResource(String) - */ - public @NonNull List<@NonNull String> getRuleSetPaths() { - return ruleSets; - } - - /** - * Sets the list of ruleset paths to load when starting the analysis. - * - * @param ruleSetPaths A list of ruleset paths, understandable by {@link RuleSetLoader#loadFromResource(String)}. - * - * @throws NullPointerException If the parameter is null - */ - public void setRuleSets(@NonNull List<@NonNull String> ruleSetPaths) { - AssertionUtil.requireParamNotNull("ruleSetPaths", ruleSetPaths); - AssertionUtil.requireContainsNoNullValue("ruleSetPaths", ruleSetPaths); - this.ruleSets = new ArrayList<>(ruleSetPaths); - } - - /** - * Add a new ruleset paths to load when starting the analysis. - * This list is initially empty. - * - * @param rulesetPath A ruleset path, understandable by {@link RuleSetLoader#loadFromResource(String)}. - * - * @throws NullPointerException If the parameter is null - */ - public void addRuleSet(@NonNull String rulesetPath) { - AssertionUtil.requireParamNotNull("rulesetPath", rulesetPath); - this.ruleSets.add(rulesetPath); - } - - /** - * Set the comma separated list of RuleSet URIs. - * - * @param ruleSets the rulesets to set - * - * @deprecated Use {@link #setRuleSets(List)} or {@link #addRuleSet(String)}. - */ - @Deprecated - @DeprecatedUntil700 - public void setRuleSets(@Nullable String ruleSets) { - if (ruleSets == null) { - this.ruleSets = new ArrayList<>(); - } else { - this.ruleSets = new ArrayList<>(Arrays.asList(ruleSets.split(","))); - } - } - - /** - * Get the minimum priority threshold when loading Rules from RuleSets. - * - * @return The minimum priority threshold. - */ - public RulePriority getMinimumPriority() { - return minimumPriority; - } - - /** - * Set the minimum priority threshold when loading Rules from RuleSets. - * - * @param minimumPriority - * The minimum priority. - */ - public void setMinimumPriority(RulePriority minimumPriority) { - this.minimumPriority = minimumPriority; - } - - public void setMinimumPriority(net.sourceforge.pmd.lang.rule.RulePriority mininumPriority) { - this.minimumPriority = RulePriority.valueOf(mininumPriority.name()); - } - - /** - * Create a Renderer instance based upon the configured reporting options. - * No writer is created. - * - * @return renderer - */ - public Renderer createRenderer() { - return createRenderer(false); - } - - /** - * Create a Renderer instance based upon the configured reporting options. - * If withReportWriter then we'll configure it with a writer for the - * reportFile specified. - * - * @param withReportWriter - * whether to configure a writer or not - * @return A Renderer instance. - */ - public Renderer createRenderer(boolean withReportWriter) { - Renderer renderer = RendererFactory.createRenderer(reportFormat, reportProperties); - renderer.setShowSuppressedViolations(showSuppressedViolations); - if (withReportWriter) { - renderer.setReportFile(getReportFile()); - } - return renderer; - } - - /** - * Get the report format. - * - * @return The report format. - */ - public String getReportFormat() { - return reportFormat; - } - - /** - * Set the report format. This should be a name of a Renderer. - * - * @param reportFormat - * The report format. - * - * @see Renderer - */ - public void setReportFormat(String reportFormat) { - this.reportFormat = reportFormat; - } - - /** - * Get whether the report should show suppressed violations. - * - * @return true if showing suppressed violations, - * false otherwise. - */ - public boolean isShowSuppressedViolations() { - return showSuppressedViolations; - } - - /** - * Set whether the report should show suppressed violations. - * - * @param showSuppressedViolations - * true if showing suppressed violations, - * false otherwise. - */ - public void setShowSuppressedViolations(boolean showSuppressedViolations) { - this.showSuppressedViolations = showSuppressedViolations; - } - - /** - * Get the Report properties. These are used to create the Renderer. - * - * @return The report properties. - */ - public Properties getReportProperties() { - return reportProperties; - } - - /** - * Set the Report properties. These are used to create the Renderer. - * - * @param reportProperties - * The Report properties to set. - */ - public void setReportProperties(Properties reportProperties) { - this.reportProperties = reportProperties; - } - - /** - * Whether PMD should exit with status 4 (the default behavior, true) if - * violations are found or just with 0 (to not break the build, e.g.). - * - * @return failOnViolation - */ - @Override - public boolean isFailOnViolation() { - return failOnViolation; - } - - /** - * Sets whether PMD should exit with status 4 (the default behavior, true) - * if violations are found or just with 0 (to not break the build, e.g.). - * - * @param failOnViolation - * failOnViolation - */ - @Override - public void setFailOnViolation(boolean failOnViolation) { - this.failOnViolation = failOnViolation; - } - - /** - * Checks if the rule set factory compatibility feature is enabled. - * - * @return true, if the rule set factory compatibility feature is enabled - * - */ - public boolean isRuleSetFactoryCompatibilityEnabled() { - return ruleSetFactoryCompatibilityEnabled; - } - - /** - * Sets the rule set factory compatibility feature enabled/disabled. - * - * @param ruleSetFactoryCompatibilityEnabled {@code true} if the feature should be enabled - * - */ - public void setRuleSetFactoryCompatibilityEnabled(boolean ruleSetFactoryCompatibilityEnabled) { - this.ruleSetFactoryCompatibilityEnabled = ruleSetFactoryCompatibilityEnabled; - } - - /** - * Retrieves the currently used analysis cache. Will never be null. - * - * @return The currently used analysis cache. Never null. - */ - public AnalysisCache getAnalysisCache() { - // Make sure we are not null - if (analysisCache == null || isIgnoreIncrementalAnalysis() && !(analysisCache instanceof NoopAnalysisCache)) { - // sets a noop cache - setAnalysisCache(new NoopAnalysisCache()); - } - - return analysisCache; - } - - /** - * Sets the analysis cache to be used. Setting a - * value of {@code null} will cause a Noop AnalysisCache to be used. - * If incremental analysis was explicitly disabled ({@link #isIgnoreIncrementalAnalysis()}), - * then this method is a noop. - * - * @param cache The analysis cache to be used. - */ - public void setAnalysisCache(final AnalysisCache cache) { - // the doc says it's a noop if incremental analysis was disabled, - // but it's actually the getter that enforces that - this.analysisCache = cache == null ? new NoopAnalysisCache() : cache; - } - - /** - * Sets the location of the analysis cache to be used. This will automatically configure - * and appropriate AnalysisCache implementation. - * - * @param cacheLocation The location of the analysis cache to be used. - */ - public void setAnalysisCacheLocation(final String cacheLocation) { - setAnalysisCache(cacheLocation == null - ? new NoopAnalysisCache() - : new FileAnalysisCache(new File(cacheLocation))); - } - - - /** - * Sets whether the user has explicitly disabled incremental analysis or not. - * If so, incremental analysis is not used, and all suggestions to use it are - * disabled. The analysis cached location is ignored, even if it's specified. - * - * @param noCache Whether to ignore incremental analysis or not - */ - public void setIgnoreIncrementalAnalysis(boolean noCache) { - // see #getAnalysisCache for the implementation. - this.ignoreIncrementalAnalysis = noCache; - } - - - /** - * Returns whether incremental analysis was explicitly disabled by the user - * or not. - * - * @return {@code true} if incremental analysis is explicitly disabled - */ - public boolean isIgnoreIncrementalAnalysis() { - return ignoreIncrementalAnalysis; - } - - - /** - * Get the file to which the report should render. - * - * @return The file to which to render. - * @deprecated Use {@link #getReportFilePath()} - */ - @Deprecated - public String getReportFile() { - return reportFile == null ? null : reportFile.toString(); - } - - /** - * Get the file to which the report should render. - * - * @return The file to which to render. - */ - public Path getReportFilePath() { - return reportFile; - } - - /** - * Set the file to which the report should render. - * - * @param reportFile the file to set - * @deprecated Use {@link #setReportFile(Path)} - */ - @Deprecated - public void setReportFile(String reportFile) { - this.reportFile = reportFile == null ? null : Paths.get(reportFile); - } - - /** - * Set the file to which the report should render. - * - * @param reportFile the file to set - */ - public void setReportFile(Path reportFile) { - this.reportFile = reportFile; - } - - // ------------------- compat extensions -------------------- - @Deprecated - public void setSourceEncoding(String sourceEncoding) { - setSourceEncoding(Charset.forName(Objects.requireNonNull(sourceEncoding))); - } - - @Deprecated - public void setBenchmark(boolean benchmark) { - // ignored - } - - // new method to be compatible with PMD 7 - RulePriority has changed package - public net.sourceforge.pmd.lang.rule.RulePriority getMinimumPriority$$bridge() { // SUPPRESS CHECKSTYLE ignore - return minimumPriority.asPMD7RulePriority(); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/PmdAnalysis.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/PmdAnalysis.java deleted file mode 100644 index 42b769b42a..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/PmdAnalysis.java +++ /dev/null @@ -1,625 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: performAnalysisAndCollectReport, changes due to Report moved package - -package net.sourceforge.pmd; - -import static net.sourceforge.pmd.util.CollectionUtil.listOf; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.event.Level; - -import net.sourceforge.pmd.benchmark.TimeTracker; -import net.sourceforge.pmd.benchmark.TimedOperation; -import net.sourceforge.pmd.benchmark.TimedOperationCategory; -import net.sourceforge.pmd.cache.internal.AnalysisCacheListener; -import net.sourceforge.pmd.cache.internal.NoopAnalysisCache; -import net.sourceforge.pmd.internal.LogMessages; -import net.sourceforge.pmd.internal.util.ClasspathClassLoader; -import net.sourceforge.pmd.internal.util.FileCollectionUtil; -import net.sourceforge.pmd.internal.util.IOUtil; -import net.sourceforge.pmd.lang.InternalApiBridge; -import net.sourceforge.pmd.lang.JvmLanguagePropertyBundle; -import net.sourceforge.pmd.lang.Language; -import net.sourceforge.pmd.lang.LanguageProcessor.AnalysisTask; -import net.sourceforge.pmd.lang.LanguageProcessorRegistry; -import net.sourceforge.pmd.lang.LanguageProcessorRegistry.LanguageTerminationException; -import net.sourceforge.pmd.lang.LanguagePropertyBundle; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersion; -import net.sourceforge.pmd.lang.LanguageVersionDiscoverer; -import net.sourceforge.pmd.lang.document.FileCollector; -import net.sourceforge.pmd.lang.document.TextFile; -import net.sourceforge.pmd.lang.rule.RuleSet; -import net.sourceforge.pmd.lang.rule.RuleSetLoader; -import net.sourceforge.pmd.renderers.Renderer; -import net.sourceforge.pmd.reporting.ConfigurableFileNameRenderer; -import net.sourceforge.pmd.reporting.FileAnalysisListener; -import net.sourceforge.pmd.reporting.GlobalAnalysisListener; -import net.sourceforge.pmd.reporting.ListenerInitializer; -import net.sourceforge.pmd.reporting.Report; -import net.sourceforge.pmd.reporting.ReportStats; -import net.sourceforge.pmd.reporting.ReportStatsListener; -import net.sourceforge.pmd.util.AssertionUtil; -import net.sourceforge.pmd.util.StringUtil; -import net.sourceforge.pmd.util.log.PmdReporter; - -/** - * Main programmatic API of PMD. This is not a CLI entry point, see module - * {@code pmd-cli} for that. - * - *

Usage overview

- * - *

Create and configure a {@link PMDConfiguration}, - * then use {@link #create(PMDConfiguration)} to obtain an instance. - * You can perform additional configuration on the instance, e.g. adding - * files to process, or additional rulesets and renderers. Then, call - * {@link #performAnalysis()} or one of the related terminal methods. - * - *

Simple example

- * - *
{@code
- *   PMDConfiguration config = new PMDConfiguration();
- *   config.setDefaultLanguageVersion(LanguageRegistry.findLanguageByTerseName("java").getVersion("11"));
- *   config.addInputPath(Path.of("src/main/java"));
- *   config.prependClasspath("target/classes");
- *   config.setMinimumPriority(RulePriority.HIGH);
- *   config.addRuleSet("rulesets/java/quickstart.xml");
- *   config.setReportFormat("xml");
- *   config.setReportFile("target/pmd-report.xml");
- *
- *   try (PmdAnalysis pmd = PmdAnalysis.create(config)) {
- *     // note: don't use `config` once a PmdAnalysis has been created.
- *     // optional: add more rulesets
- *     pmd.addRuleSet(pmd.newRuleSetLoader().loadFromResource("custom-ruleset.xml"));
- *     // optional: add more files
- *     pmd.files().addFile(Paths.get("src", "main", "more-java", "ExtraSource.java"));
- *     // optional: add more renderers
- *     pmd.addRenderer(renderer);
- *
- *     pmd.performAnalysis();
- *   }
- * }
- * - *

Rendering reports

- * - *

If you just want to render a report to a file like with the CLI, you - * should use a {@link Renderer}. You can add a custom one with {@link PmdAnalysis#addRenderer(Renderer)}. - * You can add one of the builtin renderers from its ID using {@link PMDConfiguration#setReportFormat(String)}. - * - *

Reports and events

- * - *

If you want strongly typed access to violations and other analysis events, - * you can implement and register a {@link GlobalAnalysisListener} with {@link #addListener(GlobalAnalysisListener)}. - * The listener needs to provide a new {@link FileAnalysisListener} for each file, - * which will receive events from the analysis. The listener's lifecycle - * happens only once the analysis is started ({@link #performAnalysis()}). - * - *

If you want access to all events once the analysis ends instead of processing - * events as they go, you can obtain a {@link Report} instance from {@link #performAnalysisAndCollectReport()}, - * or use {@link Report.GlobalReportBuilderListener} manually. Keep in - * mind collecting a report is less memory-efficient than using a listener. - * - *

If you want to process events in batches, one per file, you can - * use {@link Report.ReportBuilderListener}. to implement {@link GlobalAnalysisListener#startFileAnalysis(TextFile)}. - * - *

Listeners can be used alongside renderers. - * - *

Specifying the Java classpath

- * - *

Java rules work better if you specify the path to the compiled classes - * of the analysed sources. See {@link PMDConfiguration#prependAuxClasspath(String)}. - * - *

Customizing message output

- * - *

The analysis reports messages like meta warnings and errors through a - * {@link PmdReporter} instance. To override how those messages are output, - * you can set it in {@link PMDConfiguration#setReporter(PmdReporter)}. - * By default, it forwards messages to SLF4J. - * - */ -public final class PmdAnalysis implements AutoCloseable { - - private static final Logger LOG = LoggerFactory.getLogger(PmdAnalysis.class); - - private final FileCollector collector; - private final List renderers = new ArrayList<>(); - private final List listeners = new ArrayList<>(); - private final List ruleSets = new ArrayList<>(); - private final PMDConfiguration configuration; - private final PmdReporter reporter; - - private final Map langProperties = new HashMap<>(); - private boolean closed; - private final ConfigurableFileNameRenderer fileNameRenderer = new ConfigurableFileNameRenderer(); - - /** - * Constructs a new instance. The files paths (input files, filelist, - * exclude list, etc) given in the configuration are collected into - * the file collector ({@link #files()}), but more can be added - * programmatically using the file collector. - */ - private PmdAnalysis(PMDConfiguration config) { - this.configuration = config; - this.reporter = config.getReporter(); - this.collector = net.sourceforge.pmd.lang.document.InternalApiBridge.newCollector( - config.getLanguageVersionDiscoverer(), - reporter - ); - - } - - /** - * Constructs a new instance from a configuration. - * - *

    - *
  • The files paths (input files, filelist, - * exclude list, etc) are explored and the files to analyse are - * collected into the file collector ({@link #files()}). - * More can be added programmatically using the file collector. - *
  • The rulesets given in the configuration are loaded ({@link PMDConfiguration#getRuleSets()}) - *
  • A renderer corresponding to the parameters of the configuration - * is created and added (but not started). - *
- */ - public static PmdAnalysis create(PMDConfiguration config) { - PmdAnalysis pmd = new PmdAnalysis(config); - - // note: do not filter files by language - // they could be ignored later. The problem is if you call - // addRuleSet later, then you could be enabling new languages - // So the files should not be pruned in advance - FileCollectionUtil.collectFiles(config, pmd.files()); - - if (config.getReportFormat() != null) { - Renderer renderer = config.createRenderer(true); - pmd.addRenderer(renderer); - } - - if (!config.getRuleSetPaths().isEmpty()) { - final net.sourceforge.pmd.lang.rule.RuleSetLoader ruleSetLoader = pmd.newRuleSetLoader(); - final List ruleSets = net.sourceforge.pmd.lang.rule.InternalApiBridge.loadRuleSetsWithoutException(ruleSetLoader, config.getRuleSetPaths()); - pmd.addRuleSets(ruleSets); - } - - for (Language language : config.getLanguageRegistry()) { - LanguagePropertyBundle props = config.getLanguageProperties(language); - assert props.getLanguage().equals(language); - pmd.langProperties.put(language, props); - - LanguageVersion forcedVersion = config.getForceLanguageVersion(); - if (forcedVersion != null && forcedVersion.getLanguage().equals(language)) { - props.setLanguageVersion(forcedVersion.getVersion()); - } - - // TODO replace those with actual language properties when the - // CLI syntax is implemented. - props.setProperty(LanguagePropertyBundle.SUPPRESS_MARKER, config.getSuppressMarker()); - if (props instanceof JvmLanguagePropertyBundle) { - ((JvmLanguagePropertyBundle) props).setClassLoader(config.getClassLoader()); - } - } - - for (Path path : config.getRelativizeRoots()) { - pmd.fileNameRenderer.relativizeWith(path); - } - - return pmd; - } - - // test only - List rulesets() { - return ruleSets; - } - - // test only - List renderers() { - return renderers; - } - - - /** - * Returns the file collector for the analysed sources. - */ - public FileCollector files() { - return collector; // todo user can close collector programmatically - } - - /** - * Returns a new ruleset loader, which can be used to create new - * rulesets (add them then with {@link #addRuleSet(RuleSet)}). - * - *
{@code
-     * try (PmdAnalysis pmd = create(config)) {
-     *     pmd.addRuleSet(pmd.newRuleSetLoader().loadFromResource("custom-ruleset.xml"));
-     * }
-     * }
- */ - public net.sourceforge.pmd.lang.rule.RuleSetLoader newRuleSetLoader() { - return RuleSetLoader.fromPmdConfig(configuration); - } - - /** - * Add a new renderer. The given renderer must not already be started, - * it will be started by {@link #performAnalysis()}. - * - * @throws NullPointerException If the parameter is null - */ - public void addRenderer(Renderer renderer) { - AssertionUtil.requireParamNotNull("renderer", renderer); - this.renderers.add(renderer); - } - - /** - * Add several renderers at once. - * - * @throws NullPointerException If the parameter is null, or any of its items is null. - */ - public void addRenderers(Collection renderers) { - renderers.forEach(this::addRenderer); - } - - /** - * Add a new listener. As per the contract of {@link GlobalAnalysisListener}, - * this object must be ready for interaction. However, nothing will - * be done with the listener until {@link #performAnalysis()} is called. - * The listener will be closed by {@link #performAnalysis()}, or - * {@link #close()}, whichever happens first. - * - * @throws NullPointerException If the parameter is null - */ - public void addListener(GlobalAnalysisListener listener) { - AssertionUtil.requireParamNotNull("listener", listener); - this.listeners.add(listener); - } - - /** - * Add several listeners at once. - * - * @throws NullPointerException If the parameter is null, or any of its items is null. - * @see #addListener(GlobalAnalysisListener) - */ - public void addListeners(Collection listeners) { - listeners.forEach(this::addListener); - } - - /** - * Add a new ruleset. - * - * @throws NullPointerException If the parameter is null - */ - public void addRuleSet(RuleSet ruleSet) { - AssertionUtil.requireParamNotNull("rule set", ruleSet); - this.ruleSets.add(ruleSet); - } - - /** - * Add several rulesets at once. - * - * @throws NullPointerException If the parameter is null, or any of its items is null. - */ - public void addRuleSets(Collection ruleSets) { - ruleSets.forEach(this::addRuleSet); - } - - /** - * Returns an unmodifiable view of the ruleset list. That will be - * processed. - */ - public List getRulesets() { - return Collections.unmodifiableList(ruleSets); - } - - - /** - * Returns a mutable bundle of language properties that are associated - * to the given language (always the same for a given language). - * - * @param language A language, which must be registered - */ - public LanguagePropertyBundle getLanguageProperties(Language language) { - configuration.checkLanguageIsRegistered(language); - return langProperties.computeIfAbsent(language, Language::newPropertyBundle); - } - - - public ConfigurableFileNameRenderer fileNameRenderer() { - return fileNameRenderer; - } - - /** - * Run PMD with the current state of this instance. This will start - * and finish the registered renderers, and close all - * {@linkplain #addListener(GlobalAnalysisListener) registered listeners}. - * All files collected in the {@linkplain #files() file collector} are - * processed. This does not return a report, as the analysis results - * are consumed by {@link GlobalAnalysisListener} instances (of which - * Renderers are a special case). Note that this does - * not throw, errors are instead accumulated into a {@link PmdReporter}. - */ - public void performAnalysis() { - performAnalysisImpl(Collections.emptyList()); - } - - /** - * Run PMD with the current state of this instance. This will start - * and finish the registered renderers. All files collected in the - * {@linkplain #files() file collector} are processed. Returns the - * output report. Note that this does not throw, errors are instead - * accumulated into a {@link PmdReporter}. - */ - public Report performAnalysisAndCollectReport() { - try (Report.GlobalReportBuilderListener reportBuilder = new Report.GlobalReportBuilderListener()) { - performAnalysisImpl(listOf(reportBuilder)); // closes the report builder - return reportBuilder.getResultImpl(); - } - } - - void performAnalysisImpl(List extraListeners) { - try (FileCollector files = collector) { - files.filterLanguages(getApplicableLanguages(false)); - performAnalysisImpl(extraListeners, files.getCollectedFiles()); - } - } - - void performAnalysisImpl(List extraListeners, List textFiles) { - net.sourceforge.pmd.lang.rule.internal.RuleSets rulesets = new net.sourceforge.pmd.lang.rule.internal.RuleSets(this.ruleSets); - - GlobalAnalysisListener listener; - try { - @SuppressWarnings("PMD.CloseResource") - AnalysisCacheListener cacheListener = new AnalysisCacheListener(configuration.getAnalysisCache(), - rulesets, - configuration.getClassLoader(), - textFiles); - listener = GlobalAnalysisListener.tee(listOf(createComposedRendererListener(renderers), - GlobalAnalysisListener.tee(listeners), - GlobalAnalysisListener.tee(extraListeners), - cacheListener)); - - // Initialize listeners - try (ListenerInitializer initializer = listener.initializer()) { - initializer.setNumberOfFilesToAnalyze(textFiles.size()); - initializer.setFileNameRenderer(fileNameRenderer()); - } - } catch (Exception e) { - reporter.errorEx("Exception while initializing analysis listeners", e); - throw new RuntimeException("Exception while initializing analysis listeners", e); - } - - try (TimedOperation ignored = TimeTracker.startOperation(TimedOperationCategory.FILE_PROCESSING)) { - for (final Rule rule : removeBrokenRules(rulesets)) { - // todo Just like we throw for invalid properties, "broken rules" - // shouldn't be a "config error". This is the only instance of - // config errors... - // see https://github.com/pmd/pmd/issues/3901 - listener.onConfigError(new Report.ConfigurationError(rule, rule.dysfunctionReason())); - } - - encourageToUseIncrementalAnalysis(configuration); - - try (LanguageProcessorRegistry lpRegistry = LanguageProcessorRegistry.create( - // only start the applicable languages (and dependencies) - new LanguageRegistry(getApplicableLanguages(true)), - langProperties, - reporter - )) { - // Note the analysis task is shared: all processors see - // the same file list, which may contain files for other - // languages. - AnalysisTask analysisTask = InternalApiBridge.createAnalysisTask( - rulesets, - textFiles, - listener, - configuration.getThreads(), - configuration.getAnalysisCache(), - reporter, - lpRegistry - ); - - List analyses = new ArrayList<>(); - try { - for (Language lang : lpRegistry.getLanguages()) { - analyses.add(lpRegistry.getProcessor(lang).launchAnalysis(analysisTask)); - } - } finally { - Exception e = IOUtil.closeAll(analyses); - if (e != null) { - reporter.errorEx("Error while joining analysis", e); - } - } - - } catch (LanguageTerminationException e) { - reporter.errorEx("Error while closing language processors", e); - } - } finally { - try { - listener.close(); - } catch (Exception e) { - reporter.errorEx("Exception while closing analysis listeners", e); - // todo better exception - throw new RuntimeException("Exception while closing analysis listeners", e); - } - } - } - - - private GlobalAnalysisListener createComposedRendererListener(List renderers) throws Exception { - if (renderers.isEmpty()) { - return GlobalAnalysisListener.noop(); - } - - List rendererListeners = new ArrayList<>(renderers.size()); - for (Renderer renderer : renderers) { - try { - @SuppressWarnings("PMD.CloseResource") - GlobalAnalysisListener listener = - Objects.requireNonNull(renderer.newListener(), "Renderer should provide non-null listener"); - rendererListeners.add(listener); - } catch (Exception ioe) { - // close listeners so far, throw their close exception or the ioe - IOUtil.ensureClosed(rendererListeners, ioe); - throw AssertionUtil.shouldNotReachHere("ensureClosed should have thrown", ioe); - } - } - return GlobalAnalysisListener.tee(rendererListeners); - } - - private Set getApplicableLanguages(boolean quiet) { - Set languages = new HashSet<>(); - LanguageVersionDiscoverer discoverer = configuration.getLanguageVersionDiscoverer(); - - for (RuleSet ruleSet : ruleSets) { - for (Rule rule : ruleSet.getRules()) { - Language ruleLanguage = rule.getLanguage(); - Objects.requireNonNull(ruleLanguage, "Rule has no language " + rule); - if (!languages.contains(ruleLanguage)) { - LanguageVersion version = discoverer.getDefaultLanguageVersion(ruleLanguage); - if (net.sourceforge.pmd.lang.rule.InternalApiBridge.ruleSetApplies((net.sourceforge.pmd.lang.rule.Rule) rule, version)) { - configuration.checkLanguageIsRegistered(ruleLanguage); - languages.add(ruleLanguage); - if (!quiet) { - LOG.trace("Using {} version ''{}''", version.getLanguage().getName(), version.getTerseName()); - } - } - } - } - } - - // collect all dependencies, they shouldn't be filtered out - LanguageRegistry reg = configuration.getLanguageRegistry(); - boolean changed; - do { - changed = false; - for (Language lang : new HashSet<>(languages)) { - for (String depId : lang.getDependencies()) { - Language depLang = reg.getLanguageById(depId); - if (depLang == null) { - // todo maybe report all then throw - throw new IllegalStateException( - "Language " + lang.getId() + " has unsatisfied dependencies: " - + depId + " is not found in " + reg - ); - } - changed |= languages.add(depLang); - } - } - } while (changed); - return languages; - } - - /** - * Remove and return the misconfigured rules from the rulesets and log them - * for good measure. - */ - private Set removeBrokenRules(final RuleSets ruleSets) { - final Set brokenRules = new HashSet<>(); - ruleSets.removeDysfunctionalRules(brokenRules); - - for (final Rule rule : brokenRules) { - reporter.warn("Removed misconfigured rule: {0} cause: {1}", - rule.getName(), rule.dysfunctionReason()); - } - - return brokenRules; - } - - - public PmdReporter getReporter() { - return reporter; - } - - @Override - public void close() { - if (closed) { - return; - } - closed = true; - collector.close(); - - // close listeners if analysis is not run. - IOUtil.closeAll(listeners); - - /* - * Make sure it's our own classloader before attempting to close it.... - * Maven + Jacoco provide us with a cloaseable classloader that if closed - * will throw a ClassNotFoundException. - */ - if (configuration.getClassLoader() instanceof ClasspathClassLoader) { - IOUtil.tryCloseClassLoader(configuration.getClassLoader()); - } - } - - public ReportStats runAndReturnStats() { - if (getRulesets().isEmpty()) { - return ReportStats.empty(); - } - - @SuppressWarnings("PMD.CloseResource") - ReportStatsListener listener = new ReportStatsListener(); - - addListener(listener); - - try { - performAnalysis(); - } catch (Exception e) { - getReporter().errorEx("Exception during processing", e); - ReportStats stats = listener.getResult(); - printErrorDetected(1 + stats.getNumErrors()); - return stats; // should have been closed - } - ReportStats stats = listener.getResult(); - - if (stats.getNumErrors() > 0) { - printErrorDetected(stats.getNumErrors()); - } - - return stats; - } - - static void printErrorDetected(PmdReporter reporter, int errors) { - String msg = LogMessages.errorDetectedMessage(errors, "PMD"); - // note: using error level here increments the error count of the reporter, - // which we don't want. - reporter.info(StringUtil.quoteMessageFormat(msg)); - } - - void printErrorDetected(int errors) { - printErrorDetected(getReporter(), errors); - } - - private static void encourageToUseIncrementalAnalysis(final PMDConfiguration configuration) { - final PmdReporter reporter = configuration.getReporter(); - - if (!configuration.isIgnoreIncrementalAnalysis() - && configuration.getAnalysisCache() instanceof NoopAnalysisCache - && reporter.isLoggable(Level.WARN)) { - final String version = - PMDVersion.isUnknown() || PMDVersion.isSnapshot() ? "latest" : "pmd-doc-" + PMDVersion.VERSION; - reporter.warn("This analysis could be faster, please consider using Incremental Analysis: " - + "https://docs.pmd-code.org/{0}/pmd_userdocs_incremental_analysis.html", version); - } - } - - // ---- compatibility - - // new method to be compatible with PMD 6 - Report has changed package - public net.sourceforge.pmd.Report performAnalysisAndCollectReport$$bridge() { // SUPPRESS CHECKSTYLE ignore - return performAnalysisAndCollectReport(); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/Report.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/Report.java deleted file mode 100644 index c02ae1a01f..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/Report.java +++ /dev/null @@ -1,437 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: filterViolations(net.sourceforge.pmd.util.Predicate filter) - -package net.sourceforge.pmd; - -import static java.util.Collections.synchronizedList; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Predicate; - -import net.sourceforge.pmd.annotation.DeprecatedUntil700; -import net.sourceforge.pmd.annotation.Experimental; -import net.sourceforge.pmd.annotation.InternalApi; -import net.sourceforge.pmd.lang.document.FileId; -import net.sourceforge.pmd.lang.document.TextFile; -import net.sourceforge.pmd.renderers.AbstractAccumulatingRenderer; -import net.sourceforge.pmd.reporting.FileAnalysisListener; -import net.sourceforge.pmd.reporting.GlobalAnalysisListener; -import net.sourceforge.pmd.reporting.ViolationSuppressor; -import net.sourceforge.pmd.util.BaseResultProducingCloseable; - -/** - * A {@link Report} collects all information during a PMD execution. This - * includes violations, suppressed violations, metrics, error during processing - * and configuration errors. - * - *

A report may be created by a {@link GlobalReportBuilderListener} that you - * use as the {@linkplain GlobalAnalysisListener} in {@link PmdAnalysis#performAnalysisAndCollectReport() PMD's entry point}. - * You can also create one manually with {@link #buildReport(Consumer)}. - * - *

For special use cases, like filtering the report after PMD analysis and - * before rendering the report, some transformation operations are provided: - *

    - *
  • {@link #filterViolations(Predicate)}
  • - *
  • {@link #union(Report)}
  • - *
- * These methods create a new {@link Report} rather than modifying their receiver. - */ -public class Report { - // todo move to package reporting - - protected final List violations = synchronizedList(new ArrayList<>()); - protected final List suppressedRuleViolations = synchronizedList(new ArrayList<>()); - protected final List errors = synchronizedList(new ArrayList<>()); - protected final List configErrors = synchronizedList(new ArrayList<>()); - - @DeprecatedUntil700 - @InternalApi - public Report() { // NOPMD - UnnecessaryConstructor - // TODO: should be package-private, you have to use a listener to build a report. - } - - /** - * Represents a configuration error. - */ - public static class ConfigurationError { - - private final Rule rule; - private final String issue; - - /** - * Creates a new configuration error for a specific rule. - * - * @param theRule - * the rule which is configured wrongly - * @param theIssue - * the reason, why the configuration is wrong - */ - public ConfigurationError(Rule theRule, String theIssue) { - rule = theRule; - issue = theIssue; - } - - /** - * Gets the wrongly configured rule - * - * @return the wrongly configured rule - */ - public Rule rule() { - return rule; - } - - /** - * Gets the reason for the configuration error. - * - * @return the issue - */ - public String issue() { - return issue; - } - } - - /** - * Represents a processing error, such as a parse error. - */ - public static class ProcessingError { - - private final Throwable error; - private final FileId file; - - /** - * Creates a new processing error - * - * @param error - * the error - * @param file - * the file during which the error occurred - */ - public ProcessingError(Throwable error, FileId file) { - this.error = error; - this.file = file; - } - - public String getMsg() { - return error.getClass().getSimpleName() + ": " + error.getMessage(); - } - - public String getDetail() { - try (StringWriter stringWriter = new StringWriter(); - PrintWriter writer = new PrintWriter(stringWriter)) { - error.printStackTrace(writer); - return stringWriter.toString(); - } catch (IOException e) { - // IOException on close - should never happen when using StringWriter - throw new RuntimeException(e); - } - } - - public FileId getFileId() { - return file; - } - - public Throwable getError() { - return error; - } - - // ------------------- compat extensions -------------------- - public String getFile() { - return file.getAbsolutePath(); - } - } - - /** - * Represents a violation, that has been suppressed. - */ - public static class SuppressedViolation { - - private final RuleViolation rv; - private final String userMessage; - private final ViolationSuppressor suppressor; - - /** - * Creates a suppressed violation. - * - * @param rv The violation, that has been suppressed - * @param suppressor The suppressor which suppressed the violation - * @param userMessage Any relevant info given by the suppressor - */ - public SuppressedViolation(RuleViolation rv, ViolationSuppressor suppressor, String userMessage) { - this.suppressor = suppressor; - this.rv = rv; - this.userMessage = userMessage; - } - - public ViolationSuppressor getSuppressor() { - return suppressor; - } - - public RuleViolation getRuleViolation() { - return this.rv; - } - - public String getUserMessage() { - return userMessage; - } - } - - /** - * Adds a new rule violation to the report and notify the listeners. - * - * @param violation the violation to add - * - * @deprecated PMD's way of creating a report is internal and may be changed in pmd 7. - */ - @DeprecatedUntil700 - @Deprecated - @InternalApi - public void addRuleViolation(RuleViolation violation) { - synchronized (violations) { - // note that this binary search is inefficient as we usually - // report violations file by file. - int index = Collections.binarySearch(violations, violation, RuleViolation.DEFAULT_COMPARATOR); - violations.add(index < 0 ? -index - 1 : index, violation); - } - } - - /** - * Adds a new suppressed violation. - */ - private void addSuppressedViolation(SuppressedViolation sv) { - suppressedRuleViolations.add(sv); - } - - /** - * Adds a new configuration error to the report. - * - * @param error the error to add - * - * @deprecated PMD's way of creating a report is internal and may be changed in pmd 7. - */ - @DeprecatedUntil700 - @Deprecated - @InternalApi - public void addConfigError(ConfigurationError error) { - configErrors.add(error); - } - - /** - * Adds a new processing error to the report. - * - * @param error - * the error to add - * @deprecated PMD's way of creating a report is internal and may be changed in pmd 7. - */ - @DeprecatedUntil700 - @Deprecated - @InternalApi - public void addError(ProcessingError error) { - errors.add(error); - } - - /** - * Merges the given report into this report. This might be necessary, if a - * summary over all violations is needed as PMD creates one report per file - * by default. - * - *

This is synchronized on an internal lock (note that other mutation - * operations are not synchronized, todo for pmd 7). - * - * @param r the report to be merged into this. - * - * @see AbstractAccumulatingRenderer - * - * @deprecated Convert Renderer to use the reports. - */ - @Deprecated - public void merge(Report r) { - errors.addAll(r.errors); - configErrors.addAll(r.configErrors); - suppressedRuleViolations.addAll(r.suppressedRuleViolations); - - for (RuleViolation violation : r.getViolations()) { - addRuleViolation(violation); - } - } - - - /** - * Returns an unmodifiable list of violations that were suppressed. - */ - public List getSuppressedViolations() { - return Collections.unmodifiableList(suppressedRuleViolations); - } - - /** - * Returns an unmodifiable list of violations that have been - * recorded until now. None of those violations were suppressed. - * - *

The violations list is sorted with {@link RuleViolation#DEFAULT_COMPARATOR}. - */ - public List getViolations() { - return Collections.unmodifiableList(violations); - } - - - /** - * Returns an unmodifiable list of processing errors that have been - * recorded until now. - */ - public List getProcessingErrors() { - return Collections.unmodifiableList(errors); - } - - - /** - * Returns an unmodifiable list of configuration errors that have - * been recorded until now. - */ - public List getConfigurationErrors() { - return Collections.unmodifiableList(configErrors); - } - - /** - * Create a report by making side effects on a {@link FileAnalysisListener}. - * This wraps a {@link ReportBuilderListener}. - */ - public static Report buildReport(Consumer lambda) { - return BaseResultProducingCloseable.using(new ReportBuilderListener(), lambda); - } - - /** - * A {@link FileAnalysisListener} that accumulates events into a - * {@link Report}. - */ - public static /*final*/ class ReportBuilderListener extends BaseResultProducingCloseable implements FileAnalysisListener { - - private final Report report; - - public ReportBuilderListener() { - this(new Report()); - } - - ReportBuilderListener(Report report) { - this.report = report; - } - - @Override - protected Report getResultImpl() { - return report; - } - - @Override - public void onRuleViolation(net.sourceforge.pmd.reporting.RuleViolation violation) { - report.addRuleViolation(violation); - } - - @Override - public void onSuppressedRuleViolation(net.sourceforge.pmd.reporting.Report.SuppressedViolation violation) { - report.addSuppressedViolation(violation); - } - - @Override - public void onError(net.sourceforge.pmd.reporting.Report.ProcessingError error) { - report.addError(error); - } - - @Override - public String toString() { - return "ReportBuilderListener"; - } - } - - /** - * A {@link GlobalAnalysisListener} that accumulates the events of - * all files into a {@link Report}. - */ - public static /*final*/ class GlobalReportBuilderListener extends BaseResultProducingCloseable implements GlobalAnalysisListener { - - private final net.sourceforge.pmd.reporting.Report report = new net.sourceforge.pmd.reporting.Report(); - - @Override - public FileAnalysisListener startFileAnalysis(TextFile file) { - // note that the report is shared, but Report is now thread-safe - return new ReportBuilderListener(this.report); - } - - @Override - public void onConfigError(net.sourceforge.pmd.reporting.Report.ConfigurationError error) { - report.addConfigError(error); - } - - @Override - protected net.sourceforge.pmd.reporting.Report getResultImpl() { - return report; - } - } - - /** - * Creates a new report taking all the information from this report, - * but filtering the violations. - * - * @param filter when true, the violation will be kept. - * @return copy of this report - */ - @Experimental - public Report filterViolations(Predicate filter) { - Report copy = new Report(); - - for (RuleViolation violation : violations) { - if (filter.test(violation)) { - copy.addRuleViolation(violation); - } - } - - copy.suppressedRuleViolations.addAll(suppressedRuleViolations); - copy.errors.addAll(errors); - copy.configErrors.addAll(configErrors); - return copy; - } - - /** - * Creates a new report by combining this report with another report. - * This is similar to {@link #merge(Report)}, but instead a new report - * is created. The lowest start time and greatest end time are kept in the copy. - * - * @param other the other report to combine - * @return - */ - @Experimental - public Report union(Report other) { - Report copy = new Report(); - - for (RuleViolation violation : violations) { - copy.addRuleViolation(violation); - } - for (RuleViolation violation : other.violations) { - copy.addRuleViolation(violation); - } - - copy.suppressedRuleViolations.addAll(suppressedRuleViolations); - copy.suppressedRuleViolations.addAll(other.suppressedRuleViolations); - - copy.errors.addAll(errors); - copy.errors.addAll(other.errors); - copy.configErrors.addAll(configErrors); - copy.configErrors.addAll(other.configErrors); - - return copy; - } - - // ------------------- compat extensions -------------------- - @Deprecated - public Report filterViolations(net.sourceforge.pmd.util.Predicate filter) { - Predicate javaPredicate = filter::test; - return filterViolations(javaPredicate); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/Rule.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/Rule.java deleted file mode 100644 index 29116c858f..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/Rule.java +++ /dev/null @@ -1,321 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// Old version of this class. In PMD 7, this has been moved into sub-package "rule". -// Changes: -// - deepCopy - -package net.sourceforge.pmd; - -import java.util.List; -import java.util.Optional; -import java.util.regex.Pattern; - -import net.sourceforge.pmd.lang.Language; -import net.sourceforge.pmd.lang.LanguageProcessor; -import net.sourceforge.pmd.lang.LanguageVersion; -import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.rule.RulePriority; -import net.sourceforge.pmd.lang.rule.RuleSet; -import net.sourceforge.pmd.lang.rule.RuleTargetSelector; -import net.sourceforge.pmd.properties.PropertyDescriptor; -import net.sourceforge.pmd.properties.PropertyFactory; -import net.sourceforge.pmd.properties.PropertySource; -import net.sourceforge.pmd.reporting.RuleContext; - -/** - * This is the basic Rule interface for PMD rules. - * - *

- * Thread safety: PMD will create one instance of a rule per - * thread. The instances are not shared across different threads. However, a - * single rule instance is reused for analyzing multiple files. - *

- */ -public interface Rule extends PropertySource { - - // TODO these should not be properties - - /** - * The property descriptor to universally suppress violations with messages - * matching a regular expression. - */ - PropertyDescriptor> VIOLATION_SUPPRESS_REGEX_DESCRIPTOR = - PropertyFactory.regexProperty("violationSuppressRegex") - .desc("Suppress violations with messages matching a regular expression") - .toOptional("") - .defaultValue(Optional.empty()) - .build(); - - /** - * Name of the property to universally suppress violations on nodes which - * match a given relative XPath expression. - */ - PropertyDescriptor> VIOLATION_SUPPRESS_XPATH_DESCRIPTOR = - PropertyFactory.stringProperty("violationSuppressXPath") - .desc("Suppress violations on nodes which match a given relative XPath expression.") - .toOptional("") - .defaultValue(Optional.empty()) - .build(); - - /** - * Get the Language of this Rule. - * - * @return the language - */ - Language getLanguage(); - - /** - * Set the Language of this Rule. - * - * @param language - * the language - */ - void setLanguage(Language language); - - /** - * Get the minimum LanguageVersion to which this Rule applies. If this value - * is null it indicates there is no minimum bound. - * - * @return the minimum language version - */ - LanguageVersion getMinimumLanguageVersion(); - - /** - * Set the minimum LanguageVersion to which this Rule applies. - * - * @param minimumLanguageVersion - * the minimum language version - */ - void setMinimumLanguageVersion(LanguageVersion minimumLanguageVersion); - - /** - * Get the maximum LanguageVersion to which this Rule applies. If this value - * is null it indicates there is no maximum bound. - * - * @return the maximum language version - */ - LanguageVersion getMaximumLanguageVersion(); - - /** - * Set the maximum LanguageVersion to which this Rule applies. - * - * @param maximumLanguageVersion - * the maximum language version - */ - void setMaximumLanguageVersion(LanguageVersion maximumLanguageVersion); - - /** - * Gets whether this Rule is deprecated. A deprecated Rule is one which: - *
    - *
  • is scheduled for removal in a future version of PMD
  • - *
  • or, has been removed and replaced with a non-functioning place-holder - * and will be completely removed in a future version of PMD
  • - *
  • or, has been renamed/moved and the old name will be completely - * removed in a future version of PMD
  • - *
- * - * @return true if this rule is deprecated - */ - boolean isDeprecated(); - - /** - * Sets whether this Rule is deprecated. - * - * @param deprecated - * whether this rule is deprecated - */ - void setDeprecated(boolean deprecated); - - /** - * Get the name of this Rule. - * - * @return the name - */ - @Override - String getName(); - - /** - * Set the name of this Rule. - * - * @param name - * the name - */ - void setName(String name); - - /** - * Get the version of PMD in which this Rule was added. Return - * null if not applicable. - * - * @return version of PMD since when this rule was added - */ - String getSince(); - - /** - * Set the version of PMD in which this Rule was added. - * - * @param since - * the version of PMD since when this rule was added - */ - void setSince(String since); - - /** - * Get the implementation class of this Rule. - * - * @return the implementation class name of this rule. - */ - String getRuleClass(); - - /** - * Set the class of this Rule. - * - * @param ruleClass - * the class name of this rule. - */ - void setRuleClass(String ruleClass); - - /** - * Get the name of the RuleSet containing this Rule. - * - * @return the name of th ruleset containing this rule. - * @see RuleSet - */ - String getRuleSetName(); - - /** - * Set the name of the RuleSet containing this Rule. - * - * @param name - * the name of the ruleset containing this rule. - * @see RuleSet - */ - void setRuleSetName(String name); - - /** - * Get the message to show when this Rule identifies a violation. - * - * @return the message to show for a violation. - */ - String getMessage(); - - /** - * Set the message to show when this Rule identifies a violation. - * - * @param message - * the message to show for a violation. - */ - void setMessage(String message); - - /** - * Get the description of this Rule. - * - * @return the description - */ - String getDescription(); - - /** - * Set the description of this Rule. - * - * @param description - * the description - */ - void setDescription(String description); - - /** - * Get the list of examples for this Rule. - * - * @return the list of examples for this rule. - */ - List getExamples(); - - /** - * Add a single example for this Rule. - * - * @param example - * a single example to add - */ - void addExample(String example); - - /** - * Get a URL for external information about this Rule. - * - * @return the URL for external information about this rule. - */ - String getExternalInfoUrl(); - - /** - * Set a URL for external information about this Rule. - * - * @param externalInfoUrl - * the URL for external information about this rule. - */ - void setExternalInfoUrl(String externalInfoUrl); - - /** - * Get the priority of this Rule. - * - * @return the priority - */ - RulePriority getPriority(); - - /** - * Set the priority of this Rule. - * - * @param priority - * the priority - */ - void setPriority(RulePriority priority); - - - /** - * Returns the object that selects the nodes to which this rule applies. - * The selected nodes will be handed to {@link #apply(Node, RuleContext)}. - */ - RuleTargetSelector getTargetSelector(); - - /** - * Initialize the rule using the language processor if needed. - * - * @param languageProcessor The processor for the rule's language - */ - default void initialize(LanguageProcessor languageProcessor) { - // by default do nothing - } - - /** - * Start processing. Called once per file, before apply() is first called. - * - * @param ctx the rule context - */ - void start(RuleContext ctx); - - - /** - * Process the given node. The nodes that are fed to this method - * are the nodes selected by {@link #getTargetSelector()}. - * - * @param target Node on which to apply the rule - * @param ctx Rule context, handling violations - */ - void apply(Node target, RuleContext ctx); - - /** - * End processing. Called once per file, after apply() is last called. - * - * @param ctx - * the rule context - */ - void end(RuleContext ctx); - - /** - * Creates a new copy of this rule. - * @return A new exact copy of this rule - */ - net.sourceforge.pmd.lang.rule.Rule deepCopy(); - - // new method to be compatible with PMD 6 - Rule has changed package - default Rule deepCopy$$bridge() { // SUPPRESS CHECKSTYLE ignore - return deepCopy(); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/RulePriority.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/RulePriority.java deleted file mode 100644 index c624f1200e..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/RulePriority.java +++ /dev/null @@ -1,138 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// Copy of net.sourceforge.pmd.lang.rule.RulePriority -// Added method: -// - asPMD7RulePriority - -package net.sourceforge.pmd; - -/** - * These are the possible Rule priority values. - * - * For backward compatibility, priorities range in value from 1 to 5, with 5 - * being the lowest priority. This means the ordinal value of the Enum should be - * avoided in favor of {@link RulePriority#getPriority()} and - * {@link RulePriority#valueOf(int)} - * - * @see How - * to define rules priority - */ -public enum RulePriority { - - /** High: Change absolutely required. Behavior is critically broken/buggy */ - HIGH(1, "High"), - /** - * Medium to high: Change highly recommended. Behavior is quite likely to be - * broken/buggy. - */ - MEDIUM_HIGH(2, "Medium High"), - /** - * Medium: Change recommended. Behavior is confusing, perhaps buggy, and/or - * against standards/best practices. - */ - MEDIUM(3, "Medium"), - /** - * Medium to low: Change optional. Behavior is not likely to be buggy, but - * more just flies in the face of standards/style/good taste. - */ - MEDIUM_LOW(4, "Medium Low"), - /** - * Low: Change highly optional. Nice to have, such as a consistent naming - * policy for package/class/fields... - */ - LOW(5, "Low"); - - private final int priority; - private final String name; - - RulePriority(int priority, String name) { - this.priority = priority; - this.name = name; - } - - /** - * Get the priority value as a number. This is the value to be used in the - * externalized form of a priority (e.g. in RuleSet XML). - * - * @return The int value of the priority. - */ - public int getPriority() { - return priority; - } - - /** - * Get the descriptive name of this priority. - * - * @return The descriptive name. - */ - public String getName() { - return name; - } - - /** - * Returns the descriptive name of the priority. - * - * @return descriptive name of the priority - * @see #getName() - */ - @Override - public String toString() { - return name; - } - - /** - * Get the priority which corresponds to the given number as returned by - * {@link RulePriority#getPriority()}. If the number is an invalid value, - * then {@link RulePriority#LOW} will be returned. - * - * @param priority - * The numeric priority value. - * @return The priority. - */ - public static RulePriority valueOf(int priority) { - try { - return RulePriority.values()[priority - 1]; - } catch (ArrayIndexOutOfBoundsException e) { - return LOW; - } - } - - /** - * Returns the priority which corresponds to the given number as returned by - * {@link RulePriority#getPriority()}. If the number is an invalid value, - * then null will be returned. - * - * @param priority The numeric priority value. - */ - public static RulePriority valueOfNullable(int priority) { - try { - return RulePriority.values()[priority - 1]; - } catch (ArrayIndexOutOfBoundsException e) { - return null; - } - } - - /** - * Returns the priority which corresponds to the given number as returned by - * {@link RulePriority#getPriority()}. If the number is an invalid value, - * then null will be returned. - * - * @param priority The numeric priority value. - */ - public static RulePriority valueOfNullable(String priority) { - try { - int integer = Integer.parseInt(priority); - return RulePriority.values()[integer - 1]; - } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) { - return null; - } - } - - // ---- compatibility extensions - - public net.sourceforge.pmd.lang.rule.RulePriority asPMD7RulePriority() { - return net.sourceforge.pmd.lang.rule.RulePriority.valueOf(name()); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetFactoryCompatibility.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetFactoryCompatibility.java deleted file mode 100644 index 2e79697725..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetFactoryCompatibility.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Before removing RuleSetFactoryCompatibility (#4314) - -package net.sourceforge.pmd; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; - -import org.checkerframework.checker.nullness.qual.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Provides a simple filter mechanism to avoid failing to parse an old ruleset, - * which references rules, that have either been removed from PMD already or - * renamed or moved to another ruleset. - * - * @see issue 1360 - */ -final class RuleSetFactoryCompatibility { - - static final RuleSetFactoryCompatibility EMPTY = new RuleSetFactoryCompatibility(); - /** The instance with the built-in filters for the modified PMD rules. */ - static final RuleSetFactoryCompatibility DEFAULT = new RuleSetFactoryCompatibility(); - - - static { - // PMD 5.3.0 - DEFAULT.addFilterRuleRenamed("java", "design", "UncommentedEmptyMethod", "UncommentedEmptyMethodBody"); - DEFAULT.addFilterRuleRemoved("java", "controversial", "BooleanInversion"); - - // PMD 5.3.1 - DEFAULT.addFilterRuleRenamed("java", "design", "UseSingleton", "UseUtilityClass"); - - // PMD 5.4.0 - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptyCatchBlock"); - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptyIfStatement"); - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptyWhileStmt"); - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptyTryBlock"); - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptyFinallyBlock"); - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptySwitchStatements"); - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptySynchronizedBlock"); - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptyStatementNotInLoop"); - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptyInitializer"); - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptyStatementBlock"); - DEFAULT.addFilterRuleMoved("java", "basic", "empty", "EmptyStaticInitializer"); - DEFAULT.addFilterRuleMoved("java", "basic", "unnecessary", "UnnecessaryConversionTemporary"); - DEFAULT.addFilterRuleMoved("java", "basic", "unnecessary", "UnnecessaryReturn"); - DEFAULT.addFilterRuleMoved("java", "basic", "unnecessary", "UnnecessaryFinalModifier"); - DEFAULT.addFilterRuleMoved("java", "basic", "unnecessary", "UselessOverridingMethod"); - DEFAULT.addFilterRuleMoved("java", "basic", "unnecessary", "UselessOperationOnImmutable"); - DEFAULT.addFilterRuleMoved("java", "basic", "unnecessary", "UnusedNullCheckInEquals"); - DEFAULT.addFilterRuleMoved("java", "basic", "unnecessary", "UselessParentheses"); - - // PMD 5.6.0 - DEFAULT.addFilterRuleRenamed("java", "design", "AvoidConstantsInterface", "ConstantsInInterface"); - // unused/UnusedModifier moved AND renamed, order is important! - DEFAULT.addFilterRuleMovedAndRenamed("java", "unusedcode", "UnusedModifier", "unnecessary", "UnnecessaryModifier"); - - // PMD 6.0.0 - DEFAULT.addFilterRuleMoved("java", "controversial", "unnecessary", "UnnecessaryParentheses"); - DEFAULT.addFilterRuleRenamed("java", "unnecessary", "UnnecessaryParentheses", "UselessParentheses"); - DEFAULT.addFilterRuleMoved("java", "typeresolution", "coupling", "LooseCoupling"); - DEFAULT.addFilterRuleMoved("java", "typeresolution", "clone", "CloneMethodMustImplementCloneable"); - DEFAULT.addFilterRuleMoved("java", "typeresolution", "imports", "UnusedImports"); - DEFAULT.addFilterRuleMoved("java", "typeresolution", "strictexception", "SignatureDeclareThrowsException"); - DEFAULT.addFilterRuleRenamed("java", "naming", "MisleadingVariableName", "MIsLeadingVariableName"); - DEFAULT.addFilterRuleRenamed("java", "unnecessary", "UnnecessaryFinalModifier", "UnnecessaryModifier"); - DEFAULT.addFilterRuleRenamed("java", "empty", "EmptyStaticInitializer", "EmptyInitializer"); - // GuardLogStatementJavaUtil moved and renamed... - DEFAULT.addFilterRuleMovedAndRenamed("java", "logging-java", "GuardLogStatementJavaUtil", "logging-jakarta-commons", "GuardLogStatement"); - DEFAULT.addFilterRuleRenamed("java", "logging-jakarta-commons", "GuardDebugLogging", "GuardLogStatement"); - - } - - - private static final Logger LOG = LoggerFactory.getLogger(RuleSetFactoryCompatibility.class); - - private final List filters = new ArrayList<>(); - - - void addFilterRuleMovedAndRenamed(String language, String oldRuleset, String oldName, String newRuleset, String newName) { - filters.add(RuleSetFilter.ruleMoved(language, oldRuleset, newRuleset, oldName)); - filters.add(RuleSetFilter.ruleRenamed(language, newRuleset, oldName, newName)); - } - - void addFilterRuleRenamed(String language, String ruleset, String oldName, String newName) { - filters.add(RuleSetFilter.ruleRenamed(language, ruleset, oldName, newName)); - } - - void addFilterRuleMoved(String language, String oldRuleset, String newRuleset, String ruleName) { - filters.add(RuleSetFilter.ruleMoved(language, oldRuleset, newRuleset, ruleName)); - } - - void addFilterRuleRemoved(String language, String ruleset, String name) { - filters.add(RuleSetFilter.ruleRemoved(language, ruleset, name)); - } - - @Nullable String applyRef(String ref) { - return applyRef(ref, false); - } - - - /** - * Returns the new rule ref, or null if the rule was deleted. Returns - * the argument if no replacement is needed. - * - * @param ref Original ref - * @param warn Whether to output a warning if a replacement is done - */ - public @Nullable String applyRef(String ref, boolean warn) { - String result = ref; - for (RuleSetFilter filter : filters) { - result = filter.applyRef(result, warn); - if (result == null) { - return null; - } - } - return result; - } - - /** - * Returns the new rule name, or null if the rule was deleted. Returns - * the argument if no replacement is needed. - * - * @param rulesetRef Ruleset name - * @param excludeName Original excluded name - * @param warn Whether to output a warning if a replacement is done - */ - public @Nullable String applyExclude(String rulesetRef, String excludeName, boolean warn) { - String result = excludeName; - for (RuleSetFilter filter : filters) { - result = filter.applyExclude(rulesetRef, result, warn); - if (result == null) { - return null; - } - } - return result; - } - - private static final class RuleSetFilter { - - private static final String MOVED_MESSAGE = "The rule \"{1}\" has been moved from ruleset \"{0}\" to \"{2}\". Please change your ruleset!"; - private static final String RENAMED_MESSAGE = "The rule \"{1}\" has been renamed to \"{3}\". Please change your ruleset!"; - private static final String REMOVED_MESSAGE = "The rule \"{1}\" in ruleset \"{0}\" has been removed from PMD and no longer exists. Please change your ruleset!"; - private final String ruleRef; - private final String oldRuleset; - private final String oldName; - private final String newRuleset; - private final String newName; - private final String logMessage; - - private RuleSetFilter(String oldRuleset, - String oldName, - @Nullable String newRuleset, - @Nullable String newName, - String logMessage) { - this.oldRuleset = oldRuleset; - this.oldName = oldName; - this.newRuleset = newRuleset; - this.newName = newName; - this.logMessage = logMessage; - this.ruleRef = oldRuleset + "/" + oldName; - } - - public static RuleSetFilter ruleRenamed(String language, String ruleset, String oldName, String newName) { - String base = "rulesets/" + language + "/" + ruleset + ".xml"; - return new RuleSetFilter(base, oldName, base, newName, RENAMED_MESSAGE); - } - - public static RuleSetFilter ruleMoved(String language, String oldRuleset, String newRuleset, String ruleName) { - String base = "rulesets/" + language + "/"; - return new RuleSetFilter(base + oldRuleset + ".xml", ruleName, - base + newRuleset + ".xml", ruleName, - MOVED_MESSAGE); - } - - public static RuleSetFilter ruleRemoved(String language, String ruleset, String name) { - String oldRuleset = "rulesets/" + language + "/" + ruleset + ".xml"; - return new RuleSetFilter(oldRuleset, name, - null, null, - REMOVED_MESSAGE); - } - - @Nullable String applyExclude(String ref, String name, boolean warn) { - if (oldRuleset.equals(ref) - && oldName.equals(name) - && oldRuleset.equals(newRuleset)) { - if (warn) { - warn(); - } - - return newName; - } - - return name; - } - - @Nullable String applyRef(String ref, boolean warn) { - - if (ref.equals(this.ruleRef)) { - - if (warn) { - warn(); - } - - if (newName != null) { - return newRuleset + "/" + newName; - } else { - // deleted - return null; - } - } - - return ref; - } - - private void warn() { - if (LOG.isWarnEnabled()) { - String log = MessageFormat.format(logMessage, oldRuleset, oldName, newRuleset, newName); - LOG.warn("Applying rule set filter: {}", log); - } - } - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetLoadException.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetLoadException.java deleted file mode 100644 index 4af60a4d22..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetLoadException.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd; - -import org.checkerframework.checker.nullness.qual.NonNull; - -public class RuleSetLoadException extends net.sourceforge.pmd.lang.rule.RuleSetLoadException { - public RuleSetLoadException(RuleSetReferenceId rsetId, @NonNull Throwable cause) { - super(rsetId, cause); - } - - public RuleSetLoadException(RuleSetReferenceId rsetId, String message) { - super(rsetId, message); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetLoader.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetLoader.java deleted file mode 100644 index 20e91f3069..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetLoader.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// Copy from PMD 7 with minimized functionality. -// Only the methods called by maven-pmd-plugin are kept, -// but they do nothing. That means, that maven-pmd-plugin can't report deprecated -// rules properly anymore. -// The ruleset for actual PMD analysis is loaded by PMD itself later on, and not -// through this class. - -package net.sourceforge.pmd; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import net.sourceforge.pmd.lang.rule.RuleSet; - -public final class RuleSetLoader { - public RuleSetLoader warnDeprecated(boolean warn) { - return this; - } - - public List loadFromResources(Collection paths) { - return Collections.emptyList(); - } - - public static RuleSetLoader fromPmdConfig(PMDConfiguration configuration) { - return new RuleSetLoader(); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetReferenceId.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetReferenceId.java deleted file mode 100644 index 0cb348899a..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSetReferenceId.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd; - -public class RuleSetReferenceId extends net.sourceforge.pmd.lang.rule.internal.RuleSetReferenceId { - public RuleSetReferenceId(String id) { - super(id); - } - - public RuleSetReferenceId(String id, RuleSetReferenceId externalRuleSetReferenceId) { - super(id, externalRuleSetReferenceId); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSets.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSets.java deleted file mode 100644 index 7ee5ec4daa..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleSets.java +++ /dev/null @@ -1,222 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// And it is kept in the old package. -// The moved class is in net.sourceforge.pmd.lang.rule.internal - -package net.sourceforge.pmd; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import net.sourceforge.pmd.benchmark.TimeTracker; -import net.sourceforge.pmd.benchmark.TimedOperation; -import net.sourceforge.pmd.benchmark.TimedOperationCategory; -import net.sourceforge.pmd.lang.LanguageProcessorRegistry; -import net.sourceforge.pmd.lang.ast.RootNode; -import net.sourceforge.pmd.lang.document.TextFile; -import net.sourceforge.pmd.lang.rule.InternalApiBridge; -import net.sourceforge.pmd.lang.rule.Rule; -import net.sourceforge.pmd.lang.rule.RuleSet; -import net.sourceforge.pmd.lang.rule.internal.RuleApplicator; -import net.sourceforge.pmd.reporting.FileAnalysisListener; -import net.sourceforge.pmd.util.log.PmdReporter; - -/** - * Grouping of Rules per Language in a RuleSet. - * - * @author pieter_van_raemdonck - Application Engineers NV/SA - www.ae.be - */ -public class RuleSets { - - private final List ruleSets; - - private RuleApplicator ruleApplicator; - - /** - * Copy constructor. Deep copies RuleSets. - * - * @param ruleSets The RuleSets to copy. - */ - public RuleSets(final RuleSets ruleSets) { - List rsets = new ArrayList<>(); - for (final RuleSet rs : ruleSets.ruleSets) { - rsets.add(new RuleSet(rs)); - } - this.ruleSets = Collections.unmodifiableList(rsets); - } - - public RuleSets(Collection ruleSets) { - this.ruleSets = Collections.unmodifiableList(new ArrayList<>(ruleSets)); - } - - /** - * Public constructor. Add the given rule set. - * - * @param ruleSet the RuleSet - */ - public RuleSets(RuleSet ruleSet) { - this.ruleSets = Collections.singletonList(ruleSet); - } - - public void initializeRules(LanguageProcessorRegistry lpReg, PmdReporter reporter) { - // this is abusing the mutability of RuleSet, will go away eventually. - for (RuleSet rset : ruleSets) { - for (Iterator iterator = rset.getRules().iterator(); iterator.hasNext();) { - Rule rule = iterator.next(); - try { - rule.initialize(lpReg.getProcessor(rule.getLanguage())); - } catch (Exception e) { - reporter.errorEx( - "Exception while initializing rule " + rule.getName() + ", the rule will not be run", e); - iterator.remove(); - } - } - } - } - - private RuleApplicator prepareApplicator() { - return RuleApplicator.build(ruleSets.stream().flatMap(it -> it.getRules().stream())::iterator); - } - - /** - * Get all the RuleSets. - * - * @return RuleSet[] - */ - public RuleSet[] getAllRuleSets() { - return ruleSets.toArray(new RuleSet[0]); - } - - // internal - List getRuleSetsInternal() { - return ruleSets; - } - - public Iterator getRuleSetsIterator() { - return ruleSets.iterator(); - } - - /** - * Return all rules from all rulesets. - * - * @return Set - */ - public Set getAllRules() { - Set result = new HashSet<>(); - for (RuleSet r : ruleSets) { - result.addAll(r.getRules()); - } - return result; - } - - /** - * Check if a given source file should be checked by rules in this RuleSets. - * - * @param file - * the source file to check - * @return true if the file should be checked, - * false otherwise - */ - public boolean applies(TextFile file) { - for (RuleSet ruleSet : ruleSets) { - if (InternalApiBridge.ruleSetApplies(ruleSet, file.getFileId())) { - return true; - } - } - return false; - } - - /** - * Apply all applicable rules to the compilation units. Applicable means the - * language of the rules must match the language of the source (@see - * applies). - * - * @param root the List of compilation units; the type these must have, - * depends on the source language - * @param listener Listener that will handle events while analysing. - */ - public void apply(RootNode root, FileAnalysisListener listener) { - if (ruleApplicator == null) { - // initialize here instead of ctor, because some rules properties - // are set after creating the ruleset, and jaxen xpath queries - // initialize their XPath expressions when calling getRuleChainVisits()... fixme - this.ruleApplicator = prepareApplicator(); - } - - try (TimedOperation ignored = TimeTracker.startOperation(TimedOperationCategory.RULE_AST_INDEXATION)) { - ruleApplicator.index(root); - } - - for (RuleSet ruleSet : ruleSets) { - if (InternalApiBridge.ruleSetApplies(ruleSet, root.getTextDocument().getFileId())) { - ruleApplicator.apply(ruleSet.getRules(), listener); - } - } - } - - /** - * Returns the first Rule found with the given name. - * - * Note: Since we support multiple languages, rule names are not expected to - * be unique within any specific ruleset. - * - * @param ruleName - * the exact name of the rule to find - * @return the rule or null if not found - */ - public Rule getRuleByName(String ruleName) { - Rule rule = null; - for (Iterator i = ruleSets.iterator(); i.hasNext() && rule == null;) { - RuleSet ruleSet = i.next(); - rule = ruleSet.getRuleByName(ruleName); - } - return rule; - } - - /** - * Determines the total count of rules that are used in all rule sets. - * - * @return the count - */ - public int ruleCount() { - int count = 0; - for (RuleSet r : ruleSets) { - count += r.getRules().size(); - } - return count; - } - - - /** - * Remove and collect any rules that report problems. - * - * @param collector - */ - public void removeDysfunctionalRules(Collection collector) { - for (RuleSet ruleSet : ruleSets) { - ruleSet.removeDysfunctionalRules(collector); - } - } - - /** - * Retrieves a checksum of the rulesets being used. Any change to any rule - * of any ruleset should trigger a checksum change. - * - * @return The checksum for this ruleset collection. - */ - public long getChecksum() { - long checksum = 1; - for (final RuleSet ruleSet : ruleSets) { - checksum = checksum * 31 + ruleSet.getChecksum(); - } - return checksum; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleViolation.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleViolation.java deleted file mode 100644 index b1d685bf46..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/RuleViolation.java +++ /dev/null @@ -1,203 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: -// - getFilename -// - getRule returns n.s.pmd.rule.Rule or the old n.s.pmd.Rule - -package net.sourceforge.pmd; - -import java.util.Comparator; -import java.util.Map; - -import net.sourceforge.pmd.annotation.DeprecatedUntil700; -import net.sourceforge.pmd.lang.document.FileId; -import net.sourceforge.pmd.lang.document.FileLocation; - -/** - * A RuleViolation is created by a Rule when it identifies a violation of the - * Rule constraints. RuleViolations are simple data holders that are collected - * into a {@link Report}. - * - *

Since PMD 6.21.0, implementations of this interface are considered internal - * API and hence deprecated. Clients should exclusively use this interface. - * - * @see Rule - */ -public interface RuleViolation { - // todo move to package reporting - - /** - * A comparator for rule violations. This compares all exposed attributes - * of a violation, filename first. The remaining parameters are compared - * in an unspecified order. - */ - Comparator DEFAULT_COMPARATOR = - Comparator.comparing(RuleViolation::getFileId) - .thenComparingInt(RuleViolation::getBeginLine) - .thenComparingInt(RuleViolation::getBeginColumn) - .thenComparing(RuleViolation::getDescription, Comparator.nullsLast(Comparator.naturalOrder())) - .thenComparingInt(RuleViolation::getEndLine) - .thenComparingInt(RuleViolation::getEndColumn) - .thenComparing(rv -> rv.getRule().getName()); - - - /** - * Key in {@link #getAdditionalInfo()} for the name of the class in - * which the violation was identified. - */ - String CLASS_NAME = "className"; - /** - * Key in {@link #getAdditionalInfo()} for the name of the variable - * related to the violation. - */ - String VARIABLE_NAME = "variableName"; - /** - * Key in {@link #getAdditionalInfo()} for the name of the method in - * which the violation was identified. - */ - String METHOD_NAME = "methodName"; - /** - * Key in {@link #getAdditionalInfo()} for the name of the package in - * which the violation was identified. - */ - String PACKAGE_NAME = "packageName"; - - /** - * Get the Rule which identified this violation. - * - * @return The identifying Rule. - */ - net.sourceforge.pmd.lang.rule.Rule getRule(); - - /** - * Get the description of this violation. - * - * @return The description. - */ - String getDescription(); - - - /** - * Returns the location where the violation should be reported. - */ - FileLocation getLocation(); - - /** - * Return the ID of the file where the violation was found. - */ - default FileId getFileId() { - return getLocation().getFileId(); - } - - /** - * Get the begin line number in the source file in which this violation was - * identified. - * - * @return Begin line number. - */ - default int getBeginLine() { - return getLocation().getStartPos().getLine(); - } - - /** - * Get the column number of the begin line in the source file in which this - * violation was identified. - * - * @return Begin column number. - */ - default int getBeginColumn() { - return getLocation().getStartPos().getColumn(); - } - - /** - * Get the end line number in the source file in which this violation was - * identified. - * - * @return End line number. - */ - default int getEndLine() { - return getLocation().getEndPos().getLine(); - } - - /** - * Get the column number of the end line in the source file in which this - * violation was identified. - * - * @return End column number. - */ - default int getEndColumn() { - return getLocation().getEndPos().getColumn(); - } - - /** - * A map of additional key-value pairs known about this violation. - * What data is in there is language specific. Common keys supported - * by several languages are defined as constants on this interface. - * The map is unmodifiable. - */ - Map getAdditionalInfo(); - - - /** - * Get the package name of the Class in which this violation was identified. - * - * @return The package name. - * - * @deprecated Use {@link #PACKAGE_NAME} - */ - @Deprecated - @DeprecatedUntil700 - default String getPackageName() { - return getAdditionalInfo().get(PACKAGE_NAME); - } - - /** - * Get the name of the Class in which this violation was identified. - * - * @return The Class name. - * @deprecated Use {@link #CLASS_NAME} - */ - @Deprecated - @DeprecatedUntil700 - default String getClassName() { - return getAdditionalInfo().get(CLASS_NAME); - } - - /** - * Get the method name in which this violation was identified. - * - * @return The method name. - * @deprecated Use {@link #METHOD_NAME} - */ - @Deprecated - @DeprecatedUntil700 - default String getMethodName() { - return getAdditionalInfo().get(METHOD_NAME); - } - - /** - * Get the variable name on which this violation was identified. - * - * @return The variable name. - * @deprecated Use {@link #VARIABLE_NAME} - */ - @Deprecated - @DeprecatedUntil700 - default String getVariableName() { - return getAdditionalInfo().get(VARIABLE_NAME); - } - - // ------------------- compat extensions -------------------- - @Deprecated - default String getFilename() { - return getLocation().getFileId().getFileName(); - } - - // returns the PMD 6 compatible Rule - default net.sourceforge.pmd.Rule getRule$$bridge() { // SUPPRESS CHECKSTYLE ignore - return getRule(); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/annotation/DeprecatedUntil700.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/annotation/DeprecatedUntil700.java deleted file mode 100644 index c74f37fc42..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/annotation/DeprecatedUntil700.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// Moved from pmd-core 7.0.0-SNAPSHOT - -package net.sourceforge.pmd.annotation; - -/** - * Tags a deprecated member that should not be removed before PMD 7.0.0. - * Such members were made deprecated on the PMD 7 development branch and - * may be kept for backwards compatibility on the day of the PMD 7 release, - * because the replacement API cannot be backported to PMD 6. - */ -public @interface DeprecatedUntil700 { -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/AbstractLanguage.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/AbstractLanguage.java deleted file mode 100644 index c6d1d84760..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/AbstractLanguage.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.cpd; - -import java.io.FilenameFilter; -import java.util.Arrays; -import java.util.List; -import java.util.Properties; - -import net.sourceforge.pmd.util.filter.Filters; - -public abstract class AbstractLanguage implements Language { - private final String name; - private final String terseName; - private final Tokenizer tokenizer; - private final FilenameFilter fileFilter; - private final List extensions; - - public AbstractLanguage(String name, String terseName, Tokenizer tokenizer, String... extensions) { - this.name = name; - this.terseName = terseName; - this.tokenizer = tokenizer; - fileFilter = Filters.toFilenameFilter(Filters.getFileExtensionOrDirectoryFilter(extensions)); - this.extensions = Arrays.asList(extensions); - } - - @Override - public FilenameFilter getFileFilter() { - return fileFilter; - } - - @Override - public Tokenizer getTokenizer() { - return tokenizer; - } - - @Override - public void setProperties(Properties properties) { - // needs to be implemented by subclasses. - } - - @Override - public String getName() { - return name; - } - - @Override - public String getTerseName() { - return terseName; - } - - @Override - public List getExtensions() { - return extensions; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/CPD.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/CPD.java deleted file mode 100644 index c570dcec07..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/CPD.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import net.sourceforge.pmd.internal.util.FileFinder; -import net.sourceforge.pmd.internal.util.IOUtil; - -/** - * Adapter for PMD 7. This exposes CPD interface of PMD 6 but runs PMD 7 under the hood. - */ -public class CPD { - private final CPDConfiguration configuration; - private final List files = new ArrayList<>(); - private Set current = new HashSet<>(); - private CPDReport report; - - public CPD(CPDConfiguration configuration) { - this.configuration = configuration; - } - - public void addAllInDirectory(File dir) throws IOException { - addDirectory(dir, false); - } - - public void addRecursively(File dir) throws IOException { - addDirectory(dir, true); - } - - public void add(List files) throws IOException { - for (File f : files) { - add(f); - } - } - - private void addDirectory(File dir, boolean recurse) throws IOException { - if (!dir.exists()) { - throw new FileNotFoundException("Couldn't find directory " + dir); - } - FileFinder finder = new FileFinder(); - // TODO - could use SourceFileSelector here - add(finder.findFilesFrom(dir, configuration.filenameFilter(), recurse)); - } - - public void add(File file) throws IOException { - if (configuration.isSkipDuplicates()) { - // TODO refactor this thing into a separate class - String signature = file.getName() + '_' + file.length(); - if (current.contains(signature)) { - System.err.println("Skipping " + file.getAbsolutePath() - + " since it appears to be a duplicate file and --skip-duplicate-files is set"); - return; - } - current.add(signature); - } - - if (!IOUtil.equalsNormalizedPaths(file.getAbsoluteFile().getCanonicalPath(), file.getAbsolutePath())) { - System.err.println("Skipping " + file + " since it appears to be a symlink"); - return; - } - - if (!file.exists()) { - System.err.println("Skipping " + file + " since it doesn't exist (broken symlink?)"); - return; - } - - files.add(file.toPath()); - } - - public void go() { - try (CpdAnalysis cpd = CpdAnalysis.create(configuration)) { - files.forEach(cpd.files()::addFile); - cpd.performAnalysis(this::collectReport); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void collectReport(CPDReport cpdReport) { - this.report = cpdReport; - } - - public Iterator getMatches() { - return report.getMatches().iterator(); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java deleted file mode 100644 index 34f4764631..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java +++ /dev/null @@ -1,347 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: setLanguage, setSourceEncoding, filenameFilter - -package net.sourceforge.pmd.cpd; - -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.io.File; -import java.io.FilenameFilter; -import java.lang.reflect.Method; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.slf4j.LoggerFactory; - -import net.sourceforge.pmd.AbstractConfiguration; -import net.sourceforge.pmd.cpd.internal.CpdLanguagePropertiesDefaults; -import net.sourceforge.pmd.internal.util.FileFinder; -import net.sourceforge.pmd.internal.util.FileUtil; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.ecmascript.EcmascriptLanguageModule; -import net.sourceforge.pmd.lang.java.JavaLanguageModule; -import net.sourceforge.pmd.lang.jsp.JspLanguageModule; -import net.sourceforge.pmd.util.log.internal.SimpleMessageReporter; - -/** - * - * @author Brian Remedios - * @author Romain Pelisse - <belaran@gmail.com> - */ -public class CPDConfiguration extends AbstractConfiguration { - - public static final String DEFAULT_LANGUAGE = "java"; - public static final String DEFAULT_RENDERER = "text"; - - private static final Map> RENDERERS = new HashMap<>(); - - - static { - RENDERERS.put(DEFAULT_RENDERER, SimpleRenderer.class); - RENDERERS.put("xml", XMLRenderer.class); - RENDERERS.put("csv", CSVRenderer.class); - RENDERERS.put("csv_with_linecount_per_file", CSVWithLinecountPerFileRenderer.class); - RENDERERS.put("vs", VSRenderer.class); - } - - - private int minimumTileSize; - - private boolean skipDuplicates; - - private String rendererName = DEFAULT_RENDERER; - - private @Nullable CPDReportRenderer cpdReportRenderer; - - private boolean ignoreLiterals; - - private boolean ignoreIdentifiers; - - private boolean ignoreAnnotations; - - private boolean ignoreUsings; - - private boolean ignoreLiteralSequences = false; - - private boolean ignoreIdentifierAndLiteralSequences = false; - - private boolean skipLexicalErrors = false; - - private boolean noSkipBlocks = false; - - private String skipBlocksPattern = CpdLanguagePropertiesDefaults.DEFAULT_SKIP_BLOCKS_PATTERN; - - private boolean help; - - private boolean failOnViolation = true; - - - public CPDConfiguration() { - this(LanguageRegistry.CPD); - } - - public CPDConfiguration(LanguageRegistry languageRegistry) { - super(languageRegistry, new SimpleMessageReporter(LoggerFactory.getLogger(CpdAnalysis.class))); - } - - @Override - public void setSourceEncoding(Charset sourceEncoding) { - super.setSourceEncoding(sourceEncoding); - if (cpdReportRenderer != null) { - setRendererEncoding(cpdReportRenderer, sourceEncoding); - } - } - - static CPDReportRenderer createRendererByName(String name, Charset encoding) { - if (name == null || "".equals(name)) { - name = DEFAULT_RENDERER; - } - Class rendererClass = RENDERERS.get(name.toLowerCase(Locale.ROOT)); - if (rendererClass == null) { - Class klass; - try { - klass = Class.forName(name); - if (CPDReportRenderer.class.isAssignableFrom(klass)) { - rendererClass = (Class) klass; - } else { - throw new IllegalArgumentException("Class " + name + " does not implement " + CPDReportRenderer.class); - } - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Cannot find class " + name); - } - } - - CPDReportRenderer renderer; - try { - renderer = rendererClass.getDeclaredConstructor().newInstance(); - setRendererEncoding(renderer, encoding); - } catch (Exception e) { - System.err.println("Couldn't instantiate renderer, defaulting to SimpleRenderer: " + e); - renderer = new SimpleRenderer(); - } - return renderer; - } - - private static void setRendererEncoding(@NonNull Object renderer, Charset encoding) { - try { - PropertyDescriptor encodingProperty = new PropertyDescriptor("encoding", renderer.getClass()); - Method method = encodingProperty.getWriteMethod(); - if (method == null) { - return; - } - if (method.getParameterTypes()[0] == Charset.class) { - method.invoke(renderer, encoding); - } else if (method.getParameterTypes()[0] == String.class) { - method.invoke(renderer, encoding.name()); - } - } catch (IntrospectionException | ReflectiveOperationException ignored) { - // ignored - maybe this renderer doesn't have a encoding property - } - } - - public static Set getRenderers() { - return Collections.unmodifiableSet(RENDERERS.keySet()); - } - - public int getMinimumTileSize() { - return minimumTileSize; - } - - public void setMinimumTileSize(int minimumTileSize) { - this.minimumTileSize = minimumTileSize; - } - - public boolean isSkipDuplicates() { - return skipDuplicates; - } - - public void setSkipDuplicates(boolean skipDuplicates) { - this.skipDuplicates = skipDuplicates; - } - - public String getRendererName() { - return rendererName; - } - - public void setRendererName(String rendererName) { - this.rendererName = rendererName; - if (rendererName == null) { - this.cpdReportRenderer = null; - } - this.cpdReportRenderer = createRendererByName(rendererName, getSourceEncoding()); - } - - - public CPDReportRenderer getCPDReportRenderer() { - return cpdReportRenderer; - } - - void setRenderer(CPDReportRenderer renderer) { - this.cpdReportRenderer = renderer; - } - - public boolean isIgnoreLiterals() { - return ignoreLiterals; - } - - public void setIgnoreLiterals(boolean ignoreLiterals) { - this.ignoreLiterals = ignoreLiterals; - } - - public boolean isIgnoreIdentifiers() { - return ignoreIdentifiers; - } - - public void setIgnoreIdentifiers(boolean ignoreIdentifiers) { - this.ignoreIdentifiers = ignoreIdentifiers; - } - - public boolean isIgnoreAnnotations() { - return ignoreAnnotations; - } - - public void setIgnoreAnnotations(boolean ignoreAnnotations) { - this.ignoreAnnotations = ignoreAnnotations; - } - - public boolean isIgnoreUsings() { - return ignoreUsings; - } - - public void setIgnoreUsings(boolean ignoreUsings) { - this.ignoreUsings = ignoreUsings; - } - - public boolean isIgnoreLiteralSequences() { - return ignoreLiteralSequences; - } - - public void setIgnoreLiteralSequences(boolean ignoreLiteralSequences) { - this.ignoreLiteralSequences = ignoreLiteralSequences; - } - - public boolean isIgnoreIdentifierAndLiteralSequences() { - return ignoreIdentifierAndLiteralSequences; - } - - public void setIgnoreIdentifierAndLiteralSequences(boolean ignoreIdentifierAndLiteralSequences) { - this.ignoreIdentifierAndLiteralSequences = ignoreIdentifierAndLiteralSequences; - } - - public boolean isSkipLexicalErrors() { - return skipLexicalErrors; - } - - public void setSkipLexicalErrors(boolean skipLexicalErrors) { - this.skipLexicalErrors = skipLexicalErrors; - } - - public boolean isHelp() { - return help; - } - - public void setHelp(boolean help) { - this.help = help; - } - - public boolean isNoSkipBlocks() { - return noSkipBlocks; - } - - public void setNoSkipBlocks(boolean noSkipBlocks) { - this.noSkipBlocks = noSkipBlocks; - } - - public String getSkipBlocksPattern() { - return skipBlocksPattern; - } - - public void setSkipBlocksPattern(String skipBlocksPattern) { - this.skipBlocksPattern = skipBlocksPattern; - } - - @Override - public boolean isFailOnViolation() { - return failOnViolation; - } - - @Override - public void setFailOnViolation(boolean failOnViolation) { - this.failOnViolation = failOnViolation; - } - - // ------------------- compat extensions -------------------- - private FilenameFilter filenameFilter; - - public void setLanguage(Language language) { - if (language instanceof JavaLanguage) { - filenameFilter = language.getFileFilter(); - setForceLanguageVersion(JavaLanguageModule.getInstance().getDefaultVersion()); - } else if (language instanceof EcmascriptLanguage) { - filenameFilter = language.getFileFilter(); - setForceLanguageVersion(EcmascriptLanguageModule.getInstance().getDefaultVersion()); - } else if (language instanceof JSPLanguage) { - filenameFilter = language.getFileFilter(); - setForceLanguageVersion(JspLanguageModule.getInstance().getDefaultVersion()); - } else if (language instanceof LanguageFactory.CpdLanguageAdapter) { - filenameFilter = language.getFileFilter(); - setForceLanguageVersion(((LanguageFactory.CpdLanguageAdapter) language).getLanguage().getDefaultVersion()); - } else { - throw new UnsupportedOperationException("Language " + language.getName() + " is not supported"); - } - } - - public void setSourceEncoding(String sourceEncoding) { - setSourceEncoding(Charset.forName(Objects.requireNonNull(sourceEncoding))); - } - - public FilenameFilter filenameFilter() { - if (getForceLanguageVersion() == null) { - throw new IllegalStateException("Language is null."); - } - - final FilenameFilter languageFilter = filenameFilter; - final Set exclusions = new HashSet<>(); - - if (getExcludes() != null) { - FileFinder finder = new FileFinder(); - for (Path excludedFile : getExcludes()) { - if (Files.isDirectory(excludedFile)) { - List files = finder.findFilesFrom(excludedFile.toFile(), languageFilter, true); - for (File f : files) { - exclusions.add(FileUtil.normalizeFilename(f.getAbsolutePath())); - } - } else { - exclusions.add(FileUtil.normalizeFilename(excludedFile.toAbsolutePath().toString())); - } - } - } - - return new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - File f = new File(dir, name); - if (exclusions.contains(FileUtil.normalizeFilename(f.getAbsolutePath()))) { - System.err.println("Excluding " + f.getAbsolutePath()); - return false; - } - return languageFilter.accept(dir, name); - } - }; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/CSVRenderer.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/CSVRenderer.java deleted file mode 100644 index 366386b1c5..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/CSVRenderer.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: implements old interface CPDRenderer, old render(Iterator matches, Writer writer) method - -package net.sourceforge.pmd.cpd; - -import java.io.IOException; -import java.io.Writer; -import java.util.Iterator; - -import org.apache.commons.lang3.StringEscapeUtils; - -import net.sourceforge.pmd.cpd.renderer.CPDRenderer; -import net.sourceforge.pmd.lang.document.FileLocation; - -/** - * Renders a report to CSV. The CSV format renders each match (duplication) - * as a single line with the following columns: - *

    - *
  • lines (optional): The number of lines the first mark of a match spans. - * Only output if the {@code lineCountPerFile} is disabled (see ctor params).
  • - *
  • tokens: The number of duplicated tokens in a match (size of the match).
  • - *
  • occurrences: The number of duplicates in a match (number of times the tokens were found in distinct places).
  • - *
- * - *

Trailing each line are pairs (or triples, if {@code lineCountPerFile} is enabled) - * of fields describing each file where the duplication was found in the format - * {@code (start line, line count (optional), file path)}. These repeat at least twice. - * - *

Examples

- *

- * Example without {@code lineCountPerFile}: - *

{@code
- * lines,tokens,occurrences
- * 10,75,2,48,/var/file1,73,/var/file2
- * }
- * This describes one match with the following characteristics: - *
    - *
  • The first duplicate instance is 10 lines long; - *
  • 75 duplicated tokens; - *
  • 2 duplicate instances; - *
  • The first duplicate instance is in file {@code /var/file1} and starts at line 48;
  • - *
  • The second duplicate instance is in file {@code /var/file2} and starts at line 73.
  • - *
- *

- * Example with {@code lineCountPerFile}: - *

{@code
- * tokens,occurrences
- * 75,2,48,10,/var/file1,73,12,/var/file2
- * }
- * This describes one match with the following characteristics: - *
    - *
  • 75 duplicated tokens - *
  • 2 duplicate instances - *
  • The first duplicate instance is in file {@code /var/file1}, starts at line 48, and is 10 lines long;
  • - *
  • The second duplicate instance is in file {@code /var/file2}, starts at line 73, and is 12 lines long.
  • - *
- */ -public class CSVRenderer implements CPDReportRenderer, CPDRenderer { - - private final char separator; - private final boolean lineCountPerFile; - - public static final char DEFAULT_SEPARATOR = ','; - public static final boolean DEFAULT_LINECOUNTPERFILE = false; - - public CSVRenderer() { - this(DEFAULT_SEPARATOR, DEFAULT_LINECOUNTPERFILE); - } - - public CSVRenderer(boolean lineCountPerFile) { - this(DEFAULT_SEPARATOR, lineCountPerFile); - } - - public CSVRenderer(char separatorChar) { - this(separatorChar, DEFAULT_LINECOUNTPERFILE); - } - - public CSVRenderer(char separatorChar, boolean lineCountPerFile) { - this.separator = separatorChar; - this.lineCountPerFile = lineCountPerFile; - } - - @Override - public void render(CPDReport report, Writer writer) throws IOException { - if (!lineCountPerFile) { - writer.append("lines").append(separator); - } - writer.append("tokens").append(separator).append("occurrences").append(System.lineSeparator()); - - for (Match match : report.getMatches()) { - if (!lineCountPerFile) { - writer.append(String.valueOf(match.getLineCount())).append(separator); - } - writer.append(String.valueOf(match.getTokenCount())).append(separator) - .append(String.valueOf(match.getMarkCount())).append(separator); - for (Iterator marks = match.iterator(); marks.hasNext();) { - Mark mark = marks.next(); - FileLocation loc = mark.getLocation(); - - writer.append(String.valueOf(loc.getStartLine())).append(separator); - if (lineCountPerFile) { - writer.append(String.valueOf(loc.getLineCount())).append(separator); - } - writer.append(StringEscapeUtils.escapeCsv(report.getDisplayName(loc.getFileId()))); - if (marks.hasNext()) { - writer.append(separator); - } - } - writer.append(System.lineSeparator()); - } - writer.flush(); - } - - // ------------------- compat extensions -------------------- - @Override - public void render(Iterator matches, Writer writer) throws IOException { - RendererHelper.render(matches, writer, this); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/EcmascriptLanguage.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/EcmascriptLanguage.java deleted file mode 100644 index ecd2a5a2cf..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/EcmascriptLanguage.java +++ /dev/null @@ -1,17 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.cpd; - -/** - * - * @author Zev Blut zb@ubit.com - */ -public class EcmascriptLanguage extends AbstractLanguage { - public EcmascriptLanguage() { - super("JavaScript", "ecmascript", new EcmascriptTokenizer(), ".js"); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/EcmascriptTokenizer.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/EcmascriptTokenizer.java deleted file mode 100644 index a63b348db2..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/EcmascriptTokenizer.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -public class EcmascriptTokenizer extends net.sourceforge.pmd.lang.ecmascript.cpd.EcmascriptCpdLexer implements Tokenizer { -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JSPLanguage.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JSPLanguage.java deleted file mode 100644 index e1501bad5d..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JSPLanguage.java +++ /dev/null @@ -1,13 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.cpd; - -public class JSPLanguage extends AbstractLanguage { - public JSPLanguage() { - super("JSP", "jsp", new JSPTokenizer(), ".jsp", ".jspx", ".jspf", ".tag"); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JSPTokenizer.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JSPTokenizer.java deleted file mode 100644 index 2e6f8d112b..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JSPTokenizer.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -public class JSPTokenizer extends net.sourceforge.pmd.lang.jsp.cpd.JspCpdLexer implements Tokenizer { -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JavaLanguage.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JavaLanguage.java deleted file mode 100644 index 344a5d9bbc..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JavaLanguage.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 -// Changes: setProperties doesn't work, provide properties in constructor already - -package net.sourceforge.pmd.cpd; - -import java.util.Properties; - -public class JavaLanguage extends AbstractLanguage { - public JavaLanguage() { - this(System.getProperties()); - } - - public JavaLanguage(Properties properties) { - super("Java", "java", new JavaTokenizer(properties), ".java"); - } - - @Override - public final void setProperties(Properties properties) { - // note: this might be actually incompatible - throw new UnsupportedOperationException(); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java deleted file mode 100644 index 39f2013699..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -import java.util.Properties; - -import net.sourceforge.pmd.lang.java.JavaLanguageModule; -import net.sourceforge.pmd.lang.java.internal.JavaLanguageProperties; - -public class JavaTokenizer extends net.sourceforge.pmd.lang.java.cpd.JavaCpdLexer implements Tokenizer { - public JavaTokenizer(Properties properties) { - super(convertLanguageProperties(properties)); - } - - public static final String IGNORE_LITERALS = "ignore_literals"; - public static final String IGNORE_IDENTIFIERS = "ignore_identifiers"; - public static final String IGNORE_ANNOTATIONS = "ignore_annotations"; - - private static JavaLanguageProperties convertLanguageProperties(Properties properties) { - boolean ignoreAnnotations = Boolean.parseBoolean(properties.getProperty(IGNORE_ANNOTATIONS, "false")); - boolean ignoreLiterals = Boolean.parseBoolean(properties.getProperty(IGNORE_LITERALS, "false")); - boolean ignoreIdentifiers = Boolean.parseBoolean(properties.getProperty(IGNORE_IDENTIFIERS, "false")); - - JavaLanguageProperties javaLanguageProperties = (JavaLanguageProperties) JavaLanguageModule.getInstance().newPropertyBundle(); - javaLanguageProperties.setProperty(CpdLanguageProperties.CPD_IGNORE_METADATA, ignoreAnnotations); - javaLanguageProperties.setProperty(CpdLanguageProperties.CPD_ANONYMIZE_LITERALS, ignoreLiterals); - javaLanguageProperties.setProperty(CpdLanguageProperties.CPD_ANONYMIZE_IDENTIFIERS, ignoreIdentifiers); - - return javaLanguageProperties; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/Language.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/Language.java deleted file mode 100644 index d2ee070bb5..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/Language.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.cpd; - -import java.io.FilenameFilter; -import java.util.List; -import java.util.Properties; - -public interface Language { - String getName(); - - String getTerseName(); - - Tokenizer getTokenizer(); - - FilenameFilter getFileFilter(); - - void setProperties(Properties properties); - - List getExtensions(); -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/LanguageFactory.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/LanguageFactory.java deleted file mode 100644 index 8191bcb298..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/LanguageFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class is here just to make maven-pmd-plugin compile with -// pmd 7.0.0 including this compat6 module. -// It would only be used, if a custom language (other than java, jsp or javascript) -// would be requested. - -package net.sourceforge.pmd.cpd; - -import java.util.Properties; -import java.util.stream.Collectors; - -import net.sourceforge.pmd.lang.LanguagePropertyBundle; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.properties.PropertyDescriptor; - -public final class LanguageFactory { - private LanguageFactory() { - // utility class - } - - public static Language createLanguage(String name, Properties properties) { - CpdCapableLanguage cpdLanguage = (CpdCapableLanguage) LanguageRegistry.CPD.getLanguageById(name); - if (cpdLanguage != null) { - return new CpdLanguageAdapter(cpdLanguage, properties); - } - throw new UnsupportedOperationException("Language " + name + " is not supported"); - } - - public static class CpdLanguageAdapter extends AbstractLanguage { - private CpdCapableLanguage language; - - public CpdLanguageAdapter(CpdCapableLanguage cpdCapableLanguage, Properties properties) { - super(cpdCapableLanguage.getName(), cpdCapableLanguage.getId(), createLexer(cpdCapableLanguage, properties), convertExtensions(cpdCapableLanguage)); - this.language = cpdCapableLanguage; - } - - private static Tokenizer createLexer(CpdCapableLanguage cpdCapableLanguage, Properties properties) { - LanguagePropertyBundle propertyBundle = cpdCapableLanguage.newPropertyBundle(); - for (String propName : properties.stringPropertyNames()) { - PropertyDescriptor propertyDescriptor = propertyBundle.getPropertyDescriptor(propName); - if (propertyDescriptor != null) { - setProperty(propertyBundle, propertyDescriptor, properties.getProperty(propName)); - } - } - CpdLexer cpdLexer = cpdCapableLanguage.createCpdLexer(propertyBundle); - return cpdLexer::tokenize; - } - - private static void setProperty(LanguagePropertyBundle propertyBundle, PropertyDescriptor propertyDescriptor, String stringValue) { - T value = propertyDescriptor.serializer().fromString(stringValue); - propertyBundle.setProperty(propertyDescriptor, value); - } - - private static String[] convertExtensions(CpdCapableLanguage cpdCapableLanguage) { - return cpdCapableLanguage.getExtensions().stream().map(s -> "." + s).collect(Collectors.toList()).toArray(new String[0]); - } - - public CpdCapableLanguage getLanguage() { - return language; - } - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/Mark.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/Mark.java deleted file mode 100644 index 2bcfdc15ea..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/Mark.java +++ /dev/null @@ -1,104 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: getFilename - -package net.sourceforge.pmd.cpd; - -import java.util.Objects; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - -import net.sourceforge.pmd.lang.document.FileId; -import net.sourceforge.pmd.lang.document.FileLocation; -import net.sourceforge.pmd.lang.document.TextRange2d; - -/** - * A range of tokens in a source file, identified by a start and end - * token (both included in the range). The start and end token may be - * the same token. - */ -public final class Mark implements Comparable { - - private final @NonNull TokenEntry token; - private @Nullable TokenEntry endToken; - - Mark(@NonNull TokenEntry token) { - this.token = token; - } - - @NonNull TokenEntry getToken() { - return this.token; - } - - @NonNull TokenEntry getEndToken() { - return endToken == null ? token : endToken; - } - - /** - * Return the location of this source range in the source file. - */ - public FileLocation getLocation() { - TokenEntry endToken = getEndToken(); - return FileLocation.range( - getFileId(), - TextRange2d.range2d(token.getBeginLine(), token.getBeginColumn(), - endToken.getEndLine(), endToken.getEndColumn())); - } - - FileId getFileId() { - return token.getFileId(); - } - - public int getBeginTokenIndex() { - return this.token.getIndex(); - } - - public int getEndTokenIndex() { - return getEndToken().getIndex(); - } - - void setEndToken(@NonNull TokenEntry endToken) { - assert endToken.getFileId().equals(token.getFileId()) - : "Tokens are not from the same file"; - this.endToken = endToken; - } - - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + token.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Mark other = (Mark) obj; - return Objects.equals(token, other.token) - && Objects.equals(endToken, other.endToken); - } - - @Override - public int compareTo(Mark other) { - return getToken().compareTo(other.getToken()); - } - - // ------------------- compat extensions -------------------- - public String getFilename() { - return this.token.getFileId().getOriginalPath(); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/RendererHelper.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/RendererHelper.java deleted file mode 100644 index c25a80d964..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/RendererHelper.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -import java.io.IOException; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import net.sourceforge.pmd.lang.document.TextFile; -import net.sourceforge.pmd.lang.java.JavaLanguageModule; - -final class RendererHelper { - private RendererHelper() { - // utility class - } - - static void render(Iterator matches, Writer writer, CPDReportRenderer renderer) throws IOException { - List matchesList = new ArrayList<>(); - matches.forEachRemaining(matchesList::add); - - List textFiles = new ArrayList<>(); - Set paths = new HashSet<>(); - for (Match match : matchesList) { - for (Mark mark : match.getMarkSet()) { - paths.add(mark.getFilename()); - } - } - for (String path : paths) { - textFiles.add(TextFile.forPath(Paths.get(path), StandardCharsets.UTF_8, JavaLanguageModule.getInstance().getDefaultVersion())); - } - - try (SourceManager sourceManager = new SourceManager(textFiles)) { - CPDReport report = new CPDReport(sourceManager, matchesList, Collections.emptyMap(), Collections.emptyList()); - renderer.render(report, writer); - } catch (Exception e) { - throw new RuntimeException(e); - } - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java deleted file mode 100644 index d4aaff8038..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: implements old interface CPDRenderer, old render(Iterator matches, Writer writer) method - -package net.sourceforge.pmd.cpd; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.Iterator; - -import net.sourceforge.pmd.cpd.renderer.CPDRenderer; -import net.sourceforge.pmd.lang.document.Chars; -import net.sourceforge.pmd.lang.document.FileLocation; -import net.sourceforge.pmd.util.StringUtil; - -public class SimpleRenderer implements CPDReportRenderer, CPDRenderer { - - private String separator; - private boolean trimLeadingWhitespace; - - public static final String DEFAULT_SEPARATOR = "====================================================================="; - - public SimpleRenderer() { - this(false); - } - - public SimpleRenderer(boolean trimLeadingWhitespace) { - this(DEFAULT_SEPARATOR); - this.trimLeadingWhitespace = trimLeadingWhitespace; - } - - public SimpleRenderer(String theSeparator) { - separator = theSeparator; - } - - @Override - public void render(CPDReport report, Writer writer0) throws IOException { - PrintWriter writer = new PrintWriter(writer0); - Iterator matches = report.getMatches().iterator(); - if (matches.hasNext()) { - renderOn(report, writer, matches.next()); - } - - while (matches.hasNext()) { - Match match = matches.next(); - writer.println(separator); - renderOn(report, writer, match); - } - writer.flush(); - } - - private void renderOn(CPDReport report, PrintWriter writer, Match match) throws IOException { - - writer.append("Found a ").append(String.valueOf(match.getLineCount())).append(" line (").append(String.valueOf(match.getTokenCount())) - .append(" tokens) duplication in the following files: ").println(); - - for (Mark mark : match) { - FileLocation loc = mark.getLocation(); - writer.append("Starting at line ") - .append(String.valueOf(loc.getStartLine())) - .append(" of ").append(report.getDisplayName(loc.getFileId())) - .println(); - } - - writer.println(); // add a line to separate the source from the desc above - - Chars source = report.getSourceCodeSlice(match.getFirstMark()); - - if (trimLeadingWhitespace) { - for (Chars line : StringUtil.linesWithTrimIndent(source)) { - line.writeFully(writer); - writer.println(); - } - return; - } - - source.writeFully(writer); - writer.println(); - } - - // ------------------- compat extensions -------------------- - @Override - public void render(Iterator matches, Writer writer) throws IOException { - RendererHelper.render(matches, writer, this); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/Tokenizer.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/Tokenizer.java deleted file mode 100644 index ece7fc3618..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/Tokenizer.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -public interface Tokenizer extends CpdLexer { -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java deleted file mode 100644 index 31f2b41d0a..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java +++ /dev/null @@ -1,165 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: implements old interface CPDRenderer, old render(Iterator matches, Writer writer) method - -package net.sourceforge.pmd.cpd; - -import java.io.IOException; -import java.io.Writer; -import java.util.Iterator; -import java.util.Map; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import net.sourceforge.pmd.cpd.renderer.CPDRenderer; -import net.sourceforge.pmd.lang.document.Chars; -import net.sourceforge.pmd.lang.document.FileId; -import net.sourceforge.pmd.lang.document.FileLocation; -import net.sourceforge.pmd.util.StringUtil; - -/** - * @author Philippe T'Seyen - original implementation - * @author Romain Pelisse - javax.xml implementation - * - */ -public final class XMLRenderer implements CPDReportRenderer, CPDRenderer { - - private String encoding; - - /** - * Creates a XML Renderer with the default (platform dependent) encoding. - */ - public XMLRenderer() { - this(null); - } - - /** - * Creates a XML Renderer with a specific output encoding. - * - * @param encoding - * the encoding to use or null. If null, default (platform - * dependent) encoding is used. - */ - public XMLRenderer(String encoding) { - setEncoding(encoding); - } - - public void setEncoding(String encoding) { - if (encoding != null) { - this.encoding = encoding; - } else { - this.encoding = System.getProperty("file.encoding"); - } - } - - public String getEncoding() { - return this.encoding; - } - - private Document createDocument() { - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder parser = factory.newDocumentBuilder(); - return parser.newDocument(); - } catch (ParserConfigurationException e) { - throw new IllegalStateException(e); - } - } - - private void dumpDocToWriter(Document doc, Writer writer) { - try { - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer transformer = tf.newTransformer(); - transformer.setOutputProperty(OutputKeys.VERSION, "1.0"); - transformer.setOutputProperty(OutputKeys.METHOD, "xml"); - transformer.setOutputProperty(OutputKeys.ENCODING, encoding); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "codefragment"); - transformer.transform(new DOMSource(doc), new StreamResult(writer)); - } catch (TransformerException e) { - throw new IllegalStateException(e); - } - } - - - @Override - public void render(final CPDReport report, final Writer writer) throws IOException { - final Document doc = createDocument(); - final Element root = doc.createElement("pmd-cpd"); - final Map numberOfTokensPerFile = report.getNumberOfTokensPerFile(); - doc.appendChild(root); - - for (final Map.Entry pair : numberOfTokensPerFile.entrySet()) { - final Element fileElement = doc.createElement("file"); - fileElement.setAttribute("path", report.getDisplayName(pair.getKey())); - fileElement.setAttribute("totalNumberOfTokens", String.valueOf(pair.getValue())); - root.appendChild(fileElement); - } - - for (Match match : report.getMatches()) { - Element dupElt = createDuplicationElement(doc, match); - addFilesToDuplicationElement(doc, dupElt, match, report); - addCodeSnippet(doc, dupElt, match, report); - root.appendChild(dupElt); - } - dumpDocToWriter(doc, writer); - writer.flush(); - } - - private void addFilesToDuplicationElement(Document doc, Element duplication, Match match, CPDReport report) { - for (Mark mark : match) { - final Element file = doc.createElement("file"); - FileLocation loc = mark.getLocation(); - file.setAttribute("line", String.valueOf(loc.getStartLine())); - // only remove invalid characters, escaping is done by the DOM impl. - String filenameXml10 = StringUtil.removedInvalidXml10Characters(report.getDisplayName(loc.getFileId())); - file.setAttribute("path", filenameXml10); - file.setAttribute("endline", String.valueOf(loc.getEndLine())); - file.setAttribute("column", String.valueOf(loc.getStartColumn())); - file.setAttribute("endcolumn", String.valueOf(loc.getEndColumn())); - file.setAttribute("begintoken", String.valueOf(mark.getBeginTokenIndex())); - file.setAttribute("endtoken", String.valueOf(mark.getEndTokenIndex())); - duplication.appendChild(file); - } - } - - private void addCodeSnippet(Document doc, Element duplication, Match match, CPDReport report) { - Chars codeSnippet = report.getSourceCodeSlice(match.getFirstMark()); - if (codeSnippet != null) { - // the code snippet has normalized line endings - String platformSpecific = codeSnippet.toString().replace("\n", System.lineSeparator()); - Element codefragment = doc.createElement("codefragment"); - // only remove invalid characters, escaping is not necessary in CDATA. - // if the string contains the end marker of a CDATA section, then the DOM impl will - // create two cdata sections automatically. - codefragment.appendChild(doc.createCDATASection(StringUtil.removedInvalidXml10Characters(platformSpecific))); - duplication.appendChild(codefragment); - } - } - - private Element createDuplicationElement(Document doc, Match match) { - Element duplication = doc.createElement("duplication"); - duplication.setAttribute("lines", String.valueOf(match.getLineCount())); - duplication.setAttribute("tokens", String.valueOf(match.getTokenCount())); - return duplication; - } - - // ------------------- compat extensions -------------------- - @Override - public void render(Iterator matches, Writer writer) throws IOException { - RendererHelper.render(matches, writer, this); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/renderer/CPDRenderer.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/renderer/CPDRenderer.java deleted file mode 100644 index 5776309eba..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/cpd/renderer/CPDRenderer.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.cpd.renderer; - -import java.io.IOException; -import java.io.Writer; -import java.util.Iterator; - -import net.sourceforge.pmd.cpd.Match; - -/** - * @deprecated Use {@link net.sourceforge.pmd.cpd.CPDReportRenderer} - */ -@Deprecated -public interface CPDRenderer { - void render(Iterator matches, Writer writer) throws IOException; -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/LanguageRegistry.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/LanguageRegistry.java deleted file mode 100644 index 8cf677dabd..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/LanguageRegistry.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: The following methods are still here, but deleted in 7.0.0 -// LanguageRegistry#getLanguage -// LanguageRegistry#findLanguageByTerseName -// LanguageRegistry#findByExtension - -package net.sourceforge.pmd.lang; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; -import java.util.Set; -import java.util.TreeSet; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import net.sourceforge.pmd.annotation.DeprecatedUntil700; -import net.sourceforge.pmd.cpd.CpdCapableLanguage; -import net.sourceforge.pmd.util.CollectionUtil; - -/** - * A set of languages with convenient methods. In the PMD CLI, languages - * are loaded from the classloader of this class. These are in the registry - * {@link #PMD}. You can otherwise create different registries with different - * languages, eg filter some out. - */ -public final class LanguageRegistry implements Iterable { - - private static final Logger LOG = LoggerFactory.getLogger(LanguageRegistry.class); - - private static final LanguageRegistry ALL_LANGUAGES = - loadLanguages(LanguageRegistry.class.getClassLoader()); - - /** - * Contains the languages that support PMD and are found on the classpath - * of the classloader of this class. This can be used as a "default" registry. - */ - public static final LanguageRegistry PMD = ALL_LANGUAGES.filter(it -> it instanceof PmdCapableLanguage); - - /** - * Contains the languages that support CPD and are found on the classpath - * of the classloader of this class. - */ - public static final LanguageRegistry CPD = ALL_LANGUAGES.filter(it -> it instanceof CpdCapableLanguage); - - private final Set languages; - - private final Map languagesById; - private final Map languagesByFullName; - - /** - * Create a new registry that contains the given set of languages. - * @throws NullPointerException If the parameter is null - */ - public LanguageRegistry(Set languages) { - this.languages = languages.stream() - .sorted(Comparator.comparing(Language::getId, String::compareToIgnoreCase)) - .collect(CollectionUtil.toUnmodifiableSet()); - this.languagesById = CollectionUtil.associateBy(languages, Language::getId); - this.languagesByFullName = CollectionUtil.associateBy(languages, Language::getName); - } - - /** - * Create a new registry with the languages that satisfy the predicate. - */ - public LanguageRegistry filter(Predicate filterFun) { - return new LanguageRegistry(languages.stream().filter(filterFun) - .collect(Collectors.toSet())); - } - - /** - * Creates a language registry containing a single language. Note - * that this may be inconvertible to a {@link LanguageProcessorRegistry} - * if the language depends on other languages. - */ - public static LanguageRegistry singleton(Language l) { - return new LanguageRegistry(Collections.singleton(l)); - } - - /** - * Creates a language registry containing the given language and - * its dependencies, fetched from this language registry or the - * parameter. - * - * @throws IllegalStateException If dependencies cannot be fulfilled. - */ - public LanguageRegistry getDependenciesOf(Language lang) { - Set result = new HashSet<>(); - result.add(lang); - addDepsOrThrow(lang, result); - return new LanguageRegistry(result); - } - - private void addDepsOrThrow(Language l, Set languages) { - for (String depId : l.getDependencies()) { - Language dep = getLanguageById(depId); - if (dep == null) { - throw new IllegalStateException( - "Cannot find language " + depId + " in " + this); - } - if (languages.add(dep)) { - addDepsOrThrow(dep, languages); - } - } - } - - @Override - public @NonNull Iterator iterator() { - return languages.iterator(); - } - - /** - * Create a new registry by loading the languages registered via {@link ServiceLoader} - * on the classpath of the given classloader. - * - * @param classLoader A classloader - */ - public static @NonNull LanguageRegistry loadLanguages(ClassLoader classLoader) { - // sort languages by terse name. Avoiding differences in the order of languages - // across JVM versions / OS. - Set languages = new TreeSet<>(Comparator.comparing(Language::getId, String::compareToIgnoreCase)); - ServiceLoader languageLoader = ServiceLoader.load(Language.class, classLoader); - Iterator iterator = languageLoader.iterator(); - while (true) { - // this loop is weird, but both hasNext and next may throw ServiceConfigurationError, - // it's more robust that way - try { - if (iterator.hasNext()) { - Language language = iterator.next(); - languages.add(language); - } else { - break; - } - } catch (UnsupportedClassVersionError | ServiceConfigurationError e) { - // Some languages require java8 and are therefore only available - // if java8 or later is used as runtime. - LOG.warn("Cannot load PMD language, ignored", e); - } - } - return new LanguageRegistry(languages); - } - - /** - * Returns a set of all the known languages. The ordering of the languages - * is by terse name. - */ - public Set getLanguages() { - return languages; - } - - /** - * Returns a language from its {@linkplain Language#getName() full name} - * (eg {@code "Java"}). This is case sensitive. - * - * @param languageName Language name - * - * @return A language, or null if the name is unknown - * - * @deprecated Use {@link #getLanguageByFullName(String) LanguageRegistry.PMD.getLanguageByFullName} - */ - @Deprecated - @DeprecatedUntil700 - public static Language getLanguage(String languageName) { - return PMD.getLanguageByFullName(languageName); - } - - /** - * Returns a language from its {@linkplain Language#getId() ID} - * (eg {@code "java"}). This is case-sensitive. - * - * @param langId Language ID - * - * @return A language, or null if the name is unknown, or the parameter is null - */ - public @Nullable Language getLanguageById(@Nullable String langId) { - return languagesById.get(langId); - } - - /** - * Returns a language version from its {@linkplain Language#getId() language ID} - * (eg {@code "java"}). This is case-sensitive. - * - * @param langId Language ID - * @param version Version ID - * - * @return A language, or null if the name is unknown - */ - public @Nullable LanguageVersion getLanguageVersionById(@Nullable String langId, @Nullable String version) { - Language lang = languagesById.get(langId); - if (lang == null) { - return null; - } - return version == null ? lang.getDefaultVersion() - : lang.getVersion(version); - } - - /** - * Returns a language from its {@linkplain Language#getName() full name} - * (eg {@code "Java"}). This is case sensitive. - * - * @param languageName Language name - * - * @return A language, or null if the name is unknown - */ - public @Nullable Language getLanguageByFullName(String languageName) { - return languagesByFullName.get(languageName); - } - - /** - * Returns a language from its {@linkplain Language#getId() terse name} - * (eg {@code "java"}). This is case sensitive. - * - * @param terseName Language terse name - * - * @return A language, or null if the name is unknown - * - * @deprecated Use {@link #getLanguageById(String) LanguageRegistry.PMD.getLanguageById}. - */ - @Deprecated - @DeprecatedUntil700 - public static @Nullable Language findLanguageByTerseName(@Nullable String terseName) { - return PMD.getLanguageById(terseName); - } - - /** - * Returns all languages that support the given extension. - * - * @param extensionWithoutDot A file extension (without '.' prefix) - * - * @deprecated Not replaced, extension will be extended to match full name in PMD 7. - */ - @Deprecated - @DeprecatedUntil700 - public static List findByExtension(String extensionWithoutDot) { - List languages = new ArrayList<>(); - for (Language language : PMD.getLanguages()) { - if (language.hasExtension(extensionWithoutDot)) { - languages.add(language); - } - } - return languages; - } - - /** - * Formats the set of languages with the given formatter, sort and - * join everything with commas. Convenience method. - */ - public @NonNull String commaSeparatedList(Function languageToString) { - return getLanguages().stream().map(languageToString).sorted().collect(Collectors.joining(", ")); - } - - @Override - public String toString() { - return "LanguageRegistry(" + commaSeparatedList(Language::getId) + ")"; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/Rule.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/Rule.java deleted file mode 100644 index a152534e5f..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/Rule.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// The class net.sourceforge.pmd.Rule has been moved into sub-package rule -// in 7.0.0-SNAPSHOT. All rules should be interchangeable. - -package net.sourceforge.pmd.lang.rule; - -public interface Rule extends net.sourceforge.pmd.Rule { -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java deleted file mode 100644 index 5cc43b7131..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// Copied from 7.0.0-SNAPSHOT -// Changes: constructors are public again - -package net.sourceforge.pmd.lang.rule; - -import org.checkerframework.checker.nullness.qual.NonNull; - -import net.sourceforge.pmd.lang.rule.internal.RuleSetReferenceId; - -/** - * An exception that is thrown when something wrong occurs while - * {@linkplain RuleSetLoader loading rulesets}. This may be because the - * XML is not well-formed, does not respect the ruleset schema, is - * not a valid ruleset or is otherwise unparsable. - */ -public class RuleSetLoadException extends RuntimeException { - - /** - * @apiNote Internal API. - */ - public RuleSetLoadException(RuleSetReferenceId rsetId, @NonNull Throwable cause) { - super("Cannot load ruleset " + rsetId + ": " + cause.getMessage(), cause); - } - - /** - * @apiNote Internal API. - */ - public RuleSetLoadException(RuleSetReferenceId rsetId, String message) { - super("Cannot load ruleset " + rsetId + ": " + message); - } - -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/XPathRule.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/XPathRule.java deleted file mode 100644 index eb11ac7e77..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/XPathRule.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.rule; - -public class XPathRule extends net.sourceforge.pmd.lang.rule.xpath.XPathRule { -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java deleted file mode 100644 index dbf505107a..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.rule.internal; - -import java.util.Collection; - -import net.sourceforge.pmd.lang.rule.RuleSet; - -public class RuleSets extends net.sourceforge.pmd.RuleSets { - public RuleSets(net.sourceforge.pmd.RuleSets ruleSets) { - super(ruleSets); - } - - public RuleSets(net.sourceforge.pmd.lang.rule.internal.RuleSets ruleSets) { - super(ruleSets); - } - - public RuleSets(Collection ruleSets) { - super(ruleSets); - } - - public RuleSets(RuleSet ruleSet) { - super(ruleSet); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/xpath/XPathRule.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/xpath/XPathRule.java deleted file mode 100644 index 6f567f1ed7..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/lang/rule/xpath/XPathRule.java +++ /dev/null @@ -1,190 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: not final anymore to allow a subclass in the old package - -package net.sourceforge.pmd.lang.rule.xpath; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.exception.ContextedRuntimeException; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import net.sourceforge.pmd.lang.LanguageProcessor; -import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.rule.AbstractRule; -import net.sourceforge.pmd.lang.rule.Rule; -import net.sourceforge.pmd.lang.rule.RuleTargetSelector; -import net.sourceforge.pmd.lang.rule.xpath.internal.DeprecatedAttrLogger; -import net.sourceforge.pmd.lang.rule.xpath.internal.SaxonXPathRuleQuery; -import net.sourceforge.pmd.properties.PropertyDescriptor; -import net.sourceforge.pmd.properties.PropertyFactory; -import net.sourceforge.pmd.reporting.RuleContext; -import net.sourceforge.pmd.util.IteratorUtil; - - -/** - * Rule that tries to match an XPath expression against a DOM view of an AST. - */ -public /*final*/ class XPathRule extends AbstractRule { - - private static final Logger LOG = LoggerFactory.getLogger(XPathRule.class); - - /** - * @deprecated Use {@link #XPathRule(XPathVersion, String)} - */ - @Deprecated - public static final PropertyDescriptor XPATH_DESCRIPTOR = - PropertyFactory.stringProperty("xpath") - .desc("XPath expression") - .defaultValue("") - .build(); - - /** - * This is initialized only once when calling {@link #apply(Node, RuleContext)} or {@link #getTargetSelector()}. - */ - private SaxonXPathRuleQuery xpathRuleQuery; - - - // this is shared with rules forked by deepCopy, used by the XPathRuleQuery - private DeprecatedAttrLogger attrLogger = DeprecatedAttrLogger.create(this); - - - /** - * @deprecated This is now only used by the ruleset loader. When - * we have syntactic sugar for XPath rules in the XML, we won't - * need this anymore. - */ - @Deprecated - public XPathRule() { - definePropertyDescriptor(XPATH_DESCRIPTOR); - } - - /** - * Make a new XPath rule with the given version + expression - * - * @param version Version of the XPath language - * @param expression XPath expression - * - * @throws NullPointerException If any of the arguments is null - */ - public XPathRule(XPathVersion version, String expression) { - this(); - - Objects.requireNonNull(version, "XPath version is null"); - Objects.requireNonNull(expression, "XPath expression is null"); - - setProperty(XPathRule.XPATH_DESCRIPTOR, expression); - } - - - @Override - public Rule deepCopy() { - XPathRule rule = (XPathRule) super.deepCopy(); - rule.attrLogger = this.attrLogger; - return rule; - } - - /** - * Returns the XPath expression that implements this rule. - */ - public String getXPathExpression() { - return getProperty(XPATH_DESCRIPTOR); - } - - - @Override - public void apply(Node target, RuleContext ctx) { - SaxonXPathRuleQuery query = getQueryMaybeInitialize(); - - List nodesWithViolation; - try { - nodesWithViolation = query.evaluate(target); - } catch (PmdXPathException e) { - throw addExceptionContext(e); - } - - for (Node nodeWithViolation : nodesWithViolation) { - // see Deprecate getImage/@Image #4787 https://github.com/pmd/pmd/issues/4787 - String messageArg = nodeWithViolation.getImage(); - // Nodes might already have been refactored to not use getImage anymore. - // Therefore, try several other common names - if (messageArg == null) { - messageArg = getFirstMessageArgFromNode(nodeWithViolation, "Name", "SimpleName", "MethodName"); - } - ctx.addViolation(nodeWithViolation, messageArg); - } - } - - private String getFirstMessageArgFromNode(Node node, String... attributeNames) { - List nameList = Arrays.asList(attributeNames); - return IteratorUtil.toStream(node.getXPathAttributesIterator()) - .filter(a -> nameList.contains(a.getName())) - .findFirst() - .map(Attribute::getStringValue) - .orElse(null); - } - - private ContextedRuntimeException addExceptionContext(PmdXPathException e) { - return e.addRuleName(getName()); - } - - @Override - public void initialize(LanguageProcessor languageProcessor) { - String xpath = getXPathExpression(); - XPathVersion version = XPathVersion.DEFAULT; - - try { - xpathRuleQuery = new SaxonXPathRuleQuery(xpath, - version, - getPropertiesByPropertyDescriptor(), - languageProcessor.services().getXPathHandler(), - attrLogger); - } catch (PmdXPathException e) { - throw addExceptionContext(e); - } - } - - private SaxonXPathRuleQuery getQueryMaybeInitialize() throws PmdXPathException { - if (xpathRuleQuery == null) { - throw new IllegalStateException("Not initialized"); - } - return xpathRuleQuery; - } - - - @Override - protected @NonNull RuleTargetSelector buildTargetSelector() { - - List visits = getQueryMaybeInitialize().getRuleChainVisits(); - - logXPathRuleChainUsage(!visits.isEmpty()); - - return visits.isEmpty() ? RuleTargetSelector.forRootOnly() - : RuleTargetSelector.forXPathNames(visits); - } - - - private void logXPathRuleChainUsage(boolean usesRuleChain) { - LOG.debug("{} rule chain for XPath rule: {} ({})", - usesRuleChain ? "Using" : "no", - getName(), - getRuleSetName()); - } - - - @Override - public String dysfunctionReason() { - if (StringUtils.isBlank(getXPathExpression())) { - return "Missing XPath expression"; - } - return null; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/renderers/Renderer.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/renderers/Renderer.java deleted file mode 100644 index 3013dbc7d1..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/renderers/Renderer.java +++ /dev/null @@ -1,288 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT -// Changes: renderFileReport - -package net.sourceforge.pmd.renderers; - -import java.io.IOException; -import java.io.Writer; - -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.lang.document.TextFile; -import net.sourceforge.pmd.properties.PropertyDescriptor; -import net.sourceforge.pmd.properties.PropertySource; -import net.sourceforge.pmd.reporting.FileAnalysisListener; -import net.sourceforge.pmd.reporting.FileNameRenderer; -import net.sourceforge.pmd.reporting.GlobalAnalysisListener; -import net.sourceforge.pmd.reporting.ListenerInitializer; -import net.sourceforge.pmd.reporting.Report; -import net.sourceforge.pmd.reporting.Report.ConfigurationError; -import net.sourceforge.pmd.reporting.Report.GlobalReportBuilderListener; -import net.sourceforge.pmd.reporting.Report.ProcessingError; -import net.sourceforge.pmd.reporting.Report.ReportBuilderListener; -import net.sourceforge.pmd.reporting.Report.SuppressedViolation; -import net.sourceforge.pmd.reporting.RuleViolation; - -/** - * This is an interface for rendering a Report. When a Renderer is being - * invoked, the sequence of method calls is something like the following: - *
    - *
  1. Renderer construction/initialization
  2. - *
  3. {@link Renderer#setShowSuppressedViolations(boolean)}
  4. - *
  5. {@link Renderer#setWriter(Writer)}
  6. - *
  7. {@link Renderer#start()}
  8. - *
  9. {@link Renderer#startFileAnalysis(TextFile)} for each source file - * processed
  10. - *
  11. {@link Renderer#renderFileReport(Report)} for each Report instance
  12. - *
  13. {@link Renderer#end()}
  14. - *
- *

- * An implementation of the Renderer interface is expected to have a default - * constructor. Properties should be defined using the - * {@link #definePropertyDescriptor(PropertyDescriptor)} - * method. After the instance is created, the property values are set. This - * means, you won't have access to property values in your constructor. - */ -// TODO Are implementations expected to be thread-safe? -public interface Renderer extends PropertySource { - - /** - * Get the name of the Renderer. - * - * @return The name of the Renderer. - */ - @Override - String getName(); - - /** - * Set the name of the Renderer. - * - * @param name - * The name of the Renderer. - */ - void setName(String name); - - /** - * Get the description of the Renderer. - * - * @return The description of the Renderer. - */ - String getDescription(); - - /** - * Return the default filename extension to use. - * - * @return String - */ - String defaultFileExtension(); - - /** - * Set the description of the Renderer. - * - * @param description - * The description of the Renderer. - */ - void setDescription(String description); - - /** - * Get the indicator for whether to show suppressed violations. - * - * @return true if suppressed violations should show, - * false otherwise. - */ - boolean isShowSuppressedViolations(); - - /** - * Set the indicator for whether to show suppressed violations. - * - * @param showSuppressedViolations - * Whether to show suppressed violations. - */ - void setShowSuppressedViolations(boolean showSuppressedViolations); - - /** - * Get the Writer for the Renderer. - * - * @return The Writer. - */ - Writer getWriter(); - - /** - * Set the {@link FileNameRenderer} used to render file paths to the report. - * Note that this renderer does not have to use the parameter to output paths. - * Some report formats require a specific format for paths (eg a URI), and are - * allowed to circumvent the provided strategy. - * - * @param fileNameRenderer a non-null file name renderer - */ - void setFileNameRenderer(FileNameRenderer fileNameRenderer); - - /** - * Set the Writer for the Renderer. - * - * @param writer The Writer. - */ - void setWriter(Writer writer); - - /** - * This method is called before any source files are processed. The Renderer - * will have been fully initialized by the time this method is called, so - * the Writer and other state will be available. - * - * @throws IOException - */ - void start() throws IOException; - - /** - * This method is called each time a source file is processed. It is called - * after {@link Renderer#start()}, but before - * {@link Renderer#renderFileReport(Report)} and {@link Renderer#end()}. - * - * This method may be invoked by different threads which are processing - * files independently. Therefore, any non-trivial implementation of this - * method needs to be thread-safe. - * - * @param dataSource - * The source file. - */ - void startFileAnalysis(TextFile dataSource); - - /** - * Render the given file Report. There may be multiple Report instances - * which need to be rendered if produced by different threads. It is called - * after {@link Renderer#start()} and - * {@link Renderer#startFileAnalysis(TextFile)}, but before - * {@link Renderer#end()}. - * - * @param report - * A file Report. - * @throws IOException - * - * @see Report - */ - void renderFileReport(Report report) throws IOException; - - /** - * This method is at the very end of the Rendering process, after - * {@link Renderer#renderFileReport(Report)}. - */ - void end() throws IOException; - - void flush() throws IOException; - - /** - * Sets the filename where the report should be written to. If no filename is provided, - * the renderer should write to stdout. - * - *

Implementations must initialize the writer of the renderer. - * - *

See {@link AbstractRenderer#setReportFile(String)} for the default impl. - * - * @param reportFilename the filename (optional). - */ - @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() throws IOException { - try (TimedOperation ignored = TimeTracker.startOperation(TimedOperationCategory.REPORTING)) { - this.start(); - } - - return new GlobalAnalysisListener() { - - // guard for the close routine - final Object reportMergeLock = new Object(); - - final GlobalReportBuilderListener configErrorReport = new GlobalReportBuilderListener(); - - @Override - public void onConfigError(ConfigurationError error) { - configErrorReport.onConfigError(error); - } - - @Override - public ListenerInitializer initializer() { - return new ListenerInitializer() { - @Override - public void setFileNameRenderer(FileNameRenderer fileNameRenderer) { - Renderer.this.setFileNameRenderer(fileNameRenderer); - } - }; - } - - @Override - public FileAnalysisListener startFileAnalysis(TextFile file) { - Renderer renderer = Renderer.this; - - renderer.startFileAnalysis(file); // this routine is thread-safe by contract - return new FileAnalysisListener() { - 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(); - synchronized (reportMergeLock) { - // TODO renderFileReport should be thread-safe instead - try (TimedOperation ignored = TimeTracker.startOperation(TimedOperationCategory.REPORTING)) { - renderer.renderFileReport(reportBuilder.getResult()); - } - } - } - - @Override - public String toString() { - return "FileRendererListener[" + Renderer.this + "]"; - } - }; - } - - @Override - public void close() throws Exception { - configErrorReport.close(); - Renderer.this.renderFileReport(configErrorReport.getResult()); - try (TimedOperation ignored = TimeTracker.startOperation(TimedOperationCategory.REPORTING)) { - end(); - flush(); - } - } - }; - } - - // --- compat - default void renderFileReport(net.sourceforge.pmd.Report report) throws IOException { - Report newReport = new Report(); - newReport.merge(report); - renderFileReport(newReport); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/reporting/Report.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/reporting/Report.java deleted file mode 100644 index db6ae84f83..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/reporting/Report.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.reporting; - -import java.util.function.Predicate; - -import net.sourceforge.pmd.Rule; -import net.sourceforge.pmd.lang.document.FileId; - -public class Report extends net.sourceforge.pmd.Report { - - public static class ConfigurationError extends net.sourceforge.pmd.Report.ConfigurationError { - public ConfigurationError(Rule theRule, String theIssue) { - super(theRule, theIssue); - } - - @Override - public net.sourceforge.pmd.lang.rule.Rule rule() { - return (net.sourceforge.pmd.lang.rule.Rule) super.rule(); - } - } - - public static class ProcessingError extends net.sourceforge.pmd.Report.ProcessingError { - public ProcessingError(Throwable error, FileId file) { - super(error, file); - } - } - - public static class SuppressedViolation extends net.sourceforge.pmd.Report.SuppressedViolation { - private final RuleViolation rv; - - public SuppressedViolation(RuleViolation rv, ViolationSuppressor suppressor, String userMessage) { - super(rv, suppressor, userMessage); - this.rv = rv; - } - - @Override - public net.sourceforge.pmd.reporting.RuleViolation getRuleViolation() { - return rv; - } - } - - public static final class GlobalReportBuilderListener extends net.sourceforge.pmd.Report.GlobalReportBuilderListener { - } - - public static final class ReportBuilderListener extends net.sourceforge.pmd.Report.ReportBuilderListener { - } - - @Override - public Report filterViolations(Predicate filter) { - Report copy = new Report(); - - for (net.sourceforge.pmd.RuleViolation violation : violations) { - if (filter.test(violation)) { - copy.addRuleViolation(violation); - } - } - - copy.suppressedRuleViolations.addAll(suppressedRuleViolations); - copy.errors.addAll(errors); - copy.configErrors.addAll(configErrors); - return copy; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java deleted file mode 100644 index d501b9820e..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.reporting; - -public interface RuleViolation extends net.sourceforge.pmd.RuleViolation { -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/Predicate.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/Predicate.java deleted file mode 100644 index a6d0e68ce1..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/Predicate.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This class has been taken from 7.0.0-SNAPSHOT - -package net.sourceforge.pmd.util; - -/** - * Simple predicate of one argument. - * - * @param the type of the input to the predicate - */ -//@Experimental -public interface Predicate { - - boolean test(T t); -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/AbstractCompoundFilter.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/AbstractCompoundFilter.java deleted file mode 100644 index 851c4bb492..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/AbstractCompoundFilter.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.util.filter; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * A base class for Filters which implements behavior using a List of other - * Filters. - * - * @param - * The underlying type on which the filter applies. - * @deprecated See {@link Filter} - */ -@Deprecated -public abstract class AbstractCompoundFilter implements Filter { - - protected List> filters; - - public AbstractCompoundFilter() { - filters = new ArrayList<>(2); - } - - public AbstractCompoundFilter(Filter... filters) { - this.filters = Arrays.asList(filters); - } - - public List> getFilters() { - return filters; - } - - public void setFilters(List> filters) { - this.filters = filters; - } - - public void addFilter(Filter filter) { - filters.add(filter); - } - - protected abstract String getOperator(); - - @Override - public String toString() { - - if (filters.isEmpty()) { - return "()"; - } - - StringBuilder builder = new StringBuilder(); - builder.append('(').append(filters.get(0)); - - for (int i = 1; i < filters.size(); i++) { - builder.append(' ').append(getOperator()).append(' '); - builder.append(filters.get(i)); - } - builder.append(')'); - return builder.toString(); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/AbstractDelegateFilter.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/AbstractDelegateFilter.java deleted file mode 100644 index e6ca4e47d2..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/AbstractDelegateFilter.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.util.filter; - -/** - * A base class for Filters which implements behavior using delegation to an - * underlying filter. - * - * @param - * The underlying type on which the filter applies. - * @deprecated See {@link Filter} - */ -@Deprecated -public abstract class AbstractDelegateFilter implements Filter { - protected Filter filter; - - public AbstractDelegateFilter() { - // default constructor - } - - public AbstractDelegateFilter(Filter filter) { - this.filter = filter; - } - - public Filter getFilter() { - return filter; - } - - public void setFilter(Filter filter) { - this.filter = filter; - } - - // Subclass should override to do something other the simply delegate. - @Override - public boolean filter(T obj) { - return filter.filter(obj); - } - - // Subclass should override to do something other the simply delegate. - @Override - public String toString() { - return filter.toString(); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/AndFilter.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/AndFilter.java deleted file mode 100644 index be8ff31fea..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/AndFilter.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.util.filter; - -/** - * A logical AND of a list of Filters. This implementation is short circuiting. - * - * @param - * The underlying type on which the filter applies. - * @deprecated See {@link Filter} - */ -@Deprecated -public class AndFilter extends AbstractCompoundFilter { - - public AndFilter() { - super(); - } - - public AndFilter(Filter... filters) { - super(filters); - } - - @Override - public boolean filter(T obj) { - boolean match = true; - for (Filter filter : filters) { - if (!filter.filter(obj)) { - match = false; - break; - } - } - return match; - } - - @Override - protected String getOperator() { - return "and"; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/DirectoryFilter.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/DirectoryFilter.java deleted file mode 100644 index c1669e91d3..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/DirectoryFilter.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.util.filter; - -import java.io.File; - -/** - * Directory filter. - * @deprecated See {@link Filter} - */ -@Deprecated -public final class DirectoryFilter implements Filter { - public static final DirectoryFilter INSTANCE = new DirectoryFilter(); - - private DirectoryFilter() { - } - - @Override - public boolean filter(File file) { - return file.isDirectory(); - } - - @Override - public String toString() { - return "is Directory"; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/FileExtensionFilter.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/FileExtensionFilter.java deleted file mode 100644 index 06259afce3..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/FileExtensionFilter.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.util.filter; - -import java.io.File; -import java.util.Locale; - -/** - * @deprecated See {@link Filter} - */ -@Deprecated -public class FileExtensionFilter implements Filter { - protected final String[] extensions; - protected final boolean ignoreCase; - - /** - * Matches any files with the given extensions, ignoring case - */ - public FileExtensionFilter(String... extensions) { - this(true, extensions); - } - - /** - * Matches any files with the given extensions, optionally ignoring case. - */ - public FileExtensionFilter(boolean ignoreCase, String... extensions) { - this.extensions = extensions; - this.ignoreCase = ignoreCase; - if (ignoreCase) { - for (int i = 0; i < this.extensions.length; i++) { - this.extensions[i] = this.extensions[i].toUpperCase(Locale.ROOT); - } - } - } - - @Override - public boolean filter(File file) { - boolean accept = extensions == null; - if (!accept) { - for (String extension : extensions) { - String name = file.getName(); - if (ignoreCase ? name.toUpperCase(Locale.ROOT).endsWith(extension) : name.endsWith(extension)) { - accept = true; - break; - } - } - } - return accept; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/Filter.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/Filter.java deleted file mode 100644 index e99a14bb44..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/Filter.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.util.filter; - -/** - * A Filter interface, used for filtering arbitrary objects. - * - * @param - * The underlying type on which the filter applies. - * - * @deprecated Will be replaced with standard java.util.function.Predicate with 7.0.0 - */ -@Deprecated -public interface Filter { - boolean filter(T obj); -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/Filters.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/Filters.java deleted file mode 100644 index 699b614308..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/Filters.java +++ /dev/null @@ -1,245 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.util.filter; - -import java.io.File; -import java.io.FilenameFilter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import net.sourceforge.pmd.annotation.InternalApi; - -/** - * Utility class for working with Filters. Contains builder style methods, apply - * methods, as well as mechanisms for adapting Filters and FilenameFilters. - * - * @deprecated Internal API, see {@link Filter} - */ -@Deprecated -@InternalApi -public final class Filters { - - private Filters() { } - - /** - * Filter a given Collection. - * - * @param - * Type of the Collection. - * @param filter - * A Filter upon the Type of objects in the Collection. - * @param collection - * The Collection to filter. - * @return A List containing only those objects for which the Filter - * returned true. - */ - public static List filter(Filter filter, Collection collection) { - List list = new ArrayList<>(); - for (T obj : collection) { - if (filter.filter(obj)) { - list.add(obj); - } - } - return list; - } - - /** - * Get a File Filter for files with the given extensions, ignoring case. - * - * @param extensions - * The extensions to filter. - * @return A File Filter. - */ - public static Filter getFileExtensionFilter(String... extensions) { - return new FileExtensionFilter(extensions); - } - - /** - * Get a File Filter for directories. - * - * @return A File Filter. - */ - public static Filter getDirectoryFilter() { - return DirectoryFilter.INSTANCE; - } - - /** - * Get a File Filter for directories or for files with the given extensions, - * ignoring case. - * - * @param extensions - * The extensions to filter. - * @return A File Filter. - */ - public static Filter getFileExtensionOrDirectoryFilter(String... extensions) { - return new OrFilter<>(getFileExtensionFilter(extensions), getDirectoryFilter()); - } - - /** - * Given a String Filter, expose as a File Filter. The File paths are - * normalized to a standard pattern using / as a path separator - * which can be used cross platform easily in a regular expression based - * String Filter. - * - * @param filter - * A String Filter. - * @return A File Filter. - */ - public static Filter toNormalizedFileFilter(final Filter filter) { - return new Filter() { - @Override - public boolean filter(File file) { - String path = file.getPath(); - path = path.replace('\\', '/'); - return filter.filter(path); - } - - @Override - public String toString() { - return filter.toString(); - } - }; - } - - /** - * Given a String Filter, expose as a Filter on another type. The - * toString() method is called on the objects of the other type - * and delegated to the String Filter. - * - * @param - * The desired type. - * @param filter - * The existing String Filter. - * @return A Filter on the desired type. - */ - public static Filter fromStringFilter(final Filter filter) { - return new Filter() { - @Override - public boolean filter(T obj) { - return filter.filter(obj.toString()); - } - - @Override - public String toString() { - return filter.toString(); - } - }; - } - - /** - * Given a File Filter, expose as a FilenameFilter. - * - * @param filter - * The File Filter. - * @return A FilenameFilter. - */ - public static FilenameFilter toFilenameFilter(final Filter filter) { - return new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return filter.filter(new File(dir, name)); - } - - @Override - public String toString() { - return filter.toString(); - } - }; - } - - /** - * Given a FilenameFilter, expose as a File Filter. - * - * @param filter - * The FilenameFilter. - * @return A File Filter. - */ - public static Filter toFileFilter(final FilenameFilter filter) { - return new Filter() { - @Override - public boolean filter(File file) { - return filter.accept(file.getParentFile(), file.getName()); - } - - @Override - public String toString() { - return filter.toString(); - } - }; - } - - /** - * Construct a String Filter using set of include and exclude regular - * expressions. If there are no include regular expressions provide, then a - * regular expression is added which matches every String by default. A - * String is included as long as it matches an include regular expression - * and does not match an exclude regular expression. - *

- * In other words, exclude patterns override include patterns. - * - * @param includeRegexes - * The include regular expressions. May be null. - * @param excludeRegexes - * The exclude regular expressions. May be null. - * @return A String Filter. - */ - public static Filter buildRegexFilterExcludeOverInclude(List includeRegexes, - List excludeRegexes) { - OrFilter includeFilter = new OrFilter<>(); - if (includeRegexes == null || includeRegexes.isEmpty()) { - includeFilter.addFilter(new RegexStringFilter(".*")); - } else { - for (String includeRegex : includeRegexes) { - includeFilter.addFilter(new RegexStringFilter(includeRegex)); - } - } - - OrFilter excludeFilter = new OrFilter<>(); - if (excludeRegexes != null) { - for (String excludeRegex : excludeRegexes) { - excludeFilter.addFilter(new RegexStringFilter(excludeRegex)); - } - } - - return new AndFilter<>(includeFilter, new NotFilter<>(excludeFilter)); - } - - /** - * Construct a String Filter using set of include and exclude regular - * expressions. If there are no include regular expressions provide, then a - * regular expression is added which matches every String by default. A - * String is included as long as the case that there is an include which - * matches or there is not an exclude which matches. - *

- * In other words, include patterns override exclude patterns. - * - * @param includeRegexes - * The include regular expressions. May be null. - * @param excludeRegexes - * The exclude regular expressions. May be null. - * @return A String Filter. - */ - public static Filter buildRegexFilterIncludeOverExclude(List includeRegexes, - List excludeRegexes) { - OrFilter includeFilter = new OrFilter<>(); - if (includeRegexes != null) { - for (String includeRegex : includeRegexes) { - includeFilter.addFilter(new RegexStringFilter(includeRegex)); - } - } - - OrFilter excludeFilter = new OrFilter<>(); - if (excludeRegexes != null) { - for (String excludeRegex : excludeRegexes) { - excludeFilter.addFilter(new RegexStringFilter(excludeRegex)); - } - } - - return new OrFilter<>(includeFilter, new NotFilter<>(excludeFilter)); - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/NotFilter.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/NotFilter.java deleted file mode 100644 index 26cc124571..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/NotFilter.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.util.filter; - -/** - * A logical NEGATION of a Filter. - * - * @param - * The underlying type on which the filter applies. - * @deprecated See {@link Filter} - */ -@Deprecated -public class NotFilter extends net.sourceforge.pmd.util.filter.AbstractDelegateFilter { - public NotFilter() { - super(); - } - - public NotFilter(Filter filter) { - super(filter); - } - - @Override - public boolean filter(T obj) { - return !filter.filter(obj); - } - - @Override - public String toString() { - return "not (" + filter + ")"; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/OrFilter.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/OrFilter.java deleted file mode 100644 index 9c57d99a1f..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/OrFilter.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.util.filter; - -/** - * A logical OR of a list of Filters. This implementation is short circuiting. - * - * @param - * The underlying type on which the filter applies. - * @deprecated See {@link Filter} - */ -@Deprecated -public class OrFilter extends AbstractCompoundFilter { - - public OrFilter() { - super(); - } - - public OrFilter(Filter... filters) { - super(filters); - } - - @Override - public boolean filter(T obj) { - boolean match = false; - for (Filter filter : filters) { - if (filter.filter(obj)) { - match = true; - break; - } - } - return match; - } - - @Override - protected String getOperator() { - return "or"; - } -} diff --git a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/RegexStringFilter.java b/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/RegexStringFilter.java deleted file mode 100644 index 010f8f6065..0000000000 --- a/pmd-compat6/src/main/java/net/sourceforge/pmd/util/filter/RegexStringFilter.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// This file has been taken from 6.55.0 - -package net.sourceforge.pmd.util.filter; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -/** - * A filter which uses a regular expression to match Strings. Invalid regular - * expressions will match nothing. - *

- * Because regular expression matching is slow, and a common usage is to match - * some sort of relative file path, the regular expression is checked to see if - * it can be evaluated using much faster calls to - * {@link String#endsWith(String)}. - * @deprecated See {@link Filter} - */ -@Deprecated -public class RegexStringFilter implements Filter { - /** - * Matches regular expressions begin with an optional {@code ^}, then - * {@code .*}, then a literal path, with an optional file extension, and - * finally an optional {@code $} at the end. The {@code .} in the extension - * may or may not be preceded by a {@code \} escape. The literal path - * portion is determine by the absence of any of the following characters: - * \ [ ( . * ? + | { $ - * - * There are two capturing groups in the expression. The first is for the - * literal path. The second is for the file extension, without the escaping. - * The concatenation of these two captures creates the {@link String} which - * can be used with {@link String#endsWith(String)}. - * - * For ease of reference, the non-Java escaped form of this pattern is: - * \^?\.\*([^\\\[\(\.\*\?\+\|\{\$]+)(?:\\?(\.\w+))?\$? - */ - private static final Pattern ENDS_WITH = Pattern - .compile("\\^?\\.\\*([^\\\\\\[\\(\\.\\*\\?\\+\\|\\{\\$]+)(?:\\\\?(\\.\\w+))?\\$?"); - - protected String regex; - protected Pattern pattern; - protected String endsWith; - - public RegexStringFilter(String regex) { - this.regex = regex; - optimize(); - } - - public String getRegex() { - return this.regex; - } - - public String getEndsWith() { - return this.endsWith; - } - - protected void optimize() { - final Matcher matcher = ENDS_WITH.matcher(this.regex); - if (matcher.matches()) { - final String literalPath = matcher.group(1); - final String fileExtension = matcher.group(2); - if (fileExtension != null) { - this.endsWith = literalPath + fileExtension; - } else { - this.endsWith = literalPath; - } - } else { - try { - this.pattern = Pattern.compile(this.regex); - } catch (PatternSyntaxException ignored) { - // If the regular expression is invalid, then pattern will be - // null. - } - } - } - - @Override - public boolean filter(String obj) { - if (this.endsWith != null) { - return obj.endsWith(this.endsWith); - } - - return this.pattern != null && this.pattern.matcher(obj).matches(); - // if pattern was null, - // The regular expression must have been bad, so it will match - // nothing. - } - - @Override - public String toString() { - return "matches " + this.regex; - } -} diff --git a/pom.xml b/pom.xml index 9e4f3c750a..95db8b37e6 100644 --- a/pom.xml +++ b/pom.xml @@ -1324,18 +1324,6 @@ pmd-dist - - - pmd-compat6-module - - - !skip-pmd-compat6 - - - - pmd-compat6 - -