Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@ -85,7 +85,7 @@ mkdir pmd.github.io
|
||||
git add latest
|
||||
git commit -q -m "Copying pmd-${RELEASE_VERSION} to latest"
|
||||
|
||||
./sitemap_generator.sh > sitemap.xml
|
||||
../.travis/sitemap_generator.sh > sitemap.xml
|
||||
git add sitemap.xml
|
||||
git commit -q -m "Generated sitemap.xml"
|
||||
git push origin master
|
||||
|
@ -66,6 +66,8 @@ export RELEASE_VERSION
|
||||
export DEVELOPMENT_VERSION
|
||||
export CURRENT_BRANCH
|
||||
|
||||
RELEASE_RULESET="pmd-core/src/main/resources/rulesets/releases/${RELEASE_VERSION//\./}.xml"
|
||||
|
||||
echo "* Update version/release info in **docs/pages/release_notes.md**."
|
||||
echo
|
||||
echo " ## $(date -u +%d-%B-%Y) - ${RELEASE_VERSION}"
|
||||
@ -73,7 +75,7 @@ echo
|
||||
echo "* Update date info in **docs/_config.yml**."
|
||||
echo
|
||||
echo "* Ensure all the new rules are listed in a the proper file:"
|
||||
echo " pmd-core/src/main/resources/rulesets/releases/${RELEASE_VERSION}.xml file."
|
||||
echo " ${RELEASE_RULESET}"
|
||||
echo
|
||||
echo "* Update **../pmd.github.io/_config.yml** to mention the new release"
|
||||
echo
|
||||
@ -82,6 +84,12 @@ echo
|
||||
echo "Press enter to continue..."
|
||||
read
|
||||
echo "Committing current changes (pmd)"
|
||||
|
||||
if [[ -e ${RELEASE_RULESET} ]]
|
||||
then
|
||||
git add ${RELEASE_RULESET}
|
||||
fi
|
||||
|
||||
git commit -a -m "Prepare pmd release ${RELEASE_VERSION}"
|
||||
(
|
||||
echo "Committing current changes (pmd.github.io)"
|
||||
@ -123,13 +131,23 @@ echo " --> move any open issues to the next milestone, close the current milesto
|
||||
echo " --> Maybe there are some milestones on sourceforge, too: <https://sourceforge.net/p/pmd/bugs/milestones>."
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo "Prepare Next development version:"
|
||||
echo "* Move version/release info from **docs/pages/release_notes.md** to **docs/pages/release_notes_old.md**."
|
||||
echo "* Update version/date info in **docs/_config.yml**."
|
||||
echo "* Update version/release info in **docs/pages/release_notes.md**."
|
||||
echo
|
||||
cat <<EOF
|
||||
echo
|
||||
echo "Press enter to continue..."
|
||||
read
|
||||
|
||||
# update release_notes_old
|
||||
OLD_RELEASE_NOTES=$(tail -n +8 docs/pages/release_notes_old.md)
|
||||
NEW_RELEASE_NOTES=$(tail -n +6 docs/pages/release_notes.md)
|
||||
echo "$(head -n 7 docs/pages/release_notes_old.md)" > docs/pages/release_notes_old.md
|
||||
echo "$NEW_RELEASE_NOTES" >> docs/pages/release_notes_old.md
|
||||
echo >> docs/pages/release_notes_old.md
|
||||
echo "$OLD_RELEASE_NOTES" >> docs/pages/release_notes_old.md
|
||||
|
||||
# reset release notes template
|
||||
cat > docs/pages/release_notes.md <<EOF
|
||||
---
|
||||
title: PMD Release Notes
|
||||
permalink: pmd_release_notes.html
|
||||
@ -158,11 +176,10 @@ This is a minor release.
|
||||
### External Contributions
|
||||
|
||||
EOF
|
||||
echo
|
||||
echo "Press enter to continue..."
|
||||
read
|
||||
|
||||
git commit -a -m "Prepare next development version"
|
||||
git push origin ${CURRENT_BRANCH}
|
||||
./mvwn -B release:clean
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
|
@ -1,8 +1,8 @@
|
||||
repository: pmd/pmd
|
||||
|
||||
pmd:
|
||||
version: 6.4.0
|
||||
date: 2018-05-27
|
||||
version: 6.5.0
|
||||
date: ?????
|
||||
|
||||
output: web
|
||||
# this property is useful for conditional filtering of content that is separate from the PDF.
|
||||
|
@ -65,7 +65,13 @@ By far the most common problem is the use of ${project.version} in a BOM or pare
|
||||
|
||||
**This rule is defined by the following XPath expression:**
|
||||
```
|
||||
//dependency/version/text[contains(@Image,'{project.version}')]
|
||||
//dependencies/dependency
|
||||
[contains(version/text/@Image,'{project.version}')]
|
||||
[
|
||||
(/project/parent/groupId and groupId/text/@Image != /project/parent/groupId/text/@Image)
|
||||
or
|
||||
(/project/groupId and groupId/text/@Image != /project/groupId/text/@Image)
|
||||
]/version
|
||||
```
|
||||
|
||||
**Example(s):**
|
||||
|
@ -4,131 +4,25 @@ permalink: pmd_release_notes.html
|
||||
keywords: changelog, release notes
|
||||
---
|
||||
|
||||
## ????? - 6.4.0-SNAPSHOT
|
||||
## ????? - 6.5.0-SNAPSHOT
|
||||
|
||||
The PMD team is pleased to announce PMD 6.4.0.
|
||||
The PMD team is pleased to announce PMD 6.5.0.
|
||||
|
||||
This is a minor release.
|
||||
|
||||
### Table Of Contents
|
||||
|
||||
* [New and noteworthy](#new-and-noteworthy)
|
||||
* [XPath Type Resolution Functions](#xpath-type-resolution-functions)
|
||||
* [New Rules](#new-rules)
|
||||
* [Modified Rules](#modified-rules)
|
||||
* [Fixed Issues](#fixed-issues)
|
||||
* [API Changes](#api-changes)
|
||||
* [External Contributions](#external-contributions)
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
#### XPath Type Resolution Functions
|
||||
|
||||
For some time now PMD has supported Type Resolution, and exposed this functionality to XPath rules for the Java language
|
||||
with the `typeof` function. This function however had a number of shortcomings:
|
||||
|
||||
* It would take a first arg with the name to match if types couldn't be resolved. In all cases this was `@Image`
|
||||
but was still required.
|
||||
* It required 2 separate arguments for the Fully Qualified Class Name and the simple name of the class against
|
||||
which to test.
|
||||
* If only the Fully Qualified Class Name was provided, no simple name check was performed (not documented,
|
||||
but abused on some rules to "fix" some false positives).
|
||||
|
||||
In this release we are deprecating `typeof` in favor of a simpler `typeIs` function, which behaves exactly as the
|
||||
old `typeof` when given all 3 arguments.
|
||||
|
||||
`typeIs` receives a single parameter, which is the fully qualified name of the class to test against.
|
||||
|
||||
So, calls such as:
|
||||
|
||||
```ruby
|
||||
//ClassOrInterfaceType[typeof(@Image, 'junit.framework.TestCase', 'TestCase')]
|
||||
```
|
||||
|
||||
can now we expressed much more concisely as:
|
||||
|
||||
```ruby
|
||||
//ClassOrInterfaceType[typeIs('junit.framework.TestCase')]
|
||||
```
|
||||
|
||||
With this change, we also allow to check against array types by just appending `[]` to the fully qualified class name.
|
||||
These can be repeated for arrays of arrays (e.g. `byte[][]` or `java.lang.String[]`).
|
||||
|
||||
Additionally, we introduce the companion function `typeIsExactly`, that receives the same parameters as `typeIs`,
|
||||
but checks for exact type matches, without considering the type hierarchy. That is, the test
|
||||
`typeIsExactly('junit.framework.TestCase')` will match only if the context node is an instance of `TestCase`, but
|
||||
not if it's an instance of a subclass of `TestCase`. Be aware then, that using that method with abstract types will
|
||||
never match.
|
||||
|
||||
#### New Rules
|
||||
|
||||
* The new Java rule [`HardCodedCryptoKey`](pmd_rules_java_security.html#hardcodedcryptokey) (`java-security`)
|
||||
detects hard coded keys used for encryption. It is recommended to store keys outside of the source code.
|
||||
|
||||
* The new Java rule [`IdenticalCatchBranches`](pmd_rules_java_codestyle.html#identicalcatchbranches) (`java-codestyle`)
|
||||
finds catch blocks,
|
||||
that catch different exception but perform the same exception handling and thus can be collapsed into a
|
||||
multi-catch try statement.
|
||||
|
||||
#### Modified Rules
|
||||
|
||||
* The Java rule [JUnit4TestShouldUseTestAnnotation](pmd_rules_java_bestpractices.html#junit4testshouldusetestannotation) (`java-bestpractices`)
|
||||
has a new parameter "testClassPattern". It is used to distinguish test classes from other classes and
|
||||
avoid false positives. By default, any class, that has "Test" in its name, is considered a test class.
|
||||
|
||||
* The Java rule [CommentDefaultAccessModifier](pmd_rules_java_codestyle.html#commentdefaultaccessmodifier) (`java-codestyle`)
|
||||
allows now by default the comment "`/* package */` in addition to "`/* default */`. This behavior can
|
||||
still be adjusted by setting the property `regex`.
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
* all
|
||||
* [#1018](https://github.com/pmd/pmd/issues/1018): \[java] Performance degradation of 250% between 6.1.0 and 6.2.0
|
||||
* [#1145](https://github.com/pmd/pmd/issues/1145): \[core] JCommander's help text for option -min is wrong
|
||||
* java
|
||||
* [#672](https://github.com/pmd/pmd/issues/672): \[java] Support exact type matches for type resolution from XPath
|
||||
* [#1077](https://github.com/pmd/pmd/issues/1077): \[java] Analyzing enum with lambda passed in constructor fails with "The enclosing scope must exist."
|
||||
* [#1115](https://github.com/pmd/pmd/issues/1115): \[java] Simplify xpath typeof syntax
|
||||
* [#1131](https://github.com/pmd/pmd/issues/1131): \[java] java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/faces/application/FacesMessage$Severity
|
||||
* java-bestpractices
|
||||
* [#527](https://github.com/pmd/pmd/issues/572): \[java] False Alarm of JUnit4TestShouldUseTestAnnotation on Predicates
|
||||
* [#1063](https://github.com/pmd/pmd/issues/1063): \[java] MissingOverride is triggered in illegal places
|
||||
* java-codestyle
|
||||
* [#720](https://github.com/pmd/pmd/issues/720): \[java] ShortVariable should whitelist lambdas
|
||||
* [#955](https://github.com/pmd/pmd/issues/955): \[java] Detect identical catch statements
|
||||
* [#1114](https://github.com/pmd/pmd/issues/1114): \[java] Star import overwritten by explicit import is not correctly handled
|
||||
* [#1064](https://github.com/pmd/pmd/issues/1064): \[java] ClassNamingConventions suggests to add Util suffix for simple exception wrappers
|
||||
* [#1065](https://github.com/pmd/pmd/issues/1065): \[java] ClassNamingConventions shouldn't prohibit numbers in class names
|
||||
* [#1067](https://github.com/pmd/pmd/issues/1067): \[java] [6.3.0] PrematureDeclaration false-positive
|
||||
* [#1096](https://github.com/pmd/pmd/issues/1096): \[java] ClassNamingConventions is too ambitious on finding utility classes
|
||||
* java-design
|
||||
* [#824](https://github.com/pmd/pmd/issues/824): \[java] UseUtilityClass false positive when extending
|
||||
* [#1021](https://github.com/pmd/pmd/issues/1021): \[java] False positive for `DoNotExtendJavaLangError`
|
||||
* [#1097](https://github.com/pmd/pmd/pull/1097): \[java] False negative in AvoidThrowingRawExceptionTypes
|
||||
* java-performance
|
||||
* [#1051](https://github.com/pmd/pmd/issues/1051): \[java] ConsecutiveAppendsShouldReuse false-negative
|
||||
* [#1098](https://github.com/pmd/pmd/pull/1098): \[java] Simplify LongInstantiation, IntegerInstantiation, ByteInstantiation, and ShortInstantiation using type resolution
|
||||
* [#1125](https://github.com/pmd/pmd/issues/1125): \[java] Improve message of InefficientEmptyStringCheck for String.trim().isEmpty()
|
||||
* doc
|
||||
* [#999](https://github.com/pmd/pmd/issues/999): \[doc] Add a header before the XPath expression in rules
|
||||
* [#1082](https://github.com/pmd/pmd/issues/1082): \[doc] Multifile analysis doc is invalid
|
||||
* vf-security
|
||||
* [#1100](https://github.com/pmd/pmd/issues/1100): \[vf] URLENCODE is ignored as valid escape method
|
||||
* xml
|
||||
* [#715](https://github.com/pmd/pmd/issues/715): \[xml] ProjectVersionAsDependencyVersion false positive
|
||||
|
||||
### API Changes
|
||||
|
||||
* The following classes in package `net.sourceforge.pmd.benchmark` have been deprecated: `Benchmark`, `Benchmarker`,
|
||||
`BenchmarkReport`, `BenchmarkResult`, `RuleDuration`, `StringBuilderCR` and `TextReport`. Their API is not supported anymore
|
||||
and is disconnected from the internals of PMD. Use the newer API based around `TimeTracker` instead, which can be found
|
||||
in the same package.
|
||||
|
||||
|
||||
### External Contributions
|
||||
|
||||
* [#966](https://github.com/pmd/pmd/pull/966): \[java] Issue #955: add new rule to detect identical catch statement - [Clément Fournier](https://github.com/oowekyala) and [BBG](https://github.com/djydewang)
|
||||
* [#1046](https://github.com/pmd/pmd/pull/1046): \[java] New security rule for finding hard-coded keys used for cryptographic operations - [Sergey Gorbaty](https://github.com/sgorbaty)
|
||||
* [#1101](https://github.com/pmd/pmd/pull/1101): \[java] Fixes false positive for `DoNotExtendJavaLangError` - [Akshat Bahety](https://github.com/akshatbahety)
|
||||
* [#1106](https://github.com/pmd/pmd/pull/1106): \[vf] URLENCODE is ignored as valid escape method - [Robert Sösemann](https://github.com/rsoesemann)
|
||||
* [#1126](https://github.com/pmd/pmd/pull/1126): \[java] Improve implementation hint in InefficientEmptyStringCheck - [krichter722](https://github.com/krichter722)
|
||||
* [#1129](https://github.com/pmd/pmd/pull/1129): \[java] Adjust InefficientEmptyStringCheck documentation - [krichter722](https://github.com/krichter722)
|
||||
* [#1137](https://github.com/pmd/pmd/pull/1137): \[ui] Removes the need for RefreshAST - [Akshat Bahety](https://github.com/akshatbahety)
|
@ -6,6 +6,151 @@ permalink: pmd_release_notes_old.html
|
||||
Previous versions of PMD can be downloaded here:
|
||||
http://sourceforge.net/projects/pmd/files/pmd/
|
||||
|
||||
## 29-May-2018 - 6.4.0
|
||||
|
||||
The PMD team is pleased to announce PMD 6.4.0.
|
||||
|
||||
This is a minor release.
|
||||
|
||||
### Table Of Contents
|
||||
|
||||
* [New and noteworthy](#new-and-noteworthy)
|
||||
* [Java 10 Support](#java-10-support)
|
||||
* [XPath Type Resolution Functions](#xpath-type-resolution-functions)
|
||||
* [New Rules](#new-rules)
|
||||
* [Modified Rules](#modified-rules)
|
||||
* [Fixed Issues](#fixed-issues)
|
||||
* [API Changes](#api-changes)
|
||||
* [External Contributions](#external-contributions)
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
#### Java 10 Support
|
||||
|
||||
PMD is now able to understand local-variable type inference as introduced by Java 10.
|
||||
Simple type resolution features are available, e.g. the type of the variable `s` is inferred
|
||||
correctly as `String`:
|
||||
|
||||
var s = "Java 10";
|
||||
|
||||
#### XPath Type Resolution Functions
|
||||
|
||||
For some time now PMD has supported Type Resolution, and exposed this functionality to XPath rules for the Java language
|
||||
with the `typeof` function. This function however had a number of shortcomings:
|
||||
|
||||
* It would take a first arg with the name to match if types couldn't be resolved. In all cases this was `@Image`
|
||||
but was still required.
|
||||
* It required 2 separate arguments for the Fully Qualified Class Name and the simple name of the class against
|
||||
which to test.
|
||||
* If only the Fully Qualified Class Name was provided, no simple name check was performed (not documented,
|
||||
but abused on some rules to "fix" some false positives).
|
||||
|
||||
In this release we are deprecating `typeof` in favor of a simpler `typeIs` function, which behaves exactly as the
|
||||
old `typeof` when given all 3 arguments.
|
||||
|
||||
`typeIs` receives a single parameter, which is the fully qualified name of the class to test against.
|
||||
|
||||
So, calls such as:
|
||||
|
||||
```ruby
|
||||
//ClassOrInterfaceType[typeof(@Image, 'junit.framework.TestCase', 'TestCase')]
|
||||
```
|
||||
|
||||
can now we expressed much more concisely as:
|
||||
|
||||
```ruby
|
||||
//ClassOrInterfaceType[typeIs('junit.framework.TestCase')]
|
||||
```
|
||||
|
||||
With this change, we also allow to check against array types by just appending `[]` to the fully qualified class name.
|
||||
These can be repeated for arrays of arrays (e.g. `byte[][]` or `java.lang.String[]`).
|
||||
|
||||
Additionally, we introduce the companion function `typeIsExactly`, that receives the same parameters as `typeIs`,
|
||||
but checks for exact type matches, without considering the type hierarchy. That is, the test
|
||||
`typeIsExactly('junit.framework.TestCase')` will match only if the context node is an instance of `TestCase`, but
|
||||
not if it's an instance of a subclass of `TestCase`. Be aware then, that using that method with abstract types will
|
||||
never match.
|
||||
|
||||
#### New Rules
|
||||
|
||||
* The new Java rule [`HardCodedCryptoKey`](pmd_rules_java_security.html#hardcodedcryptokey) (`java-security`)
|
||||
detects hard coded keys used for encryption. It is recommended to store keys outside of the source code.
|
||||
|
||||
* The new Java rule [`IdenticalCatchBranches`](pmd_rules_java_codestyle.html#identicalcatchbranches) (`java-codestyle`)
|
||||
finds catch blocks,
|
||||
that catch different exception but perform the same exception handling and thus can be collapsed into a
|
||||
multi-catch try statement.
|
||||
|
||||
#### Modified Rules
|
||||
|
||||
* The Java rule [JUnit4TestShouldUseTestAnnotation](pmd_rules_java_bestpractices.html#junit4testshouldusetestannotation) (`java-bestpractices`)
|
||||
has a new parameter "testClassPattern". It is used to distinguish test classes from other classes and
|
||||
avoid false positives. By default, any class, that has "Test" in its name, is considered a test class.
|
||||
|
||||
* The Java rule [CommentDefaultAccessModifier](pmd_rules_java_codestyle.html#commentdefaultaccessmodifier) (`java-codestyle`)
|
||||
allows now by default the comment "`/* package */` in addition to "`/* default */`. This behavior can
|
||||
still be adjusted by setting the property `regex`.
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
* all
|
||||
* [#1018](https://github.com/pmd/pmd/issues/1018): \[java] Performance degradation of 250% between 6.1.0 and 6.2.0
|
||||
* [#1145](https://github.com/pmd/pmd/issues/1145): \[core] JCommander's help text for option -min is wrong
|
||||
* java
|
||||
* [#672](https://github.com/pmd/pmd/issues/672): \[java] Support exact type matches for type resolution from XPath
|
||||
* [#743](https://github.com/pmd/pmd/issues/743): \[java] Prepare for Java 10
|
||||
* [#1077](https://github.com/pmd/pmd/issues/1077): \[java] Analyzing enum with lambda passed in constructor fails with "The enclosing scope must exist."
|
||||
* [#1115](https://github.com/pmd/pmd/issues/1115): \[java] Simplify xpath typeof syntax
|
||||
* [#1131](https://github.com/pmd/pmd/issues/1131): \[java] java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/faces/application/FacesMessage$Severity
|
||||
* java-bestpractices
|
||||
* [#527](https://github.com/pmd/pmd/issues/572): \[java] False Alarm of JUnit4TestShouldUseTestAnnotation on Predicates
|
||||
* [#1063](https://github.com/pmd/pmd/issues/1063): \[java] MissingOverride is triggered in illegal places
|
||||
* java-codestyle
|
||||
* [#720](https://github.com/pmd/pmd/issues/720): \[java] ShortVariable should whitelist lambdas
|
||||
* [#955](https://github.com/pmd/pmd/issues/955): \[java] Detect identical catch statements
|
||||
* [#1114](https://github.com/pmd/pmd/issues/1114): \[java] Star import overwritten by explicit import is not correctly handled
|
||||
* [#1064](https://github.com/pmd/pmd/issues/1064): \[java] ClassNamingConventions suggests to add Util suffix for simple exception wrappers
|
||||
* [#1065](https://github.com/pmd/pmd/issues/1065): \[java] ClassNamingConventions shouldn't prohibit numbers in class names
|
||||
* [#1067](https://github.com/pmd/pmd/issues/1067): \[java] \[6.3.0] PrematureDeclaration false-positive
|
||||
* [#1096](https://github.com/pmd/pmd/issues/1096): \[java] ClassNamingConventions is too ambitious on finding utility classes
|
||||
* java-design
|
||||
* [#824](https://github.com/pmd/pmd/issues/824): \[java] UseUtilityClass false positive when extending
|
||||
* [#1021](https://github.com/pmd/pmd/issues/1021): \[java] False positive for `DoNotExtendJavaLangError`
|
||||
* [#1097](https://github.com/pmd/pmd/pull/1097): \[java] False negative in AvoidThrowingRawExceptionTypes
|
||||
* java-performance
|
||||
* [#1051](https://github.com/pmd/pmd/issues/1051): \[java] ConsecutiveAppendsShouldReuse false-negative
|
||||
* [#1098](https://github.com/pmd/pmd/pull/1098): \[java] Simplify LongInstantiation, IntegerInstantiation, ByteInstantiation, and ShortInstantiation using type resolution
|
||||
* [#1125](https://github.com/pmd/pmd/issues/1125): \[java] Improve message of InefficientEmptyStringCheck for String.trim().isEmpty()
|
||||
* doc
|
||||
* [#999](https://github.com/pmd/pmd/issues/999): \[doc] Add a header before the XPath expression in rules
|
||||
* [#1082](https://github.com/pmd/pmd/issues/1082): \[doc] Multifile analysis doc is invalid
|
||||
* vf-security
|
||||
* [#1100](https://github.com/pmd/pmd/issues/1100): \[vf] URLENCODE is ignored as valid escape method
|
||||
|
||||
### API Changes
|
||||
|
||||
* The following classes in package `net.sourceforge.pmd.benchmark` have been deprecated: `Benchmark`, `Benchmarker`,
|
||||
`BenchmarkReport`, `BenchmarkResult`, `RuleDuration`, `StringBuilderCR` and `TextReport`. Their API is not supported anymore
|
||||
and is disconnected from the internals of PMD. Use the newer API based around `TimeTracker` instead, which can be found
|
||||
in the same package.
|
||||
* The class `net.sourceforge.pmd.lang.java.xpath.TypeOfFunction` has been deprecated. Use the newer `TypeIsFunction` in the same package.
|
||||
* The `typeof` methdos in `net.sourceforge.pmd.lang.java.xpath.JavaFunctions` have been deprecated.
|
||||
Use the newer `typeIs` method in the same class instead..
|
||||
* The methods `isA`, `isEither` and `isNeither` of `net.sourceforge.pmd.lang.java.typeresolution.TypeHelper`.
|
||||
Use the new `isExactlyAny` and `isExactlyNone` methods in the same class instead.
|
||||
|
||||
|
||||
### External Contributions
|
||||
|
||||
* [#966](https://github.com/pmd/pmd/pull/966): \[java] Issue #955: add new rule to detect identical catch statement - [Clément Fournier](https://github.com/oowekyala) and [BBG](https://github.com/djydewang)
|
||||
* [#1046](https://github.com/pmd/pmd/pull/1046): \[java] New security rule for finding hard-coded keys used for cryptographic operations - [Sergey Gorbaty](https://github.com/sgorbaty)
|
||||
* [#1101](https://github.com/pmd/pmd/pull/1101): \[java] Fixes false positive for `DoNotExtendJavaLangError` - [Akshat Bahety](https://github.com/akshatbahety)
|
||||
* [#1106](https://github.com/pmd/pmd/pull/1106): \[vf] URLENCODE is ignored as valid escape method - [Robert Sösemann](https://github.com/rsoesemann)
|
||||
* [#1126](https://github.com/pmd/pmd/pull/1126): \[java] Improve implementation hint in InefficientEmptyStringCheck - [krichter722](https://github.com/krichter722)
|
||||
* [#1129](https://github.com/pmd/pmd/pull/1129): \[java] Adjust InefficientEmptyStringCheck documentation - [krichter722](https://github.com/krichter722)
|
||||
* [#1137](https://github.com/pmd/pmd/pull/1137): \[ui] Removes the need for RefreshAST - [Akshat Bahety](https://github.com/akshatbahety)
|
||||
|
||||
|
||||
|
||||
## 29-April-2018 - 6.3.0
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -19,6 +19,9 @@
|
||||
<exclude-pattern>.*/net/sourceforge/pmd/lang/java/ast/jdkversiontests/assert_test7.java</exclude-pattern>
|
||||
<exclude-pattern>.*/net/sourceforge/pmd/lang/java/ast/jdkversiontests/jdk14_enum.java</exclude-pattern>
|
||||
<exclude-pattern>.*/net/sourceforge/pmd/lang/java/ast/jdkversiontests/jdk9_invalid_identifier.java</exclude-pattern>
|
||||
<exclude-pattern>.*/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsAnnotationName.java</exclude-pattern>
|
||||
<exclude-pattern>.*/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsEnumName.java</exclude-pattern>
|
||||
<exclude-pattern>.*/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java10/LocalVariableTypeInference_varAsTypeIdentifier.java</exclude-pattern>
|
||||
|
||||
<rule ref="category/java/bestpractices.xml" />
|
||||
<rule ref="category/java/codestyle.xml" />
|
||||
|
14
pmd-core/src/main/resources/rulesets/releases/640.xml
Normal file
14
pmd-core/src/main/resources/rulesets/releases/640.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<ruleset name="640"
|
||||
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
|
||||
<description>
|
||||
This ruleset contains links to rules that are new in PMD v6.4.0
|
||||
</description>
|
||||
|
||||
<rule ref="category/java/security.xml/HardCodedCryptoKey"/>
|
||||
<rule ref="category/java/codestyle.xml/IdenticalCatchBranches"/>
|
||||
</ruleset>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -76,10 +76,10 @@ check_lib_dir() {
|
||||
|
||||
jre_specific_vm_options() {
|
||||
# java_ver is eg "18" for java 1.8, "90" for java 9.0
|
||||
java_ver=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;')
|
||||
java_ver=$(java -version 2>&1 | sed -n ';s/^.* version "\(.*\)\.\(.*\)\..*".*$/\1\2/p;')
|
||||
options=""
|
||||
|
||||
if [ $java_ver -ge 90 ] && [ "${APPNAME}" = "designer" ]
|
||||
if [ "$java_ver" -ge 90 ] && [ "${APPNAME}" = "designer" ]
|
||||
then # open internal module of javafx to reflection
|
||||
options="--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED"
|
||||
fi
|
||||
|
@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -1,4 +1,8 @@
|
||||
/**
|
||||
* Add support for Java 10 Local Variable Type Inference
|
||||
* See #743. In Java 10 mode, "var" as local variable type is handled special.
|
||||
* Andreas Dangel 04/2018
|
||||
*====================================================================
|
||||
* Fixes #888 [java] ParseException occurs with valid '<>' in Java 1.8 mode
|
||||
* Juan Martin Sotuyo Dodero 01/2018
|
||||
*====================================================================
|
||||
@ -369,6 +373,11 @@ public class JavaParser {
|
||||
throwParseException("Cannot use concise try-with-resources when running in JDK inferior to 9 mode!");
|
||||
}
|
||||
}
|
||||
private void checkForBadTypeIdentifierUsage(String image) {
|
||||
if (jdkVersion >= 10 && "var".equals(image)) {
|
||||
throwParseException("With JDK 10, 'var' is a restricted local variable type and cannot be used for type declarations!");
|
||||
}
|
||||
}
|
||||
|
||||
// This is a semantic LOOKAHEAD to determine if we're dealing with an assert
|
||||
// Note that this can't be replaced with a syntactic lookahead
|
||||
@ -1647,7 +1656,7 @@ void ClassOrInterfaceDeclaration(int modifiers):
|
||||
{
|
||||
( /* See note about this optional final modifier in BlockStatement */
|
||||
["final"|"abstract"] "class" | "interface" { jjtThis.setInterface(); inInterface = true; } )
|
||||
t=<IDENTIFIER> { jjtThis.setImage(t.image); }
|
||||
t=<IDENTIFIER> { checkForBadTypeIdentifierUsage(t.image); jjtThis.setImage(t.image); }
|
||||
[ TypeParameters() ]
|
||||
[ ExtendsList() ]
|
||||
[ ImplementsList() ]
|
||||
@ -1679,7 +1688,7 @@ jjtThis.setModifiers(modifiers);
|
||||
}
|
||||
{
|
||||
t = <IDENTIFIER> {
|
||||
if (!t.image.equals("enum")) {
|
||||
if (!"enum".equals(t.image)) {
|
||||
throw new ParseException("ERROR: expecting enum");
|
||||
}
|
||||
|
||||
@ -1687,7 +1696,7 @@ jjtThis.setModifiers(modifiers);
|
||||
throw new ParseException("ERROR: Can't use enum as a keyword in pre-JDK 1.5 target");
|
||||
}
|
||||
}
|
||||
t=<IDENTIFIER> {jjtThis.setImage(t.image);}
|
||||
t=<IDENTIFIER> {checkForBadTypeIdentifierUsage(t.image); jjtThis.setImage(t.image);}
|
||||
[ ImplementsList() ]
|
||||
EnumBody()
|
||||
}
|
||||
@ -1870,13 +1879,17 @@ void Initializer() :
|
||||
|
||||
/*
|
||||
* Type, name and expression syntax follows.
|
||||
* Type is the same as "UnannType" in JLS
|
||||
*
|
||||
* See https://docs.oracle.com/javase/specs/jls/se10/html/jls-8.html#jls-UnannType
|
||||
*/
|
||||
void Type():
|
||||
{}
|
||||
{
|
||||
LOOKAHEAD(2) ReferenceType()
|
||||
|
|
||||
PrimitiveType()
|
||||
Token t;
|
||||
}
|
||||
{
|
||||
LOOKAHEAD(2) ReferenceType()
|
||||
| PrimitiveType()
|
||||
}
|
||||
|
||||
void ReferenceType():
|
||||
@ -2327,15 +2340,25 @@ void BlockStatement():
|
||||
LOOKAHEAD( (Annotation())* ["final"|"abstract"] "class") (Annotation())* ClassOrInterfaceDeclaration(0)
|
||||
}
|
||||
|
||||
/*
|
||||
* See https://docs.oracle.com/javase/specs/jls/se10/html/jls-14.html#jls-14.4
|
||||
*/
|
||||
void LocalVariableDeclaration() :
|
||||
{}
|
||||
{
|
||||
( "final" {jjtThis.setFinal(true);} | Annotation() )*
|
||||
Type()
|
||||
LocalVariableType()
|
||||
VariableDeclarator()
|
||||
( "," VariableDeclarator() )*
|
||||
}
|
||||
|
||||
void LocalVariableType() #void :
|
||||
{}
|
||||
{
|
||||
LOOKAHEAD( { jdkVersion >= 10 && isKeyword("var") } ) <IDENTIFIER>
|
||||
| Type()
|
||||
}
|
||||
|
||||
void EmptyStatement() :
|
||||
{}
|
||||
{
|
||||
@ -2491,7 +2514,7 @@ void Resources() :
|
||||
void Resource() :
|
||||
{}
|
||||
{
|
||||
LOOKAHEAD(2) ( ( "final" {jjtThis.setFinal(true);} | Annotation() )* Type() VariableDeclaratorId() "=" Expression() )
|
||||
LOOKAHEAD(2) ( ( "final" {jjtThis.setFinal(true);} | Annotation() )* LocalVariableType() VariableDeclaratorId() "=" Expression() )
|
||||
|
|
||||
Name() {checkForBadConciseTryWithResourcesUsage();}
|
||||
}
|
||||
@ -2620,7 +2643,13 @@ Token t;
|
||||
jjtThis.setModifiers(modifiers);
|
||||
}
|
||||
{
|
||||
"@" "interface" t=<IDENTIFIER> {checkForBadAnnotationUsage();jjtThis.setImage(t.image);} AnnotationTypeBody()
|
||||
"@" "interface" t=<IDENTIFIER>
|
||||
{
|
||||
checkForBadAnnotationUsage();
|
||||
checkForBadTypeIdentifierUsage(t.image);
|
||||
jjtThis.setImage(t.image);
|
||||
}
|
||||
AnnotationTypeBody()
|
||||
}
|
||||
|
||||
void AnnotationTypeBody():
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -23,7 +23,8 @@ public class JavaLanguageModule extends BaseLanguageModule {
|
||||
addVersion("1.6", new JavaLanguageHandler(6), false);
|
||||
addVersion("1.7", new JavaLanguageHandler(7), false);
|
||||
addVersion("1.8", new JavaLanguageHandler(8), false);
|
||||
addVersion("9", new JavaLanguageHandler(9), true);
|
||||
addVersion("9", new JavaLanguageHandler(9), false);
|
||||
addVersion("10", new JavaLanguageHandler(10), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,32 +37,49 @@ public class ASTLocalVariableDeclaration extends AbstractJavaAccessNode implemen
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, this local variable declaration represents a declaration,
|
||||
* which makes use of local variable type inference, e.g. java10 "var".
|
||||
* You can receive the inferred type via {@link ASTVariableDeclarator#getType()}.
|
||||
*
|
||||
* @see ASTVariableDeclaratorId#isTypeInferred()
|
||||
*/
|
||||
public boolean isTypeInferred() {
|
||||
return getTypeNode() == null;
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return checkType() + checkDecl() > 0;
|
||||
return getArrayDepth() > 0;
|
||||
}
|
||||
|
||||
public int getArrayDepth() {
|
||||
return checkType() + checkDecl();
|
||||
return getArrayDimensionOnType() + getArrayDimensionOnDeclaratorId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type node for this variable declaration statement.
|
||||
* With Java10 and local variable type inference, there might be
|
||||
* no type node at all.
|
||||
* @return The type node or <code>null</code>
|
||||
* @see #isTypeInferred()
|
||||
*/
|
||||
public ASTType getTypeNode() {
|
||||
for (int i = 0; i < jjtGetNumChildren(); i++) {
|
||||
if (jjtGetChild(i) instanceof ASTType) {
|
||||
return (ASTType) jjtGetChild(i);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("ASTType not found");
|
||||
return getFirstChildOfType(ASTType.class);
|
||||
}
|
||||
|
||||
private int checkType() {
|
||||
return getTypeNode().getArrayDepth();
|
||||
private int getArrayDimensionOnType() {
|
||||
ASTType typeNode = getTypeNode();
|
||||
if (typeNode != null) {
|
||||
return typeNode.getArrayDepth();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private ASTVariableDeclaratorId getDecl() {
|
||||
return (ASTVariableDeclaratorId) jjtGetChild(jjtGetNumChildren() - 1).jjtGetChild(0);
|
||||
}
|
||||
|
||||
private int checkDecl() {
|
||||
private int getArrayDimensionOnDeclaratorId() {
|
||||
return getDecl().getArrayDepth();
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,15 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
/**
|
||||
* Represents a type reference.
|
||||
*
|
||||
* <pre>
|
||||
* Type ::= ReferenceType | PrimitiveType
|
||||
* </pre>
|
||||
*
|
||||
* Note: it is not exactly the same the "UnnanType" defined in JLS.
|
||||
*/
|
||||
public class ASTType extends AbstractJavaTypeNode {
|
||||
public ASTType(int id) {
|
||||
super(id);
|
||||
@ -35,12 +44,10 @@ public class ASTType extends AbstractJavaTypeNode {
|
||||
&& (jjtGetChild(0) instanceof ASTReferenceType || jjtGetChild(0) instanceof ASTPrimitiveType)) {
|
||||
return ((Dimensionable) jjtGetChild(0)).getArrayDepth();
|
||||
}
|
||||
throw new RuntimeException("ASTType.getArrayDepth called, but first child (of " + jjtGetNumChildren()
|
||||
+ " total children) is neither a primitive nor a reference type.");
|
||||
return 0; // this is not an array
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return getArrayDepth() > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -142,9 +142,24 @@ public class ASTVariableDeclaratorId extends AbstractJavaTypeNode implements Dim
|
||||
* since the type node is absent.
|
||||
*/
|
||||
public boolean isTypeInferred() {
|
||||
return isLambdaExpression() || isLocalVariableTypeInferred();
|
||||
}
|
||||
|
||||
private boolean isLambdaExpression() {
|
||||
return jjtGetParent() instanceof ASTLambdaExpression;
|
||||
}
|
||||
|
||||
private boolean isLocalVariableTypeInferred() {
|
||||
if (jjtGetParent() instanceof ASTResource) {
|
||||
// covers "var" in try-with-resources
|
||||
return jjtGetParent().getFirstChildOfType(ASTType.class) == null;
|
||||
} else if (getNthParent(2) instanceof ASTLocalVariableDeclaration) {
|
||||
// covers "var" as local variables and in for statements
|
||||
return getNthParent(2).getFirstChildOfType(ASTType.class) == null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first child of the node returned by {@link #getTypeNode()}.
|
||||
|
@ -48,8 +48,10 @@ public class CheckResultSetRule extends AbstractJavaRule {
|
||||
|
||||
@Override
|
||||
public Object visit(ASTLocalVariableDeclaration node, Object data) {
|
||||
ASTClassOrInterfaceType type = node.getFirstChildOfType(ASTType.class)
|
||||
.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
|
||||
ASTClassOrInterfaceType type = null;
|
||||
if (!node.isTypeInferred()) {
|
||||
type = node.getFirstChildOfType(ASTType.class).getFirstDescendantOfType(ASTClassOrInterfaceType.class);
|
||||
}
|
||||
if (type != null && (type.getType() != null && "java.sql.ResultSet".equals(type.getType().getName())
|
||||
|| "ResultSet".equals(type.getImage()))) {
|
||||
ASTVariableDeclarator declarator = node.getFirstChildOfType(ASTVariableDeclarator.class);
|
||||
|
@ -340,8 +340,10 @@ public class ForLoopCanBeForeachRule extends AbstractJavaRule {
|
||||
|
||||
Node prefix = suffix.jjtGetParent().jjtGetChild(0);
|
||||
|
||||
if (!(prefix instanceof ASTPrimaryPrefix) && prefix.jjtGetNumChildren() != 1
|
||||
&& !(prefix.jjtGetChild(0) instanceof ASTName)) {
|
||||
if (!(prefix instanceof ASTPrimaryPrefix) || prefix.jjtGetNumChildren() != 1
|
||||
|| !(prefix.jjtGetChild(0) instanceof ASTName)) {
|
||||
// it's either not a primary prefix, doesn't have children (can happen with this./super.)
|
||||
// or first child is not a name
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ public class CloseResourceRule extends AbstractJavaRule {
|
||||
for (ASTLocalVariableDeclaration var : vars) {
|
||||
ASTType type = var.getTypeNode();
|
||||
|
||||
if (type.jjtGetChild(0) instanceof ASTReferenceType) {
|
||||
if (type != null && type.jjtGetChild(0) instanceof ASTReferenceType) {
|
||||
ASTReferenceType ref = (ASTReferenceType) type.jjtGetChild(0);
|
||||
if (ref.jjtGetChild(0) instanceof ASTClassOrInterfaceType) {
|
||||
ASTClassOrInterfaceType clazz = (ASTClassOrInterfaceType) ref.jjtGetChild(0);
|
||||
|
@ -63,7 +63,7 @@ public class MoreThanOneLoggerRule extends AbstractJavaRule {
|
||||
if (count > 1) {
|
||||
return super.visit(node, data);
|
||||
}
|
||||
Node type = node.jjtGetParent().getFirstChildOfType(ASTType.class);
|
||||
ASTType type = node.jjtGetParent().getFirstChildOfType(ASTType.class);
|
||||
if (type != null) {
|
||||
Node reftypeNode = type.jjtGetChild(0);
|
||||
if (reftypeNode instanceof ASTReferenceType) {
|
||||
|
@ -100,8 +100,10 @@ public class UselessOperationOnImmutableRule extends AbstractJavaRule {
|
||||
*/
|
||||
private ASTVariableDeclaratorId getDeclaration(ASTLocalVariableDeclaration node) {
|
||||
ASTType type = node.getTypeNode();
|
||||
if (MAP_CLASSES.keySet().contains(type.getTypeImage())) {
|
||||
return node.getFirstDescendantOfType(ASTVariableDeclaratorId.class);
|
||||
if (type != null) {
|
||||
if (MAP_CLASSES.keySet().contains(type.getTypeImage())) {
|
||||
return node.getFirstDescendantOfType(ASTVariableDeclaratorId.class);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user