Merge branch 'master' into issue-4830-consolidate-packages

This commit is contained in:
Andreas Dangel
2024-03-04 19:21:16 +01:00
176 changed files with 3833 additions and 4482 deletions

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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`.

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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) {

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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());
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,2 @@
invoker.goals = verify
invoker.buildResult = failure

View 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>

View 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";
}
}

View 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";
}
}

View 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");
}

View 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>

View File

@ -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>

View File

@ -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()) {

View File

@ -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");
}

View File

@ -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