Merge branch 'master' into pr-3246
This commit is contained in:
84 files changed
+1812
-394
No files matched your search
+2
-1
@@ -7,7 +7,8 @@ It uses the common scripts from [build-tools](https://github.com/pmd/build-tools
|
||||
|
||||
This files contains the following environment variables:
|
||||
|
||||
* DANGER_GITHUB_API_TOKEN: Token for danger to add comments to PRs as <https://github.com/pmd-test>
|
||||
* DANGER_GITHUB_API_TOKEN: Token for danger to add comments to PRs as <https://github.com/pmd-test>.
|
||||
The token needs the scope "public_repo".
|
||||
* PMD_CI_CHUNK_TOKEN: Token for uploading reports to chunk.io
|
||||
|
||||
The file is encrypted, so that the tokens are not automatically disabled when github detects them
|
||||
|
||||
+11
-10
@@ -1,13 +1,14 @@
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
jA0ECQMCkmcn6+I5p8D/0sDSAW6N6nliZko1kP0nXZ7303ywGHypHRzLyIhaiOKl
|
||||
9afpeACRJ995FY66KL1NZdaeoujK3gFFl0QtTFrcde2KZTyoqrS1Nfro5RGkXYI8
|
||||
AyX/kaEd54bVlsiUbHWBjiAUvK83wJiIhClKhD13mpKtsVr5Ep+Rb6j/zeoIkJ8k
|
||||
sKkS97qZjiXQVGwZzb42tO8W/K2fsahwBUfYU+pGzkqE9jPQPkVDBvWWZTczrj6p
|
||||
PVWyuREFa0Tdpc2py7+/bS/ls+1JUer6GxYsNl+KiZvCUyBDVL67M42tNzU/cAcA
|
||||
fdNVkzIB5TCgmUFlIrH43utl/f9O2bXC09NzK+xr3VPSp4BvO8fVA1DfDGswnMgz
|
||||
OctjRQXeOJZys5Z+Ls01C37ropAC8JTzT+UHM/v0VoQmoKhBx6+ehHkqzwDeUmbV
|
||||
QJ4HMFsWGyTPy64SCZbS4aOWaQx0q0NFFU7Kmdu4RQNq0u6aODZ99lEvdCODGe70
|
||||
vl5qVkzp2q8b6ayY1DUVo4kIvhu3KqFllETnVnHq4J8TCJLw
|
||||
=goqq
|
||||
jA0ECQMC6NJFOgCtLK790sDsAV7zf22dX5W7Ki3LdPBesQvoN+fU5xjNcu9ytrOQ
|
||||
pNDQybzmGkBU7gJM5sasTEv2OKp7h+nt8xSfaE8u0i4G0+yLGZKxbCrZoHnoBiaW
|
||||
udpjvvxyKdEV8wn1DPsh/W9ARmxdJezpreUwmwExamYiVEXsWOr2DWST+DPVX+4I
|
||||
5vAxi/YqO1/Pn+s/wIOKM/57otuVxwzwyUFxItJF4GV3NeCKt1cDQHRT1OSn2Mlw
|
||||
1LY8oUJgjKVCzI9F7xSlHYRYtvUK2icc7lvwrUliXIlcVetUB6Swe5AJmtmQ63y0
|
||||
EU52Uh7VPYjj929QgpoVpJHGTJl/Omyk63nb1EOrDWEVUMzg4fDsbAsmzvPyD/FR
|
||||
R6S9OeJUCsLMXlu7MRHCQi0vDk3li25pVqJmFm9Ahk8tkY/yzgQLoWmVEOhl8xDY
|
||||
oEQh0XNy9TxvzRzYlutYdU7K4ACohNsJN/MpKkRVzA3aMIBrNjVGa0dF8kd+7grg
|
||||
fJ+MW8skcpIHDegDcxVAs+O4r9VO3UDAcx3E/kgdLAKSOV0sRt4ZbJZaML7sKkSV
|
||||
muTtIhHzGwB41qKichY=
|
||||
=fgy5
|
||||
-----END PGP MESSAGE-----
|
||||
@@ -11,6 +11,7 @@ on:
|
||||
schedule:
|
||||
# build it monthly: At 04:00 on day-of-month 1.
|
||||
- cron: '0 4 1 * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -28,12 +29,13 @@ jobs:
|
||||
with:
|
||||
path: |
|
||||
~/.m2/repository
|
||||
~/.gradle/caches
|
||||
~/.cache
|
||||
~/work/pmd/target/repositories
|
||||
vendor/bundle
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
|
||||
key: v1-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-
|
||||
v1-${{ runner.os }}-
|
||||
- name: Set up Ruby 2.7
|
||||
uses: actions/setup-ruby@v1
|
||||
with:
|
||||
@@ -43,7 +45,7 @@ jobs:
|
||||
run: |
|
||||
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
|
||||
echo "MAVEN_OPTS=-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/11/scripts" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/12/scripts" >> $GITHUB_ENV
|
||||
- name: Check Environment
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/11/scripts" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/12/scripts" >> $GITHUB_ENV
|
||||
- name: Sync
|
||||
run: .ci/git-repo-sync.sh
|
||||
shell: bash
|
||||
|
||||
@@ -16,12 +16,14 @@ jobs:
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.m2/repository
|
||||
~/.cache
|
||||
vendor/bundle
|
||||
key: push-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
|
||||
~/.m2/repository
|
||||
~/.gradle/caches
|
||||
~/.cache
|
||||
~/work/pmd/target/repositories
|
||||
vendor/bundle
|
||||
key: v1-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
push-${{ runner.os }}-
|
||||
v1-${{ runner.os }}-
|
||||
- name: Set up Ruby 2.7
|
||||
uses: actions/setup-ruby@v1
|
||||
with:
|
||||
@@ -31,7 +33,7 @@ jobs:
|
||||
run: |
|
||||
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
|
||||
echo "MAVEN_OPTS=-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3 -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/11/scripts" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/12/scripts" >> $GITHUB_ENV
|
||||
- name: Check Environment
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
+2
-1
@@ -16,7 +16,8 @@ This will create the zip files in the directory `pmd-dist/target`:
|
||||
|
||||
That's all !
|
||||
|
||||
**Note:** While Java 11 is required for building, running PMD only requires Java 7 (or Java 8 for Apex and the Designer).
|
||||
**Note:** While Java 11 is required for building, running PMD only requires Java 7
|
||||
(or Java 8 for Apex, JavaScript, Scala, Visualforce, and the Designer).
|
||||
|
||||
**Note:** With PMD 6.24.0, we are creating [Reproducible Builds](https://reproducible-builds.org/). Since we use
|
||||
[Maven](https://maven.apache.org/guides/mini/guide-reproducible-builds.html) for building, the following
|
||||
|
||||
+4
-4
@@ -39,14 +39,14 @@ GEM
|
||||
kramdown (1.17.0)
|
||||
liquid (5.0.1)
|
||||
logger-colors (1.0.0)
|
||||
mini_portile2 (2.5.0)
|
||||
mini_portile2 (2.5.1)
|
||||
multipart-post (2.1.1)
|
||||
nap (1.1.0)
|
||||
no_proxy_fix (0.1.2)
|
||||
nokogiri (1.11.3)
|
||||
nokogiri (1.11.5)
|
||||
mini_portile2 (~> 2.5.0)
|
||||
racc (~> 1.4)
|
||||
octokit (4.20.0)
|
||||
octokit (4.21.0)
|
||||
faraday (>= 0.9)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
open4 (1.3.4)
|
||||
@@ -68,7 +68,7 @@ GEM
|
||||
sawyer (0.8.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (> 0.8, < 2.0)
|
||||
slop (4.8.2)
|
||||
slop (4.9.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
tzinfo (2.0.4)
|
||||
|
||||
+15
-11
@@ -1,7 +1,7 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (6.0.3.6)
|
||||
activesupport (6.0.3.7)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
@@ -22,15 +22,19 @@ GEM
|
||||
em-websocket (0.5.2)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
ethon (0.12.0)
|
||||
ffi (>= 1.3.0)
|
||||
ethon (0.14.0)
|
||||
ffi (>= 1.15.0)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.7.0)
|
||||
faraday (1.3.0)
|
||||
execjs (2.8.1)
|
||||
faraday (1.4.1)
|
||||
faraday-excon (~> 1.1)
|
||||
faraday-net_http (~> 1.0)
|
||||
faraday-net_http_persistent (~> 1.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ruby2_keywords
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-excon (1.1.0)
|
||||
faraday-net_http (1.0.1)
|
||||
faraday-net_http_persistent (1.1.0)
|
||||
ffi (1.15.0)
|
||||
forwardable-extended (2.6.0)
|
||||
gemoji (3.0.1)
|
||||
@@ -205,27 +209,27 @@ GEM
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
mercenary (0.3.6)
|
||||
mini_portile2 (2.5.0)
|
||||
mini_portile2 (2.5.1)
|
||||
minima (2.5.1)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-feed (~> 0.9)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
minitest (5.14.4)
|
||||
multipart-post (2.1.1)
|
||||
nokogiri (1.11.2)
|
||||
nokogiri (1.11.5)
|
||||
mini_portile2 (~> 2.5.0)
|
||||
racc (~> 1.4)
|
||||
octokit (4.20.0)
|
||||
octokit (4.21.0)
|
||||
faraday (>= 0.9)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
pathutil (0.16.2)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (4.0.6)
|
||||
racc (1.5.2)
|
||||
rb-fsevent (0.10.4)
|
||||
rb-fsevent (0.11.0)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rexml (3.2.4)
|
||||
rexml (3.2.5)
|
||||
rouge (3.26.0)
|
||||
ruby-enum (0.9.0)
|
||||
i18n
|
||||
|
||||
@@ -12,7 +12,8 @@ author: Tom Copeland, Xavier Le Vourch <xlv@users.sourceforge.net>
|
||||
|
||||
* JDK 11 or higher
|
||||
|
||||
{% include note.html content="While Java 11 is required for building, running PMD only requires Java 7 (or Java 8 for Apex, Scala, Visualforce, and the Designer)." %}
|
||||
{% include note.html content="While Java 11 is required for building, running PMD only requires Java 7
|
||||
(or Java 8 for Apex, JavaScript, Scala, Visualforce, and the Designer)." %}
|
||||
|
||||
You’ll need to either check out the source code or download the latest source release. Assuming you’ve got the latest source release, unzip it to a directory:
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ The tool comes with a rather extensive help text, simply running with `-help`!
|
||||
%}
|
||||
{% include custom/cli_option_row.html options="-reportfile,-r"
|
||||
option_arg="path"
|
||||
description="Path to a file in which the report output will be sent. By default the report is printed on standard output."
|
||||
description="Path to a file to which report output is written. The file is created if it does not exist. If this option is not specified, the report is rendered to standard output."
|
||||
%}
|
||||
{% include custom/cli_option_row.html options="-shortnames"
|
||||
description="Prints shortened filenames in the report."
|
||||
|
||||
@@ -11,7 +11,13 @@ sidebar: pmd_sidebar
|
||||
|
||||
### Requirements
|
||||
|
||||
* [Java JRE](http://www.oracle.com/technetwork/java/javase/downloads/index.html) 1.7 or higher
|
||||
* [Java JRE](http://www.oracle.com/technetwork/java/javase/downloads/index.html),
|
||||
OpenJDK from [Azul](https://www.azul.com/downloads/zulu-community/)
|
||||
or [AdoptOpenJDK](https://adoptopenjdk.net/) 1.7 or higher.
|
||||
|
||||
**Note:** For analyzing Apex, JavaScript, Scala or VisualForce or running the [Designer](pmd_userdocs_extending_designer_reference.html)
|
||||
at least Java 8 is required.
|
||||
|
||||
* A zip archiver, e.g.:
|
||||
|
||||
* For Windows: [Winzip](http://winzip.com) or the free [7-zip](http://www.7-zip.org/)
|
||||
|
||||
@@ -14,14 +14,99 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
#### Javascript module now requires at least Java 8
|
||||
|
||||
The latest version of [Rhino](https://github.com/mozilla/rhino), the implementation of JavaScript we use
|
||||
for parsing JavaScript code, requires at least Java 8. Therefore we decided to upgrade the pmd-javascript
|
||||
module to Java 8 as well. This means that from now on, a Java 8 or later runtime is required in order
|
||||
to analyze JavaScript code. Note that PMD core still only requires Java 7.
|
||||
|
||||
#### New rules
|
||||
|
||||
* The new Java rule {% rule "java/bestpractices/JUnit5TestShouldBePackagePrivate" %}
|
||||
enforces the convention that JUnit 5 tests should have minimal visibility.
|
||||
You can try out this rule like so:
|
||||
```xml
|
||||
<rule ref="category/java/bestpractices.xml/JUnit5TestShouldBePackagePrivate" />
|
||||
```
|
||||
|
||||
#### Modified rules
|
||||
|
||||
* The Java rule {% rule "java/errorprone/CompareObjectsWithEquals" %} has now a new property
|
||||
`typesThatCompareByReference`. With that property, you can configure types, that should be whitelisted
|
||||
for comparison by reference. By default, `java.lang.Enum` and `java.lang.Class` are allowed, but
|
||||
you could add custom types here.
|
||||
Additionally comparisons against constants are allowed now. This makes the rule less noisy when two constants
|
||||
are compared. Constants are identified by looking for an all-caps identifier.
|
||||
|
||||
#### Deprecated rules
|
||||
|
||||
* The java rule {% rule "java/codestyle/DefaultPackage" %} has been deprecated in favor of
|
||||
{% rule "java/codestyle/CommentDefaultAccessModifier" %}.
|
||||
|
||||
The rule "DefaultPackage" assumes that any usage of package-access is accidental,
|
||||
and by doing so, prohibits using a really fundamental and useful feature of the language.
|
||||
|
||||
To satisfy the rule, you have to make the member public even if it doesn't need to, or make it protected,
|
||||
which muddies your intent even more if you don't intend the class to be extended, and may be at odds with
|
||||
other rules like {% rule "java/codestyle/AvoidProtectedFieldInFinalClass" %}.
|
||||
|
||||
The rule {% rule "java/codestyle/CommentDefaultAccessModifier" %} should be used instead.
|
||||
It flags the same thing, but has an escape hatch.
|
||||
|
||||
* The Java rule {% rule "java/errorprone/CloneThrowsCloneNotSupportedException" %} has been deprecated without
|
||||
replacement.
|
||||
|
||||
The rule has no real value as `CloneNotSupportedException` is a
|
||||
checked exception and therefore you need to deal with it while implementing the `clone()` method. You either
|
||||
need to declare the exception or catch it. If you catch it, then subclasses can't throw it themselves explicitly.
|
||||
However, `Object.clone()` will still throw this exception if the `Cloneable` interface is not implemented.
|
||||
|
||||
Note, this rule has also been removed from the Quickstart Ruleset (`rulesets/java/quickstart.xml`).
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
* apex
|
||||
* [#3183](https://github.com/pmd/pmd/issues/3183): \[apex] ApexUnitTestMethodShouldHaveIsTestAnnotation false positive with helper method
|
||||
* [#3243](https://github.com/pmd/pmd/pull/3243): \[apex] Correct findBoundary when traversing AST
|
||||
* core
|
||||
* [#2639](https://github.com/pmd/pmd/issues/2639): \[core] PMD CLI output file is not created if directory or directories in path don't exist
|
||||
* doc
|
||||
* [#3230](https://github.com/pmd/pmd/issues/3230): \[doc] Remove "Edit me" button for language index pages
|
||||
* dist
|
||||
* [#2466](https://github.com/pmd/pmd/issues/2466): \[dist] Distribution archive doesn't include all batch scripts
|
||||
* java
|
||||
* [#3269](https://github.com/pmd/pmd/pull/3269): \[java] Fix NPE in MethodTypeResolution
|
||||
* java-bestpractices
|
||||
* [#1175](https://github.com/pmd/pmd/issues/1175): \[java] UnusedPrivateMethod FP with Junit 5 @MethodSource
|
||||
* [#2219](https://github.com/pmd/pmd/issues/2219): \[java] Document Reasons to Avoid Reassigning Parameters
|
||||
* [#2737](https://github.com/pmd/pmd/issues/2737): \[java] Fix misleading rule message on rule SwitchStmtsShouldHaveDefault with non-exhaustive enum switch
|
||||
* [#3236](https://github.com/pmd/pmd/issues/3236): \[java] LiteralsFirstInComparisons should consider constant fields (cont'd)
|
||||
* [#3254](https://github.com/pmd/pmd/issues/3254): \[java] AvoidReassigningParameters reports violations on wrong line numbers
|
||||
* java-codestyle
|
||||
* [#2655](https://github.com/pmd/pmd/issues/2655): \[java] UnnecessaryImport false positive for on-demand imports
|
||||
* [#3206](https://github.com/pmd/pmd/issues/3206): \[java] Deprecate rule DefaultPackage
|
||||
* [#3262](https://github.com/pmd/pmd/pull/3262): \[java] FieldDeclarationsShouldBeAtStartOfClass: false negative with anon classes
|
||||
* [#3265](https://github.com/pmd/pmd/pull/3265): \[java] MethodArgumentCouldBeFinal: false negatives with interfaces and inner classes
|
||||
* [#3266](https://github.com/pmd/pmd/pull/3266): \[java] LocalVariableCouldBeFinal: false negatives with interfaces, anon classes
|
||||
* [#3274](https://github.com/pmd/pmd/pull/3274): \[java] OnlyOneReturn: false negative with anonymous class
|
||||
* [#3275](https://github.com/pmd/pmd/pull/3275): \[java] UnnecessaryLocalBeforeReturn: false negatives with lambda and anon class
|
||||
* java-design
|
||||
* [#2780](https://github.com/pmd/pmd/issues/2780): \[java] DataClass example from documentation results in false-negative
|
||||
* java-errorprone
|
||||
* [#3110](https://github.com/pmd/pmd/issues/3110): \[java] Enhance CompareObjectsWithEquals with list of exceptions
|
||||
* [#3112](https://github.com/pmd/pmd/issues/3112): \[java] Deprecate rule CloneThrowsCloneNotSupportedException
|
||||
* [#3205](https://github.com/pmd/pmd/issues/3205): \[java] Make CompareObjectWithEquals allow comparing against constants
|
||||
* [#3248](https://github.com/pmd/pmd/issues/3248): \[java] Documentation is wrong for SingletonClassReturningNewInstance rule
|
||||
* [#3249](https://github.com/pmd/pmd/pull/3249): \[java] AvoidFieldNameMatchingTypeName: False negative with interfaces
|
||||
* [#3268](https://github.com/pmd/pmd/pull/3268): \[java] ConstructorCallsOverridableMethod: IndexOutOfBoundsException with annotations
|
||||
* javascript
|
||||
* [#699](https://github.com/pmd/pmd/issues/699): \[javascript] Update Rhino library to 1.7.13
|
||||
* [#2081](https://github.com/pmd/pmd/issues/2081): \[javascript] Failing with OutOfMemoryError parsing a Javascript file
|
||||
|
||||
### API Changes
|
||||
|
||||
### External Contributions
|
||||
* [#3272](https://github.com/pmd/pmd/pull/3272): \[apex] correction for ApexUnitTestMethodShouldHaveIsTestAnnotation false positives - [William Brockhus](https://github.com/YodaDaCoda)
|
||||
|
||||
{% endtocmaker %}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import static apex.jorje.semantic.symbol.type.ModifierTypeInfos.TEST_METHOD;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
|
||||
import apex.jorje.semantic.ast.modifier.ModifierNode;
|
||||
@@ -62,10 +64,20 @@ public class ASTModifierNode extends AbstractApexNode<ModifierNode> implements A
|
||||
return (node.getModifiers().getJavaModifiers() & TRANSIENT) == TRANSIENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if function has `@isTest` annotation or `testmethod` modifier
|
||||
*/
|
||||
public boolean isTest() {
|
||||
return node.getModifiers().isTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if function has `testmethod` modifier
|
||||
*/
|
||||
public boolean hasDeprecatedTestMethod() {
|
||||
return node.getModifiers().has(TEST_METHOD);
|
||||
}
|
||||
|
||||
public boolean isTestOrTestSetup() {
|
||||
return node.getModifiers().isTestOrTestSetup();
|
||||
}
|
||||
|
||||
@@ -50,4 +50,9 @@ public abstract class ApexRootNode<T extends AstNode> extends AbstractApexNode<T
|
||||
public double getApexVersion() {
|
||||
return node.getDefiningType().getCodeUnitDetails().getVersion().getExternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFindBoundary() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.rule.bestpractices;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethodCallExpression;
|
||||
import net.sourceforge.pmd.lang.apex.rule.AbstractApexUnitTestRule;
|
||||
|
||||
public class ApexUnitTestMethodShouldHaveIsTestAnnotationRule extends AbstractApexUnitTestRule {
|
||||
private static final Set<String> ASSERT_METHODS = new HashSet<>();
|
||||
|
||||
static {
|
||||
ASSERT_METHODS.add("system.assert");
|
||||
ASSERT_METHODS.add("system.assertequals");
|
||||
ASSERT_METHODS.add("system.assertnotequals");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(final ASTMethod node, final Object data) {
|
||||
// test methods should have @isTest annotation.
|
||||
if (isTestMethodOrClass(node)) {
|
||||
return data;
|
||||
}
|
||||
return checkForAssertStatements(node, data);
|
||||
}
|
||||
|
||||
private Object checkForAssertStatements(final ASTMethod testMethod, final Object data) {
|
||||
List<ASTMethodCallExpression> methodCallList = testMethod.findDescendantsOfType(ASTMethodCallExpression.class);
|
||||
String assertMethodName;
|
||||
for (ASTMethodCallExpression assertMethodCall : methodCallList) {
|
||||
assertMethodName = assertMethodCall.getFullMethodName().toLowerCase(Locale.ROOT);
|
||||
if (ASSERT_METHODS.contains(assertMethodName)) {
|
||||
addViolationWithMessage(data, testMethod,
|
||||
"''{0}'' method should have @IsTest annotation.",
|
||||
new Object[] { testMethod.getImage() });
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
+1
@@ -35,6 +35,7 @@ public class ApexBadCryptoRule extends AbstractApexRule {
|
||||
private final Set<String> potentiallyStaticBlob = new HashSet<>();
|
||||
|
||||
public ApexBadCryptoRule() {
|
||||
addRuleChainVisit(ASTUserClass.class);
|
||||
setProperty(CODECLIMATE_CATEGORIES, "Security");
|
||||
setProperty(CODECLIMATE_REMEDIATION_MULTIPLIER, 100);
|
||||
setProperty(CODECLIMATE_BLOCK_HIGHLIGHTING, false);
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public class ApexDangerousMethodsRule extends AbstractApexRule {
|
||||
private final Set<String> whiteListedVariables = new HashSet<>();
|
||||
|
||||
public ApexDangerousMethodsRule() {
|
||||
super.addRuleChainVisit(ASTUserClass.class);
|
||||
addRuleChainVisit(ASTUserClass.class);
|
||||
setProperty(CODECLIMATE_CATEGORIES, "Security");
|
||||
setProperty(CODECLIMATE_REMEDIATION_MULTIPLIER, 100);
|
||||
setProperty(CODECLIMATE_BLOCK_HIGHLIGHTING, false);
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ public class ApexOpenRedirectRule extends AbstractApexRule {
|
||||
private final Set<String> listOfStringLiteralVariables = new HashSet<>();
|
||||
|
||||
public ApexOpenRedirectRule() {
|
||||
super.addRuleChainVisit(ASTUserClass.class);
|
||||
addRuleChainVisit(ASTUserClass.class);
|
||||
setProperty(CODECLIMATE_CATEGORIES, "Security");
|
||||
setProperty(CODECLIMATE_REMEDIATION_MULTIPLIER, 100);
|
||||
setProperty(CODECLIMATE_BLOCK_HIGHLIGHTING, false);
|
||||
|
||||
+1
@@ -51,6 +51,7 @@ public class ApexSOQLInjectionRule extends AbstractApexRule {
|
||||
private final Map<String, Boolean> selectContainingVariables = new HashMap<>();
|
||||
|
||||
public ApexSOQLInjectionRule() {
|
||||
addRuleChainVisit(ASTUserClass.class);
|
||||
setProperty(CODECLIMATE_CATEGORIES, "Security");
|
||||
setProperty(CODECLIMATE_REMEDIATION_MULTIPLIER, 100);
|
||||
setProperty(CODECLIMATE_BLOCK_HIGHLIGHTING, false);
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ public class ApexSuggestUsingNamedCredRule extends AbstractApexRule {
|
||||
private final Set<String> listOfAuthorizationVariables = new HashSet<>();
|
||||
|
||||
public ApexSuggestUsingNamedCredRule() {
|
||||
super.addRuleChainVisit(ASTUserClass.class);
|
||||
addRuleChainVisit(ASTUserClass.class);
|
||||
setProperty(CODECLIMATE_CATEGORIES, "Security");
|
||||
setProperty(CODECLIMATE_REMEDIATION_MULTIPLIER, 100);
|
||||
setProperty(CODECLIMATE_BLOCK_HIGHLIGHTING, false);
|
||||
|
||||
+1
@@ -23,6 +23,7 @@ public class ApexXSSFromEscapeFalseRule extends AbstractApexRule {
|
||||
private static final String ADD_ERROR = "addError";
|
||||
|
||||
public ApexXSSFromEscapeFalseRule() {
|
||||
addRuleChainVisit(ASTUserClass.class);
|
||||
setProperty(CODECLIMATE_CATEGORIES, "Security");
|
||||
setProperty(CODECLIMATE_REMEDIATION_MULTIPLIER, 100);
|
||||
setProperty(CODECLIMATE_BLOCK_HIGHLIGHTING, false);
|
||||
|
||||
@@ -64,16 +64,28 @@ public class Foo {
|
||||
</rule>
|
||||
|
||||
<rule name="ApexUnitTestMethodShouldHaveIsTestAnnotation"
|
||||
language="apex"
|
||||
since="6.13.0"
|
||||
language="apex"
|
||||
message="Apex test methods should have @isTest annotation."
|
||||
class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexUnitTestMethodShouldHaveIsTestAnnotationRule"
|
||||
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexunittestmethodshouldhaveistestannotation">
|
||||
<description>
|
||||
Apex test methods should have @isTest annotation.
|
||||
As testMethod keyword is deprecated, Salesforce advices to use @isTest annotation for test class/methods.
|
||||
Apex test methods should have `@isTest` annotation instead of the `testMethod` keyword,
|
||||
as `testMethod` is deprecated.
|
||||
Salesforce advices to use [@isTest](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_isTest.htm)
|
||||
annotation for test classes and methods.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//Method[ModifierNode[@DeprecatedTestMethod = true()]]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
</properties>
|
||||
<example>
|
||||
<![CDATA[
|
||||
@isTest
|
||||
@@ -86,7 +98,7 @@ private class ATest {
|
||||
@isTest static void methodCTest() {
|
||||
System.assert(1==2);
|
||||
}
|
||||
@isTest static void methodCTest() {
|
||||
static testmethod void methodCTest() {
|
||||
System.debug('I am a debug statement');
|
||||
}
|
||||
private void fetchData() {
|
||||
@@ -94,6 +106,7 @@ private class ATest {
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
|
||||
</rule>
|
||||
|
||||
<rule name="ApexUnitTestShouldNotUseSeeAllDataTrue"
|
||||
|
||||
+16
-16
@@ -1,11 +1,11 @@
|
||||
+- UserClass[@ApexVersion = 51.0, @DefiningType = "Foo", @Image = "Foo", @InterfaceNames = null, @Location = "(4, 14, 180, 183)", @Namespace = "", @RealLoc = true, @SuperClassName = "", @TypeKind = TypeKind.CLASS]
|
||||
+- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(4, 14, 180, 183)", @Modifiers = 1, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(4, 14, 180, 183)", @Modifiers = 1, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- Field[@DefiningType = "Foo", @Image = "x", @Location = "(5, 13, 198, 199)", @Name = "x", @Namespace = "", @RealLoc = true, @Type = "Integer", @Value = null]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(5, 13, 198, 199)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(5, 13, 198, 199)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- Field[@DefiningType = "Foo", @Image = "profileUrl", @Location = "(8, 12, 365, 375)", @Name = "profileUrl", @Namespace = "", @RealLoc = true, @Type = "String", @Value = null]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(8, 12, 365, 375)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(8, 12, 365, 375)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- FieldDeclarationStatements[@DefiningType = "Foo", @Location = "(5, 5, 190, 199)", @Namespace = "", @RealLoc = true, @TypeArguments = null, @TypeName = "Integer"]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "no location", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "no location", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- FieldDeclaration[@DefiningType = "Foo", @Image = "anIntegerField", @Location = "(5, 13, 198, 199)", @Name = "anIntegerField", @Namespace = "", @RealLoc = true]
|
||||
| +- VariableExpression[@DefiningType = "Foo", @Image = "anIntegerField", @Location = "(5, 27, 212, 226)", @Namespace = "", @RealLoc = true]
|
||||
| | +- ReferenceExpression[@Context = null, @DefiningType = "Foo", @Location = "no location", @Names = null, @Namespace = "", @RealLoc = false, @ReferenceType = ReferenceType.LOAD, @SafeNav = true]
|
||||
@@ -14,7 +14,7 @@
|
||||
| +- VariableExpression[@DefiningType = "Foo", @Image = "x", @Location = "(5, 13, 198, 199)", @Namespace = "", @RealLoc = true]
|
||||
| +- EmptyReferenceExpression[@DefiningType = null, @Location = "no location", @Namespace = null, @RealLoc = false]
|
||||
+- FieldDeclarationStatements[@DefiningType = "Foo", @Location = "(8, 5, 358, 375)", @Namespace = "", @RealLoc = true, @TypeArguments = null, @TypeName = "String"]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "no location", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "no location", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- FieldDeclaration[@DefiningType = "Foo", @Image = "profileUrl", @Location = "(8, 12, 365, 375)", @Name = "profileUrl", @Namespace = "", @RealLoc = true]
|
||||
| +- MethodCallExpression[@DefiningType = "Foo", @FullMethodName = "toExternalForm", @InputParametersSize = 0, @Location = "(8, 47, 400, 414)", @MethodName = "toExternalForm", @Namespace = "", @RealLoc = true]
|
||||
| | +- ReferenceExpression[@Context = null, @DefiningType = "Foo", @Location = "no location", @Names = null, @Namespace = "", @RealLoc = false, @ReferenceType = ReferenceType.METHOD, @SafeNav = true]
|
||||
@@ -23,9 +23,9 @@
|
||||
| +- VariableExpression[@DefiningType = "Foo", @Image = "profileUrl", @Location = "(8, 12, 365, 375)", @Namespace = "", @RealLoc = true]
|
||||
| +- EmptyReferenceExpression[@DefiningType = null, @Location = "no location", @Namespace = null, @RealLoc = false]
|
||||
+- Method[@Arity = 1, @CanonicalName = "bar1", @Constructor = false, @DefiningType = "Foo", @Image = "bar1", @Location = "(10, 17, 435, 439)", @Namespace = "", @RealLoc = true, @ReturnType = "void"]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(10, 17, 435, 439)", @Modifiers = 1, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(10, 17, 435, 439)", @Modifiers = 1, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- Parameter[@DefiningType = "Foo", @Image = "a", @Location = "(10, 29, 447, 448)", @Namespace = "", @RealLoc = true, @Type = "Object"]
|
||||
| | +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(10, 29, 447, 448)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| | +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(10, 29, 447, 448)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- BlockStatement[@CurlyBrace = true, @DefiningType = "Foo", @Location = "(10, 32, 450, 538)", @Namespace = "", @RealLoc = true]
|
||||
| +- ExpressionStatement[@DefiningType = "Foo", @Location = "(11, 12, 463, 465)", @Namespace = "", @RealLoc = true]
|
||||
| | +- VariableExpression[@DefiningType = "Foo", @Image = "b", @Location = "(11, 12, 463, 464)", @Namespace = "", @RealLoc = true]
|
||||
@@ -41,11 +41,11 @@
|
||||
| +- VariableExpression[@DefiningType = "Foo", @Image = "a1", @Location = "(12, 13, 518, 520)", @Namespace = "", @RealLoc = true]
|
||||
| +- EmptyReferenceExpression[@DefiningType = null, @Location = "no location", @Namespace = null, @RealLoc = false]
|
||||
+- Method[@Arity = 2, @CanonicalName = "bar2", @Constructor = false, @DefiningType = "Foo", @Image = "bar2", @Location = "(15, 17, 556, 560)", @Namespace = "", @RealLoc = true, @ReturnType = "void"]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(15, 17, 556, 560)", @Modifiers = 1, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(15, 17, 556, 560)", @Modifiers = 1, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- Parameter[@DefiningType = "Foo", @Image = "a", @Location = "(15, 31, 570, 571)", @Namespace = "", @RealLoc = true, @Type = "List<Object>"]
|
||||
| | +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(15, 31, 570, 571)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| | +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(15, 31, 570, 571)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- Parameter[@DefiningType = "Foo", @Image = "x", @Location = "(15, 38, 577, 578)", @Namespace = "", @RealLoc = true, @Type = "int"]
|
||||
| | +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(15, 38, 577, 578)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| | +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(15, 38, 577, 578)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- BlockStatement[@CurlyBrace = true, @DefiningType = "Foo", @Location = "(15, 41, 580, 688)", @Namespace = "", @RealLoc = true]
|
||||
| +- ExpressionStatement[@DefiningType = "Foo", @Location = "(16, 25, 606, 613)", @Namespace = "", @RealLoc = true]
|
||||
| | +- VariableExpression[@DefiningType = "Foo", @Image = "aField", @Location = "(16, 25, 606, 612)", @Namespace = "", @RealLoc = true]
|
||||
@@ -68,12 +68,12 @@
|
||||
| +- VariableExpression[@DefiningType = "Foo", @Image = "x", @Location = "(17, 11, 661, 662)", @Namespace = "", @RealLoc = true]
|
||||
| +- EmptyReferenceExpression[@DefiningType = null, @Location = "no location", @Namespace = null, @RealLoc = false]
|
||||
+- Method[@Arity = 1, @CanonicalName = "getName", @Constructor = false, @DefiningType = "Foo", @Image = "getName", @Location = "(20, 19, 708, 715)", @Namespace = "", @RealLoc = true, @ReturnType = "String"]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(20, 19, 708, 715)", @Modifiers = 1, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(20, 19, 708, 715)", @Modifiers = 1, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- Parameter[@DefiningType = "Foo", @Image = "accId", @Location = "(20, 31, 720, 725)", @Namespace = "", @RealLoc = true, @Type = "int"]
|
||||
| | +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(20, 31, 720, 725)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| | +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(20, 31, 720, 725)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- BlockStatement[@CurlyBrace = true, @DefiningType = "Foo", @Location = "(20, 38, 727, 905)", @Namespace = "", @RealLoc = true]
|
||||
| +- VariableDeclarationStatements[@DefiningType = "Foo", @Location = "(21, 9, 737, 745)", @Namespace = "", @RealLoc = true]
|
||||
| | +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "no location", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| | +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "no location", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| | +- VariableDeclaration[@DefiningType = "Foo", @Image = "s", @Location = "(21, 16, 744, 745)", @Namespace = "", @RealLoc = true, @Type = "String"]
|
||||
| | +- VariableExpression[@DefiningType = "Foo", @Image = "BillingCity", @Location = "(21, 37, 765, 776)", @Namespace = "", @RealLoc = true]
|
||||
| | | +- ReferenceExpression[@Context = null, @DefiningType = "Foo", @Location = "no location", @Names = null, @Namespace = "", @RealLoc = false, @ReferenceType = ReferenceType.LOAD, @SafeNav = true]
|
||||
@@ -89,10 +89,10 @@
|
||||
| +- VariableExpression[@DefiningType = "Foo", @Image = "accId", @Location = "(23, 54, 886, 891)", @Namespace = "", @RealLoc = true]
|
||||
| +- EmptyReferenceExpression[@DefiningType = null, @Location = "no location", @Namespace = null, @RealLoc = false]
|
||||
+- Method[@Arity = 0, @CanonicalName = "<clinit>", @Constructor = false, @DefiningType = "Foo", @Image = "<clinit>", @Location = "no location", @Namespace = "", @RealLoc = false, @ReturnType = "void"]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = false, @InheritedSharing = false, @Location = "(4, 14, 180, 183)", @Modifiers = 8, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = true, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Location = "(4, 14, 180, 183)", @Modifiers = 8, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = true, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- Method[@Arity = 0, @CanonicalName = "clone", @Constructor = false, @DefiningType = "Foo", @Image = "clone", @Location = "no location", @Namespace = "", @RealLoc = false, @ReturnType = "Object"]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = true, @InheritedSharing = false, @Location = "no location", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = true, @InheritedSharing = false, @Location = "no location", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- UserClassMethods[@DefiningType = "Foo", @Location = "no location", @Namespace = "", @RealLoc = false]
|
||||
| +- Method[@Arity = 0, @CanonicalName = "<init>", @Constructor = true, @DefiningType = "Foo", @Image = "<init>", @Location = "no location", @Namespace = "", @RealLoc = false, @ReturnType = "void"]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @Final = false, @Global = true, @InheritedSharing = false, @Location = "(4, 14, 180, 183)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = true, @InheritedSharing = false, @Location = "(4, 14, 180, 183)", @Modifiers = 0, @Namespace = "", @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
|
||||
+- BridgeMethodCreator[@DefiningType = "Foo", @Location = "no location", @Namespace = "", @RealLoc = false]
|
||||
+16
-2
@@ -14,7 +14,7 @@ private class ATest {
|
||||
@isTest
|
||||
static void methodATest() {
|
||||
}
|
||||
static void methodBTest() {
|
||||
static testmethod void methodBTest() {
|
||||
System.assert(1==2);
|
||||
}
|
||||
@isTest static void methodCTest() {
|
||||
@@ -26,7 +26,7 @@ private class ATest {
|
||||
static void methodETest() {
|
||||
System.debug('I am a debug statement.');
|
||||
}
|
||||
static void methodFTest() {
|
||||
static testmethod void methodFTest() {
|
||||
System.assertEquals(1,2);
|
||||
}
|
||||
private void fetchData() {
|
||||
@@ -69,6 +69,20 @@ private class A {
|
||||
private void fetchData() {
|
||||
System.assertEquals(1,1);
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>false positive with @testsetup #3282</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
@isTest
|
||||
public class TestFactory {
|
||||
@testsetup static void setup() {
|
||||
System.assertEquals(null, null, 'this should be null');
|
||||
}
|
||||
@isTest static void testCase1() { }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
+19
@@ -7,6 +7,7 @@
|
||||
<test-code>
|
||||
<description>Apex Crypto hardcoded IV</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>6</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public Foo() {
|
||||
@@ -76,6 +77,24 @@ public class Foo {
|
||||
Blob data = Blob.valueOf('Data to be encrypted');
|
||||
Blob encrypted = Crypto.encryptWithManagedIV('AES128', key, data);
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Apex Crypto hardcoded IV in inner class</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>7</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
class MyInnerClass {
|
||||
public MyInnerClass() {
|
||||
Blob exampleIv = Blob.valueOf('0000000000000000');
|
||||
Blob key = Crypto.generateAesKey(128);
|
||||
Blob data = Blob.valueOf('Data to be encrypted');
|
||||
Blob encrypted = Crypto.encrypt('AES128', key, exampleIv, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
+18
@@ -7,6 +7,7 @@
|
||||
<test-code>
|
||||
<description>Potentially unsafe SOQL on concatenation of variables 1</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>5</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void test1() {
|
||||
@@ -304,6 +305,23 @@ public class Foo {
|
||||
public void test1(String name) {
|
||||
List<SObject> res = Database.query('Select Id,Name From ' + (name == 'Account' ? name : 'Cases'));
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Potentially unsafe SOQL on concatenation of variables in nested class</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>6</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
class MyNestedClass {
|
||||
public void test1() {
|
||||
String field1 = getSomeID();
|
||||
String field2 = 'SELECT Id FROM Account WHERE Id =';
|
||||
Database.query(field2 + field1);
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
+16
@@ -7,6 +7,7 @@
|
||||
<test-code>
|
||||
<description>Add error variable with escape false</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>3</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void test1(String bad) {
|
||||
@@ -36,6 +37,21 @@ public class Foo {
|
||||
public void test1() {
|
||||
Trigger.new[0].addError('something else' + bad, false);
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Add error variable with escape false in nested class</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>4</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
class MyNestedClass {
|
||||
public void test1(String bad) {
|
||||
Trigger.new[0].addError(bad, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
@@ -89,7 +89,10 @@ public class PMDParameters {
|
||||
converter = PropertyConverter.class)
|
||||
private List<Properties> properties = new ArrayList<>();
|
||||
|
||||
@Parameter(names = { "-reportfile", "-r" }, description = "Sends report output to a file; default to System.out.")
|
||||
@Parameter(names = { "-reportfile", "-r" },
|
||||
description = "Path to a file to which report output is written. "
|
||||
+ "The file is created if it does not exist. "
|
||||
+ "If this option is not specified, the report is rendered to standard output.")
|
||||
private String reportfile = null;
|
||||
|
||||
@Parameter(names = { "-version", "-v" }, description = "Specify version of a language PMD should use.")
|
||||
|
||||
@@ -15,6 +15,7 @@ import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
@@ -62,16 +63,23 @@ public final class IOUtil {
|
||||
|
||||
/**
|
||||
* Creates a writer that writes to the given file or to stdout.
|
||||
* The file is created if it does not exist.
|
||||
*
|
||||
* <p>Warning: This writer always uses the system default charset.
|
||||
*
|
||||
* @param reportFile the file name (optional)
|
||||
* @return the writer, never <code>null</code>
|
||||
*
|
||||
* @return the writer, never null
|
||||
*/
|
||||
public static Writer createWriter(String reportFile) {
|
||||
try {
|
||||
return StringUtils.isBlank(reportFile) ? createWriter()
|
||||
: Files.newBufferedWriter(new File(reportFile).toPath(), getDefaultCharset());
|
||||
if (StringUtils.isBlank(reportFile)) {
|
||||
return createWriter();
|
||||
}
|
||||
Path path = new File(reportFile).toPath();
|
||||
Files.createDirectories(path.getParent()); // ensure parent dir exists
|
||||
// this will create the file if it doesn't exist
|
||||
return Files.newBufferedWriter(path, getDefaultCharset());
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
|
||||
@@ -732,6 +732,34 @@ public final class StringUtil {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the string starts and ends with the delimiter, returns the substring
|
||||
* within the delimiters. Otherwise returns the original string. The
|
||||
* start and end delimiter must be 2 separate instances.
|
||||
* <pre>{@code
|
||||
* removeSurrounding("", _ ) = ""
|
||||
* removeSurrounding("q", 'q') = "q"
|
||||
* removeSurrounding("qq", 'q') = ""
|
||||
* removeSurrounding("q_q", 'q') = "_"
|
||||
* }</pre>
|
||||
*/
|
||||
public static String removeSurrounding(String string, char delimiter) {
|
||||
if (string.length() >= 2
|
||||
&& string.charAt(0) == delimiter
|
||||
&& string.charAt(string.length() - 1) == delimiter) {
|
||||
return string.substring(1, string.length() - 1);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #removeSurrounding(String, char) removeSurrounding} with
|
||||
* a double quote as a delimiter.
|
||||
*/
|
||||
public static String removeDoubleQuotes(String string) {
|
||||
return removeSurrounding(string, '"');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an empty array of string
|
||||
|
||||
Loaded 30 of 84 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user