Merge branch 'master' into issue-4830-consolidate-packages
This commit is contained in:
@ -7361,6 +7361,24 @@
|
||||
"bug",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "enexusde",
|
||||
"name": "Peter Rader",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6880636?v=4",
|
||||
"profile": "http://www.e-nexus.de./",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "liqingjun123",
|
||||
"name": "liqingjun123",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/12873992?v=4",
|
||||
"profile": "https://github.com/liqingjun123",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
@ -281,7 +281,7 @@ echo "Then proceed with releasing pmd-designer..."
|
||||
echo "<https://github.com/pmd/pmd-designer/blob/master/releasing.md>"
|
||||
echo
|
||||
echo "Press enter to continue when pmd-designer is available in maven-central..."
|
||||
echo "<https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd-ui/maven-metadata.xml>."
|
||||
echo "<https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd-designer/maven-metadata.xml>."
|
||||
echo
|
||||
echo "Note: If there is no new pmd-designer release needed, you can directly proceed."
|
||||
read -r
|
||||
|
@ -252,7 +252,7 @@ This can be achieved with Rule Designer:
|
||||
* Fork and clone the [pmd/pmd-designer](https://github.com/pmd/pmd-designer) repository.
|
||||
* Add a syntax highlighter implementation to `net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting` (you could use Java as an example).
|
||||
* Register it in the `AvailableSyntaxHighlighters` enumeration.
|
||||
* Now build your implementation and place the `target/pmd-ui-<version>-SNAPSHOT.jar` to the `lib` directory inside your `pmd-bin-...` distribution (you have to delete old `pmd-ui-*.jar` from there).
|
||||
* Now build your implementation and place the `target/pmd-designer-<version>-SNAPSHOT.jar` to the `lib` directory inside your `pmd-bin-...` distribution (you have to delete old `pmd-designer-*.jar` from there).
|
||||
|
||||
## Optional features
|
||||
|
||||
|
@ -33,8 +33,10 @@ See [Apex language properties](pmd_languages_configuration.html#apex-language-pr
|
||||
|
||||
## Parser
|
||||
|
||||
We use Jorje, the Apex parsers that is shipped within the Apex Language Server. This is part of
|
||||
the [Salesforce Extensions for VS Code](https://github.com/forcedotcom/salesforcedx-vscode).
|
||||
Since PMD 7.0.0 we use the open source [apex-parser](https://github.com/apex-dev-tools/apex-parser),
|
||||
together with [Summit AST](https://github.com/google/summit-ast) which translates the ANTLR parse tree
|
||||
into an AST.
|
||||
|
||||
We take the binary from <https://github.com/forcedotcom/salesforcedx-vscode/tree/develop/packages/salesforcedx-vscode-apex/out>
|
||||
and provide it as a maven dependency (see [pmd-apex-jorje](https://github.com/pmd/pmd/tree/master/pmd-apex-jorje)).
|
||||
When PMD added Apex support with version 5.5.0, it utilized the Apex Jorje library to parse Apex source
|
||||
and generate an AST. This library is however a binary-blob provided as part of the
|
||||
[Salesforce Extensions for VS Code](https://github.com/forcedotcom/salesforcedx-vscode), and it is closed-source.
|
||||
|
@ -15,9 +15,10 @@ Usually the latest non-preview Java Version is the default version.
|
||||
|
||||
| Java Version | Alias | Supported by PMD since |
|
||||
|--------------|-------|------------------------|
|
||||
| 22-preview | | 7.0.0 |
|
||||
| 22 (default) | | 7.0.0 |
|
||||
| 21-preview | | 7.0.0 |
|
||||
| 21 (default) | | 7.0.0 |
|
||||
| 20-preview | | 6.55.0 |
|
||||
| 21 | | 7.0.0 |
|
||||
| 20 | | 6.55.0 |
|
||||
| 19 | | 6.48.0 |
|
||||
| 18 | | 6.44.0 |
|
||||
@ -40,10 +41,10 @@ Usually the latest non-preview Java Version is the default version.
|
||||
## Using Java preview features
|
||||
|
||||
In order to analyze a project with PMD that uses preview language features, you'll need to enable
|
||||
it via the environment variable `PMD_JAVA_OPTS` and select the new language version, e.g. `21-preview`:
|
||||
it via the environment variable `PMD_JAVA_OPTS` and select the new language version, e.g. `22-preview`:
|
||||
|
||||
export PMD_JAVA_OPTS=--enable-preview
|
||||
pmd check --use-version java-21-preview ...
|
||||
pmd check --use-version java-22-preview ...
|
||||
|
||||
Note: we only support preview language features for the latest two java versions.
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@ short_title: Configuring rules
|
||||
keywords: [property, properties, message, priority]
|
||||
tags: [userdocs, getting_started]
|
||||
summary: "Learn how to configure your rules directly from the ruleset XML."
|
||||
last_updated: May 2023 (7.0.0)
|
||||
last_updated: February 2024 (7.0.0)
|
||||
permalink: pmd_userdocs_configuring_rules.html
|
||||
author: Hooper Bloob <hooperbloob@users.sourceforge.net>, Romain Pelisse <rpelisse@users.sourceforge.net>, Clément Fournier <clement.fournier76@gmail.com>
|
||||
---
|
||||
@ -43,7 +43,10 @@ will cause the rule to be ignored.
|
||||
|
||||
## Rule properties
|
||||
|
||||
Properties make it easy to customise the behaviour of a rule directly from the xml. They come in several types, which correspond to the type of their values. For example, NPathComplexity declares a property "reportLevel", with an integer value type, and which corresponds to the threshold above which a method will be reported. If you believe that its default value of 200 is too high, you could lower it to e.g. 150 in the following way:
|
||||
Properties make it easy to customise the behaviour of a rule directly from the xml. They come in several types,
|
||||
which correspond to the type of their values. For example, NPathComplexity declares a property "reportLevel",
|
||||
with an integer value type, and which corresponds to the threshold above which a method will be reported.
|
||||
If you believe that its default value of 200 is too high, you could lower it to e.g. 150 in the following way:
|
||||
|
||||
```xml
|
||||
<rule ref="category/java/design.xml/NPathComplexity">
|
||||
@ -55,7 +58,9 @@ Properties make it easy to customise the behaviour of a rule directly from the x
|
||||
</rule>
|
||||
```
|
||||
|
||||
Properties are assigned a value with a `property` element, which should mention the name of a property as an attribute. The value of the property can be specified either in the content of the element, like above, or in the `value` attribute, e.g.
|
||||
Properties are assigned a value with a `property` element, which should mention the name of a property as an
|
||||
attribute. The value of the property can be specified either in the content of the element, like above, or
|
||||
in the `value` attribute, e.g.
|
||||
|
||||
```xml
|
||||
<property name="reportLevel" value="150"/>
|
||||
@ -63,12 +68,17 @@ Properties are assigned a value with a `property` element, which should mention
|
||||
|
||||
All property assignments must be enclosed in a `properties` element, which is itself inside a `rule` element.
|
||||
|
||||
{%include tip.html content="The properties of a rule are documented with the rule, e.g. [here](pmd_rules_java_design.html#npathcomplexity) for NPathComplexity. Note that **assigning a value to a property that does not exist throws an error!**" %}
|
||||
{% capture tip_content %}
|
||||
The properties of a rule are documented with the rule, e.g. [here](pmd_rules_java_design.html#npathcomplexity)
|
||||
for NPathComplexity. Note that **assigning a value to a property that does not exist throws an error!**
|
||||
{% endcapture %}
|
||||
{%include tip.html content=tip_content %}
|
||||
|
||||
Some properties take multiple values (a list), in which case you can provide them all by delimiting them with a delimiter character. It is usually a pipe ('\|'), or a comma (',') for numeric properties, e.g.
|
||||
Some properties take multiple values (a list), in which case you can provide them all by delimiting them with
|
||||
a comma (','), e.g.
|
||||
```xml
|
||||
<property name="legalCollectionTypes"
|
||||
value="java.util.ArrayList|java.util.Vector|java.util.HashMap"/>
|
||||
value="java.util.ArrayList,java.util.Vector,java.util.HashMap"/>
|
||||
```
|
||||
|
||||
These properties are referred to as **multivalued properties** in this documentation.
|
||||
|
@ -3,7 +3,7 @@ title: The rule designer
|
||||
short_title: Rule designer
|
||||
tags: [extending, userdocs]
|
||||
summary: "Learn about the usage and features of the rule designer."
|
||||
last_updated: December 2023 (7.0.0)
|
||||
last_updated: February 2024 (7.0.0)
|
||||
permalink: pmd_userdocs_extending_designer_reference.html
|
||||
author: Clément Fournier <clement.fournier76@gmail.com>
|
||||
---
|
||||
@ -25,7 +25,7 @@ If the bin directory of your PMD distribution is on your shell's path, then you
|
||||
windows="pmd.bat designer" %}
|
||||
|
||||
|
||||
{% include note.html content="pmd-ui.jar is not a runnable jar, because it doesn't include any PMD language module, or PMD Core. " %}
|
||||
{% include note.html content="pmd-designer.jar is not a runnable jar, because it doesn't include any PMD language module, or PMD Core. " %}
|
||||
|
||||
|
||||
This is to allow easy updating, and let you choose the dependencies you're interested in.
|
||||
@ -36,7 +36,7 @@ standard PMD startup scripts, which setups the classpath with the available PMD
|
||||
### Updating
|
||||
|
||||
The latest version of the designer currently **works with PMD 7.0.0 and above**. You can simply replace
|
||||
pmd-ui-7.X.Y.jar with the [latest build](https://github.com/pmd/pmd-designer/releases) in the installation
|
||||
pmd-designer-7.X.Y.jar with the [latest build](https://github.com/pmd/pmd-designer/releases) in the installation
|
||||
folder of your PMD distribution, and run it normally. Note that updating may cause some persisted state
|
||||
to get lost, for example the code snippet.
|
||||
|
||||
|
@ -212,7 +212,7 @@ accordingly and this rule won't be executed.
|
||||
The specific version of a language to be used is selected via the `sourceLanguage`
|
||||
nested element. Example:
|
||||
|
||||
<sourceLanguage name="java" version="21"/>
|
||||
<sourceLanguage name="java" version="22"/>
|
||||
|
||||
The available versions depend on the language. You can get a list of the currently supported language versions
|
||||
via the CLI option `--help`.
|
||||
|
@ -73,6 +73,28 @@ As PMD 7 revamped the Java module, if you have custom rules, you need to migrate
|
||||
See the use case [I'm using custom rules]({{ baseurl }}pmd_userdocs_migrating_to_pmd7.html#im-using-custom-rules)
|
||||
in the Migration Guide.
|
||||
|
||||
##### Java 22 Support
|
||||
|
||||
This release of PMD brings support for Java 22. There are the following new standard language features,
|
||||
that are supported now:
|
||||
|
||||
* [JEP 456: Unnamed Variables & Patterns](https://openjdk.org/jeps/456)
|
||||
|
||||
PMD also supports the following preview language features:
|
||||
|
||||
* [JEP 447: Statements before super(...) (Preview)](https://openjdk.org/jeps/447)
|
||||
* [JEP 459: String Templates (Second Preview)](https://openjdk.org/jeps/459)
|
||||
* [JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview)](https://openjdk.org/jeps/463)
|
||||
|
||||
In order to analyze a project with PMD that uses these language features,
|
||||
you'll need to enable it via the environment variable `PMD_JAVA_OPTS` and select the new language
|
||||
version `22-preview`:
|
||||
|
||||
export PMD_JAVA_OPTS=--enable-preview
|
||||
pmd check --use-version java-22-preview ...
|
||||
|
||||
Note: Support for Java 20 preview language features have been removed. The version "20-preview" is no longer available.
|
||||
|
||||
##### Swift Support
|
||||
|
||||
* limited support for Swift 5.9 (Macro Expansions)
|
||||
@ -102,7 +124,8 @@ Also having access to the source code, enhancements and modifications are easier
|
||||
|
||||
Under the hood, we use two open source libraries instead:
|
||||
|
||||
* [apex-parser](https://github.com/nawforce/apex-parser) by [Kevin Jones](https://github.com/nawforce) (@nawforce)
|
||||
* [apex-parser](https://github.com/apex-dev-tools/apex-parser) originally by
|
||||
[Kevin Jones](https://github.com/nawforce) (@nawforce).
|
||||
This project provides the grammar for a ANTLR based parser.
|
||||
* [Summit-AST](https://github.com/google/summit-ast) by [Google](https://github.com/google) (@google)
|
||||
This project translates the ANTLR parse tree into an AST, that is similar to the AST Jorje provided.
|
||||
@ -158,6 +181,13 @@ If you import rules, you also need to ajdust the paths, e.g.
|
||||
|
||||
* {% rule java/codestyle/EmptyControlStatement %}: The rule has a new property to allow empty blocks when
|
||||
they contain a comment (`allowCommentedBlocks`).
|
||||
* {% rule apex/codestyle/MethodNamingConventions %}: The deprecated rule property `skipTestMethodUnderscores` has
|
||||
been removed. It was actually deprecated since PMD 6.15.0, but was not mentioned in the release notes
|
||||
back then. Use the property `testPattern` instead to configure valid names for test methods.
|
||||
* {% rule java/documentation/CommentRequired %}: The deprecated property `headerCommentRequirement` has been removed.
|
||||
Use the property `classCommentRequirement` instead.
|
||||
* {% rule java/errorprone/NonSerializableClass %}: The deprecated property `prefix` has been removed
|
||||
without replacement. In a serializable class all fields have to be serializable regardless of the name.
|
||||
|
||||
**Renamed Rulesets**
|
||||
|
||||
@ -282,6 +312,7 @@ The rules have been moved into categories with PMD 6.
|
||||
* [#4659](https://github.com/pmd/pmd/pull/4659): \[doc] Improve ant documentation
|
||||
* [#4669](https://github.com/pmd/pmd/pull/4669): \[doc] Add bld PMD Extension to Tools / Integrations
|
||||
* [#4676](https://github.com/pmd/pmd/issues/4676): \[doc] Clarify how CPD `--ignore-literals` and `--ignore-identifiers` work
|
||||
* [#4704](https://github.com/pmd/pmd/issues/4704): \[doc] Multivalued properties do not accept | as a separator
|
||||
* miscellaneous
|
||||
* [#4699](https://github.com/pmd/pmd/pull/4699): Make PMD buildable with java 21
|
||||
* [#4586](https://github.com/pmd/pmd/pull/4586): Use explicit encoding in ruleset xml files
|
||||
@ -291,9 +322,13 @@ The rules have been moved into categories with PMD 6.
|
||||
* [#4749](https://github.com/pmd/pmd/pull/4749): Fixes NoSuchMethodError on processing errors in pmd-compat6
|
||||
* [#4776](https://github.com/pmd/pmd/issues/4776): \[ci] Upgrade to ruby 3
|
||||
* [#4796](https://github.com/pmd/pmd/pull/4796): Remove deprecated and release rulesets
|
||||
* [#4823](https://github.com/pmd/pmd/pull/4823): Update to use renamed pmd-designer
|
||||
* [#4827](https://github.com/pmd/pmd/pull/4827): \[compat6] Support config errors and cpd for csharp
|
||||
* [#4830](https://github.com/pmd/pmd/issues/4830): Consolidate packages in each maven module
|
||||
* apex
|
||||
* [#3766](https://github.com/pmd/pmd/issues/3766): \[apex] Replace Jorje with fully open source front-end
|
||||
* apex-documentation
|
||||
* [#4774](https://github.com/pmd/pmd/issues/4774): \[apex] ApexDoc false-positive for the first method of an annotated Apex class
|
||||
* apex-performance
|
||||
* [#4675](https://github.com/pmd/pmd/issues/4675): \[apex] New Rule: OperationWithHighCostInLoop
|
||||
* groovy
|
||||
@ -303,15 +338,23 @@ The rules have been moved into categories with PMD 6.
|
||||
* [#3751](https://github.com/pmd/pmd/issues/3751): \[java] Rename some node types
|
||||
* [#4628](https://github.com/pmd/pmd/pull/4628): \[java] Support loading classes from java runtime images
|
||||
* [#4753](https://github.com/pmd/pmd/issues/4753): \[java] PMD crashes while using generics and wildcards
|
||||
* [#4794](https://github.com/pmd/pmd/issues/4794): \[java] Support JDK 22
|
||||
* java-bestpractices
|
||||
* [#4603](https://github.com/pmd/pmd/issues/4603): \[java] UnusedAssignment false positive in record compact constructor
|
||||
* [#4625](https://github.com/pmd/pmd/issues/4625): \[java] UnusedPrivateMethod false positive: Autoboxing into Number
|
||||
* java-codestyle
|
||||
* [#2847](https://github.com/pmd/pmd/issues/2847): \[java] New Rule: Use Explicit Types
|
||||
* [#4239](https://github.com/pmd/pmd/issues/4239): \[java] UnnecessaryLocalBeforeReturn - false positive with catch clause
|
||||
* [#4578](https://github.com/pmd/pmd/issues/4578): \[java] CommentDefaultAccessModifier comment needs to be before annotation if present
|
||||
* [#4631](https://github.com/pmd/pmd/issues/4631): \[java] UnnecessaryFullyQualifiedName fails to recognize illegal self reference in enums
|
||||
* [#4645](https://github.com/pmd/pmd/issues/4645): \[java] CommentDefaultAccessModifier - False Positive with JUnit5's ParameterizedTest
|
||||
* [#4754](https://github.com/pmd/pmd/pull/4754): \[java] EmptyControlStatementRule: Add allowCommentedBlocks property
|
||||
* [#4816](https://github.com/pmd/pmd/issues/4816): \[java] UnnecessaryImport false-positive on generic method call with on lambda
|
||||
* java-design
|
||||
* [#174](https://github.com/pmd/pmd/issues/174): \[java] SingularField false positive with switch in method that both assigns and reads field
|
||||
* java-errorprone
|
||||
* [#718](https://github.com/pmd/pmd/issues/718): \[java] BrokenNullCheck false positive with parameter/field confusion
|
||||
* [#932](https://github.com/pmd/pmd/issues/932): \[java] SingletonClassReturningNewInstance false positive with double assignment
|
||||
* [#1831](https://github.com/pmd/pmd/issues/1831): \[java] DetachedTestCase reports abstract methods
|
||||
* [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string
|
||||
* javascript
|
||||
@ -325,6 +368,17 @@ The rules have been moved into categories with PMD 6.
|
||||
|
||||
#### API Changes
|
||||
|
||||
**pmd-java**
|
||||
|
||||
* Support for Java 20 preview language features have been removed. The version "20-preview" is no longer available.
|
||||
* {%jdoc java::lang.java.ast.ASTPattern %}, {%jdoc java::lang.java.ast.ASTRecordPattern %},
|
||||
{%jdoc java::lang.java.ast.ASTTypePattern %}, {%jdoc java::lang.java.ast.ASTUnnamedPattern %}
|
||||
- method `getParenthesisDepth()` has been removed.
|
||||
* {%jdoc java::lang.java.ast.ASTTemplateFragment %}: To get the content of the template, use now
|
||||
{%jdoc java::lang.java.ast.ASTTemplateFragment#getContent() %} or `@Content` instead of `getImage()`/`@Image`.
|
||||
* {%jdoc java::lang.java.ast.ASTUnnamedPattern %} is not experimental anymore. The language feature
|
||||
has been standardized with Java 22.
|
||||
|
||||
**New API**
|
||||
|
||||
The API around {%jdoc core::util.treeexport.TreeRenderer %} has been declared as stable. It was previously
|
||||
@ -1152,6 +1206,12 @@ Contributors: [Aaron Hurst](https://github.com/aaronhurst-google) (@aaronhurst-g
|
||||
from all rules. These properties have been deprecated since PMD 6.13.0.
|
||||
See [issue #1648](https://github.com/pmd/pmd/issues/1648) for more details.
|
||||
|
||||
**Apex Codestyle**
|
||||
|
||||
* {% rule apex/codestyle/MethodNamingConventions %}: The deprecated rule property `skipTestMethodUnderscores` has
|
||||
been removed. It was actually deprecated since PMD 6.15.0, but was not mentioned in the release notes
|
||||
back then. Use the property `testPattern` instead to configure valid names for test methods.
|
||||
|
||||
**Java General changes**
|
||||
|
||||
* Violations reported on methods or classes previously reported the line range of the entire method
|
||||
@ -1222,6 +1282,8 @@ Contributors: [Aaron Hurst](https://github.com/aaronhurst-google) (@aaronhurst-g
|
||||
See also [pull request #3757](https://github.com/pmd/pmd/pull/3757).
|
||||
* Elements in annotation types are now detected as well. This might lead to an increased number of violations
|
||||
for missing public method comments.
|
||||
* The deprecated property `headerCommentRequirement` has been removed. Use the property `classCommentRequirement`
|
||||
instead.
|
||||
* {% rule java/documentation/CommentSize %}: When determining the line-length of a comment, the leading comment
|
||||
prefix markers (e.g. `*` or `//`) are ignored and don't add up to the line-length.
|
||||
See also [pull request #4369](https://github.com/pmd/pmd/pull/4369).
|
||||
@ -1235,6 +1297,8 @@ Contributors: [Aaron Hurst](https://github.com/aaronhurst-google) (@aaronhurst-g
|
||||
special-cased anymore. Rename the exception parameter to `ignored` to ignore them.
|
||||
* {% rule java/errorprone/ImplicitSwitchFallThrough %}: Violations are now reported on the case statements
|
||||
rather than on the switch statements. This is more accurate but might result in more violations now.
|
||||
* {% rule java/errorprone/NonSerializableClass %}: The deprecated property `prefix` has been removed
|
||||
without replacement. In a serializable class all fields have to be serializable regardless of the name.
|
||||
|
||||
#### Removed Rules
|
||||
|
||||
@ -1289,6 +1353,8 @@ See also [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.
|
||||
* [#4749](https://github.com/pmd/pmd/pull/4749): Fixes NoSuchMethodError on processing errors in pmd-compat6
|
||||
* [#4776](https://github.com/pmd/pmd/issues/4776): \[ci] Upgrade to ruby 3
|
||||
* [#4796](https://github.com/pmd/pmd/pull/4796): Remove deprecated and release rulesets
|
||||
* [#4823](https://github.com/pmd/pmd/pull/4823): Update to use renamed pmd-designer
|
||||
* [#4827](https://github.com/pmd/pmd/pull/4827): \[compat6] Support config errors and cpd for csharp
|
||||
* [#4830](https://github.com/pmd/pmd/issues/4830): Consolidate packages in each maven module
|
||||
* ant
|
||||
* [#4080](https://github.com/pmd/pmd/issues/4080): \[ant] Split off Ant integration into a new submodule
|
||||
@ -1375,6 +1441,7 @@ See also [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.
|
||||
* [#4676](https://github.com/pmd/pmd/issues/4676): \[doc] Clarify how CPD `--ignore-literals` and `--ignore-identifiers` work
|
||||
* [#4659](https://github.com/pmd/pmd/pull/4659): \[doc] Improve ant documentation
|
||||
* [#4669](https://github.com/pmd/pmd/pull/4669): \[doc] Add bld PMD Extension to Tools / Integrations
|
||||
* [#4704](https://github.com/pmd/pmd/issues/4704): \[doc] Multivalued properties do not accept | as a separator
|
||||
* testing
|
||||
* [#2435](https://github.com/pmd/pmd/issues/2435): \[test] Remove duplicated Dummy language module
|
||||
* [#4234](https://github.com/pmd/pmd/issues/4234): \[test] Tests that change the logging level do not work
|
||||
@ -1394,6 +1461,8 @@ Language specific fixes:
|
||||
* [#2667](https://github.com/pmd/pmd/issues/2667): \[apex] Integrate nawforce/ApexLink to build robust Unused rule
|
||||
* [#4509](https://github.com/pmd/pmd/issues/4509): \[apex] ExcessivePublicCount doesn't consider inner classes correctly
|
||||
* [#4596](https://github.com/pmd/pmd/issues/4596): \[apex] ExcessivePublicCount ignores properties
|
||||
* apex-documentation
|
||||
* [#4774](https://github.com/pmd/pmd/issues/4774): \[apex] ApexDoc false-positive for the first method of an annotated Apex class
|
||||
* apex-performance
|
||||
* [#4675](https://github.com/pmd/pmd/issues/4675): \[apex] New Rule: OperationWithHighCostInLoop
|
||||
* apex-security
|
||||
@ -1433,6 +1502,7 @@ Language specific fixes:
|
||||
* [#4583](https://github.com/pmd/pmd/issues/4583): \[java] Support JDK 21 (LTS)
|
||||
* [#4628](https://github.com/pmd/pmd/pull/4628): \[java] Support loading classes from java runtime images
|
||||
* [#4753](https://github.com/pmd/pmd/issues/4753): \[java] PMD crashes while using generics and wildcards
|
||||
* [#4794](https://github.com/pmd/pmd/issues/4794): \[java] Support JDK 22
|
||||
* java-bestpractices
|
||||
* [#342](https://github.com/pmd/pmd/issues/342): \[java] AccessorMethodGeneration: Name clash with another public field not properly handled
|
||||
* [#755](https://github.com/pmd/pmd/issues/755): \[java] AccessorClassGeneration false positive for private constructors
|
||||
@ -1472,6 +1542,8 @@ Language specific fixes:
|
||||
* [#4516](https://github.com/pmd/pmd/issues/4516): \[java] UnusedLocalVariable: false-negative with try-with-resources
|
||||
* [#4517](https://github.com/pmd/pmd/issues/4517): \[java] UnusedLocalVariable: false-negative with compound assignments
|
||||
* [#4518](https://github.com/pmd/pmd/issues/4518): \[java] UnusedLocalVariable: false-positive with multiple for-loop indices
|
||||
* [#4603](https://github.com/pmd/pmd/issues/4603): \[java] UnusedAssignment false positive in record compact constructor
|
||||
* [#4625](https://github.com/pmd/pmd/issues/4625): \[java] UnusedPrivateMethod false positive: Autoboxing into Number
|
||||
* [#4634](https://github.com/pmd/pmd/issues/4634): \[java] JUnit4TestShouldUseTestAnnotation false positive with TestNG
|
||||
* java-codestyle
|
||||
* [#1208](https://github.com/pmd/pmd/issues/1208): \[java] PrematureDeclaration rule false-positive on variable declared to measure time
|
||||
@ -1493,6 +1565,7 @@ Language specific fixes:
|
||||
* [#3221](https://github.com/pmd/pmd/issues/3221): \[java] PrematureDeclaration false positive for unused variables
|
||||
* [#3238](https://github.com/pmd/pmd/issues/3238): \[java] Improve ExprContext, fix FNs of UnnecessaryCast
|
||||
* [#3500](https://github.com/pmd/pmd/pull/3500): \[java] UnnecessaryBoxing - check for Integer.valueOf(String) calls
|
||||
* [#4239](https://github.com/pmd/pmd/issues/4239): \[java] UnnecessaryLocalBeforeReturn - false positive with catch clause
|
||||
* [#4268](https://github.com/pmd/pmd/issues/4268): \[java] CommentDefaultAccessModifier: false positive with TestNG annotations
|
||||
* [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default
|
||||
* [#4357](https://github.com/pmd/pmd/pull/4357): \[java] Fix IllegalStateException in UseDiamondOperator rule
|
||||
@ -1503,8 +1576,10 @@ Language specific fixes:
|
||||
* [#4512](https://github.com/pmd/pmd/issues/4512): \[java] MethodArgumentCouldBeFinal shouldn't report unused parameters
|
||||
* [#4557](https://github.com/pmd/pmd/issues/4557): \[java] UnnecessaryImport FP with static imports of overloaded methods
|
||||
* [#4578](https://github.com/pmd/pmd/issues/4578): \[java] CommentDefaultAccessModifier comment needs to be before annotation if present
|
||||
* [#4631](https://github.com/pmd/pmd/issues/4631): \[java] UnnecessaryFullyQualifiedName fails to recognize illegal self reference in enums
|
||||
* [#4645](https://github.com/pmd/pmd/issues/4645): \[java] CommentDefaultAccessModifier - False Positive with JUnit5's ParameterizedTest
|
||||
* [#4754](https://github.com/pmd/pmd/pull/4754): \[java] EmptyControlStatementRule: Add allowCommentedBlocks property
|
||||
* [#4816](https://github.com/pmd/pmd/issues/4816): \[java] UnnecessaryImport false-positive on generic method call with on lambda
|
||||
* java-design
|
||||
* [#174](https://github.com/pmd/pmd/issues/174): \[java] SingularField false positive with switch in method that both assigns and reads field
|
||||
* [#1014](https://github.com/pmd/pmd/issues/1014): \[java] LawOfDemeter: False positive with lambda expression
|
||||
@ -1533,6 +1608,7 @@ Language specific fixes:
|
||||
* java-errorprone
|
||||
* [#659](https://github.com/pmd/pmd/issues/659): \[java] MissingBreakInSwitch - last default case does not contain a break
|
||||
* [#718](https://github.com/pmd/pmd/issues/718): \[java] BrokenNullCheck false positive with parameter/field confusion
|
||||
* [#932](https://github.com/pmd/pmd/issues/932): \[java] SingletonClassReturningNewInstance false positive with double assignment
|
||||
* [#1005](https://github.com/pmd/pmd/issues/1005): \[java] CloneMethodMustImplementCloneable triggers for interfaces
|
||||
* [#1669](https://github.com/pmd/pmd/issues/1669): \[java] NullAssignment - FP with ternay and null as constructor argument
|
||||
* [#1831](https://github.com/pmd/pmd/issues/1831): \[java] DetachedTestCase reports abstract methods
|
||||
|
@ -214,6 +214,28 @@ module `pmd-coco`.
|
||||
|
||||
Contributors: [Wener](https://github.com/wener-tiobe) (@wener-tiobe)
|
||||
|
||||
### Java 22 Support
|
||||
|
||||
This release of PMD brings support for Java 22. There are the following new standard language features,
|
||||
that are supported now:
|
||||
|
||||
* [JEP 456: Unnamed Variables & Patterns](https://openjdk.org/jeps/456)
|
||||
|
||||
PMD also supports the following preview language features:
|
||||
|
||||
* [JEP 447: Statements before super(...) (Preview)](https://openjdk.org/jeps/447)
|
||||
* [JEP 459: String Templates (Second Preview)](https://openjdk.org/jeps/459)
|
||||
* [JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview)](https://openjdk.org/jeps/463)
|
||||
|
||||
In order to analyze a project with PMD that uses these language features,
|
||||
you'll need to enable it via the environment variable `PMD_JAVA_OPTS` and select the new language
|
||||
version `22-preview`:
|
||||
|
||||
export PMD_JAVA_OPTS=--enable-preview
|
||||
pmd check --use-version java-22-preview ...
|
||||
|
||||
Note: Support for Java 20 preview language features have been removed. The version "20-preview" is no longer available.
|
||||
|
||||
### New: Java 21 Support
|
||||
|
||||
This release of PMD brings support for Java 21. There are the following new standard language features,
|
||||
@ -343,6 +365,12 @@ can be parsed now. PMD should now be able to parse Apex code up to version 59.0
|
||||
from all rules. These properties have been deprecated since PMD 6.13.0.
|
||||
See [issue #1648](https://github.com/pmd/pmd/issues/1648) for more details.
|
||||
|
||||
**Apex Codestyle**
|
||||
|
||||
* {% rule apex/codestyle/MethodNamingConventions %}: The deprecated rule property `skipTestMethodUnderscores` has
|
||||
been removed. It was actually deprecated since PMD 6.15.0, but was not mentioned in the release notes
|
||||
back then. Use the property `testPattern` instead to configure valid names for test methods.
|
||||
|
||||
**Java General changes**
|
||||
|
||||
* Violations reported on methods or classes previously reported the line range of the entire method
|
||||
@ -384,6 +412,8 @@ can be parsed now. PMD should now be able to parse Apex code up to version 59.0
|
||||
not necessary are allowed, if they separate expressions of different precedence.
|
||||
The other property `ignoreBalancing` (default: true) is similar, in that it allows parentheses that help
|
||||
reading and understanding the expressions.
|
||||
* {% rule java/codestyle/EmptyControlStatement %}: The rule has a new property to allow empty blocks when
|
||||
they contain a comment (`allowCommentedBlocks`).
|
||||
|
||||
**Java Design**
|
||||
|
||||
@ -411,6 +441,8 @@ can be parsed now. PMD should now be able to parse Apex code up to version 59.0
|
||||
See also [pull request #3757](https://github.com/pmd/pmd/pull/3757).
|
||||
* Elements in annotation types are now detected as well. This might lead to an increased number of violations
|
||||
for missing public method comments.
|
||||
* The deprecated property `headerCommentRequirement` has been removed. Use the property `classCommentRequirement`
|
||||
instead.
|
||||
* {% rule java/documentation/CommentSize %}: When determining the line-length of a comment, the leading comment
|
||||
prefix markers (e.g. `*` or `//`) are ignored and don't add up to the line-length.
|
||||
See also [pull request #4369](https://github.com/pmd/pmd/pull/4369).
|
||||
@ -424,6 +456,8 @@ can be parsed now. PMD should now be able to parse Apex code up to version 59.0
|
||||
special-cased anymore. Rename the exception parameter to `ignored` to ignore them.
|
||||
* {% rule java/errorprone/ImplicitSwitchFallThrough %}: Violations are now reported on the case statements
|
||||
rather than on the switch statements. This is more accurate but might result in more violations now.
|
||||
* {% rule java/errorprone/NonSerializableClass %}: The deprecated property `prefix` has been removed
|
||||
without replacement. In a serializable class all fields have to be serializable regardless of the name.
|
||||
|
||||
### Deprecated Rules
|
||||
|
||||
|
@ -15,6 +15,24 @@
|
||||
<name>PMD Ant Integration</name>
|
||||
<description>Apache Ant integration for PMD.</description>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- overrides the configuration from parent pom: we only have pmd-core yet -->
|
||||
<offlineLinks combine.self="override">
|
||||
<offlineLink>
|
||||
<location>${project.basedir}/../pmd-core/target/apidocs</location>
|
||||
<url>../../pmd-core/${project.version}</url>
|
||||
</offlineLink>
|
||||
</offlineLinks>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
|
@ -11,6 +11,7 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -196,8 +197,21 @@ public class Formatter {
|
||||
|
||||
private static String getConsoleEncoding() {
|
||||
Console console = System.console();
|
||||
// in case of pipe or redirect, no interactive console.
|
||||
// in case of pipe or redirect, no interactive console, we get null
|
||||
if (console != null) {
|
||||
// Since Java 22, this returns a console even for redirected streams.
|
||||
// In that case, we need to check Console.isTerminal()
|
||||
// See: JLine As The Default Console Provider (JDK-8308591)
|
||||
try {
|
||||
Boolean isTerminal = (Boolean) MethodUtils.invokeMethod(console, "isTerminal");
|
||||
if (!isTerminal) {
|
||||
// stop here, we don't have an interactive console.
|
||||
return null;
|
||||
}
|
||||
} catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException ignored) {
|
||||
// fall-through - we use a Java Runtime < 22.
|
||||
}
|
||||
|
||||
try {
|
||||
Object res = FieldUtils.readDeclaredField(console, "cs", true);
|
||||
if (res instanceof Charset) {
|
||||
|
@ -76,10 +76,9 @@ import com.google.summit.ast.statement.WhileLoopStatement
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class ApexTreeBuilder(val task: ParserTask, val proc: ApexLanguageProcessor) {
|
||||
private val sourceCode = task.getTextDocument()
|
||||
private val commentBuilder = ApexCommentBuilder(sourceCode, proc.getProperties().getSuppressMarker())
|
||||
class ApexTreeBuilder(private val task: ParserTask, private val proc: ApexLanguageProcessor) {
|
||||
private val sourceCode = task.textDocument
|
||||
private val commentBuilder = ApexCommentBuilder(sourceCode, proc.properties.suppressMarker)
|
||||
|
||||
/** Builds and returns an [ASTApexFile] corresponding to the given [CompilationUnit]. */
|
||||
fun buildTree(compilationUnit: CompilationUnit): ASTApexFile {
|
||||
@ -87,7 +86,7 @@ class ApexTreeBuilder(val task: ParserTask, val proc: ApexLanguageProcessor) {
|
||||
val baseClass =
|
||||
build(compilationUnit, parent = null) as? BaseApexClass<*>
|
||||
?: throw ParseException("Unable to build tree")
|
||||
val result = ASTApexFile(task, compilationUnit, commentBuilder.getSuppressMap(), proc)
|
||||
val result = ASTApexFile(task, compilationUnit, commentBuilder.suppressMap, proc)
|
||||
baseClass.setParent(result)
|
||||
|
||||
// Post-processing passes
|
||||
@ -759,8 +758,8 @@ class ApexTreeBuilder(val task: ParserTask, val proc: ApexLanguageProcessor) {
|
||||
}
|
||||
}
|
||||
|
||||
for(i in 0..node.getNumChildren()-1) {
|
||||
node.setChild(children.get(i) as AbstractApexNode, i)
|
||||
for(i in 0 until node.getNumChildren()) {
|
||||
node.setChild(children[i] as AbstractApexNode, i)
|
||||
}
|
||||
}
|
||||
|
||||
@ -794,12 +793,10 @@ class ApexTreeBuilder(val task: ParserTask, val proc: ApexLanguageProcessor) {
|
||||
}
|
||||
|
||||
/**
|
||||
* If [parent] is not null, adds this [ApexNode] as a [child][ApexNode.jjtAddChild] and sets
|
||||
* [parent] as the [parent][ApexNode.jjtSetParent].
|
||||
* If [parent] is not null, adds this [ApexNode] as a [child][AbstractApexNode.addChild] and sets
|
||||
* [parent] as the [parent][AbstractApexNode.setParent].
|
||||
*/
|
||||
private fun AbstractApexNode.setParent(parent: AbstractApexNode?) {
|
||||
if (parent != null) {
|
||||
parent.addChild(this, parent.numChildren)
|
||||
}
|
||||
parent?.addChild(this, parent.numChildren)
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.rule.codestyle;
|
||||
|
||||
import static net.sourceforge.pmd.properties.PropertyFactory.booleanProperty;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
@ -30,14 +28,7 @@ public class MethodNamingConventionsRule extends AbstractNamingConventionsRule {
|
||||
private static final PropertyDescriptor<Pattern> INSTANCE_REGEX = prop("instancePattern", "instance method",
|
||||
DESCRIPTOR_TO_DISPLAY_NAME).defaultValue(CAMEL_CASE).build();
|
||||
|
||||
private static final PropertyDescriptor<Boolean> SKIP_TEST_METHOD_UNDERSCORES_DESCRIPTOR
|
||||
= booleanProperty("skipTestMethodUnderscores")
|
||||
.desc("deprecated! Skip underscores in test methods")
|
||||
.defaultValue(false)
|
||||
.build();
|
||||
|
||||
public MethodNamingConventionsRule() {
|
||||
definePropertyDescriptor(SKIP_TEST_METHOD_UNDERSCORES_DESCRIPTOR);
|
||||
definePropertyDescriptor(TEST_REGEX);
|
||||
definePropertyDescriptor(STATIC_REGEX);
|
||||
definePropertyDescriptor(INSTANCE_REGEX);
|
||||
@ -65,11 +56,7 @@ public class MethodNamingConventionsRule extends AbstractNamingConventionsRule {
|
||||
}
|
||||
|
||||
if (node.getModifiers().isTest()) {
|
||||
if (getProperty(SKIP_TEST_METHOD_UNDERSCORES_DESCRIPTOR)) {
|
||||
checkMatches(TEST_REGEX, CAMEL_CASE_WITH_UNDERSCORES, node, data);
|
||||
} else {
|
||||
checkMatches(TEST_REGEX, node, data);
|
||||
}
|
||||
checkMatches(TEST_REGEX, node, data);
|
||||
} else if (node.getModifiers().isStatic()) {
|
||||
checkMatches(STATIC_REGEX, node, data);
|
||||
} else {
|
||||
|
@ -10,6 +10,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ApexCommentTest extends ApexParserTestBase {
|
||||
private static final String FORMAL_COMMENT_CONTENT = "/** formal comment */";
|
||||
|
||||
@Test
|
||||
void testContainsComment1() {
|
||||
@ -24,13 +25,45 @@ class ApexCommentTest extends ApexParserTestBase {
|
||||
|
||||
@Test
|
||||
void fieldDeclarationHasFormalComment() {
|
||||
final String commentContent = "/** formal comment */";
|
||||
ASTApexFile file = apex.parse("class MyClass {\n"
|
||||
+ " " + commentContent + "\n"
|
||||
+ " " + FORMAL_COMMENT_CONTENT + "\n"
|
||||
+ " Integer field;\n"
|
||||
+ "}\n");
|
||||
ASTFormalComment comment = file.descendants(ASTFieldDeclaration.class).crossFindBoundaries()
|
||||
ASTFormalComment comment = file.descendants(ASTUserClass.class)
|
||||
.children(ASTFieldDeclarationStatements.class)
|
||||
.children(ASTFieldDeclaration.class)
|
||||
.children(ASTFormalComment.class).first();
|
||||
assertEquals(commentContent, comment.getImage());
|
||||
assertEquals(FORMAL_COMMENT_CONTENT, comment.getImage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodHasFormalComment() {
|
||||
ASTApexFile file = apex.parse(FORMAL_COMMENT_CONTENT + "\n"
|
||||
+ "class MyClass {\n"
|
||||
+ " " + FORMAL_COMMENT_CONTENT + "\n"
|
||||
+ " public void bar() {}\n"
|
||||
+ "}");
|
||||
ASTFormalComment comment = file.descendants(ASTUserClass.class).children(ASTMethod.class).children(ASTFormalComment.class).first();
|
||||
assertEquals(FORMAL_COMMENT_CONTENT, comment.getImage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodHasFormalCommentAnnotatedClass() {
|
||||
ASTApexFile file = apex.parse(FORMAL_COMMENT_CONTENT + "\n"
|
||||
+ "@RestResource(urlMapping='/api/v1/get/*')\n"
|
||||
+ "class MyClass {\n"
|
||||
+ " " + FORMAL_COMMENT_CONTENT + "\n"
|
||||
+ " public void bar() {}\n"
|
||||
+ "}");
|
||||
ASTFormalComment comment = file.descendants(ASTUserClass.class).children(ASTMethod.class).children(ASTFormalComment.class).first();
|
||||
assertEquals(FORMAL_COMMENT_CONTENT, comment.getImage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void classHasFormalComment() {
|
||||
ASTApexFile file = apex.parse(FORMAL_COMMENT_CONTENT + "\n"
|
||||
+ "class MyClass {}");
|
||||
ASTFormalComment comment = file.descendants(ASTUserClass.class).children(ASTFormalComment.class).first();
|
||||
assertEquals(FORMAL_COMMENT_CONTENT, comment.getImage());
|
||||
}
|
||||
}
|
||||
|
@ -64,41 +64,6 @@ public class Foo {
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#1573 method names should not contain underscores, but skip test methods 1</description>
|
||||
<rule-property name="skipTestMethodUnderscores">true</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
@isTest
|
||||
void test_barFoo() {}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#1573 method names should not contain underscores, but skip test methods 2</description>
|
||||
<rule-property name="skipTestMethodUnderscores">true</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
testmethod void test_barFoo() {}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#1573 method names should not contain underscores, but skip test methods 3</description>
|
||||
<rule-property name="skipTestMethodUnderscores">false</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
@isTest
|
||||
void test_barFoo() {}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>all is well</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
|
@ -728,6 +728,23 @@ public class MyClass {
|
||||
Test = 1;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>[apex] ApexDoc false-positive for the first method of an annotated Apex class #4774</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* @description : rest service
|
||||
**/
|
||||
@RestResource(urlMapping='/api/v1/get/*')
|
||||
global without sharing class TestService {
|
||||
/**
|
||||
* @description Bar
|
||||
*/
|
||||
public void bar() { return; }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
||||
|
@ -32,7 +32,7 @@
|
||||
<!-- Needed for Designer command -->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-ui</artifactId>
|
||||
<artifactId>pmd-designer</artifactId>
|
||||
<version>${pmd-designer.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
@ -39,6 +39,11 @@
|
||||
<artifactId>pmd-jsp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-cs</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
2
pmd-compat6/src/it/cpd-for-csharp/invoker.properties
Normal file
2
pmd-compat6/src/it/cpd-for-csharp/invoker.properties
Normal file
@ -0,0 +1,2 @@
|
||||
invoker.goals = verify
|
||||
invoker.buildResult = failure
|
78
pmd-compat6/src/it/cpd-for-csharp/pom.xml
Normal file
78
pmd-compat6/src/it/cpd-for-csharp/pom.xml
Normal file
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>net.sourceforge.pmd.pmd-compat6.it</groupId>
|
||||
<artifactId>cpd-for-csharp</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-pmd-plugin</artifactId>
|
||||
<version>@maven-pmd-plugin.version.for.integrationtest@</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>csharp-cpd-check</id>
|
||||
<goals>
|
||||
<goal>cpd-check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<language>cs</language>
|
||||
<minimumTokens>10</minimumTokens>
|
||||
<includes>
|
||||
<include>**/*.cs</include>
|
||||
</includes>
|
||||
<compileSourceRoots>
|
||||
<compileSourceRoot>${basedir}/src/main/cs</compileSourceRoot>
|
||||
</compileSourceRoots>
|
||||
<printFailingErrors>true</printFailingErrors>
|
||||
<skipPmdError>false</skipPmdError>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-compat6</artifactId>
|
||||
<version>@project.version@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-core</artifactId>
|
||||
<version>@pmd.version.for.integrationtest@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-java</artifactId>
|
||||
<version>@pmd.version.for.integrationtest@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-javascript</artifactId>
|
||||
<version>@pmd.version.for.integrationtest@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-jsp</artifactId>
|
||||
<version>@pmd.version.for.integrationtest@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-cs</artifactId>
|
||||
<version>@pmd.version.for.integrationtest@</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
12
pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings1.cs
Normal file
12
pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings1.cs
Normal file
@ -0,0 +1,12 @@
|
||||
class Foo {
|
||||
void bar() {
|
||||
|
||||
var test = $@"test";
|
||||
var test2 = @$"test";
|
||||
|
||||
String query =
|
||||
@"SELECT foo, bar
|
||||
FROM table
|
||||
WHERE id = 42";
|
||||
}
|
||||
}
|
12
pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings2.cs
Normal file
12
pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings2.cs
Normal file
@ -0,0 +1,12 @@
|
||||
class Foo {
|
||||
void bar() {
|
||||
|
||||
var test = $@"test";
|
||||
var test2 = @$"test";
|
||||
|
||||
String query =
|
||||
@"SELECT foo, bar
|
||||
FROM table
|
||||
WHERE id = 42";
|
||||
}
|
||||
}
|
46
pmd-compat6/src/it/cpd-for-csharp/verify.bsh
Normal file
46
pmd-compat6/src/it/cpd-for-csharp/verify.bsh
Normal file
@ -0,0 +1,46 @@
|
||||
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("<duplication lines=\"12\" tokens=\"29\">")) {
|
||||
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");
|
||||
}
|
5
pmd-compat6/src/it/pmd-for-java/config_error_ruleset.xml
Normal file
5
pmd-compat6/src/it/pmd-for-java/config_error_ruleset.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<ruleset xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" name="RuleSet that creates a config error">
|
||||
<description/>
|
||||
<!-- Rule LoosePackageCoupling is enabled, but not configured -->
|
||||
<rule ref="category/java/design.xml/LoosePackageCoupling" />
|
||||
</ruleset>
|
@ -36,6 +36,7 @@
|
||||
<rulesets>
|
||||
<ruleset>/rulesets/java/maven-pmd-plugin-default.xml</ruleset>
|
||||
<ruleset>${project.basedir}/exception_ruleset.xml</ruleset>
|
||||
<ruleset>${project.basedir}/config_error_ruleset.xml</ruleset>
|
||||
</rulesets>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
|
@ -36,6 +36,9 @@ if (!pmdXml.contains(mainFile + "\">")) {
|
||||
if (!pmdXml.contains("<error filename=\"" + mainFile.getAbsolutePath()) || !pmdXml.contains(mainFile + "\" msg=\"PmdXPathException")) {
|
||||
throw new RuntimeException("Processing error has not been reported");
|
||||
}
|
||||
if (!pmdXml.contains("<configerror rule=\"LoosePackageCoupling\" msg=\"No packages or classes specified\"/>")) {
|
||||
throw new RuntimeException("Configuration error has not been reported");
|
||||
}
|
||||
|
||||
File pmdCsvReport = new File(basedir, "target/pmd.csv");
|
||||
if (!pmdCsvReport.exists()) {
|
||||
|
@ -296,6 +296,9 @@ public class CPDConfiguration extends AbstractConfiguration {
|
||||
} 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");
|
||||
}
|
||||
|
@ -10,6 +10,11 @@
|
||||
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() {
|
||||
@ -17,6 +22,44 @@ public final class LanguageFactory {
|
||||
}
|
||||
|
||||
public static Language createLanguage(String name, Properties properties) {
|
||||
throw new UnsupportedOperationException();
|
||||
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 <T> void setProperty(LanguagePropertyBundle propertyBundle, PropertyDescriptor<T> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user