Merge branch 'master' into pr-3246

This commit is contained in:
Andreas Dangel committed 2021-05-25 19:11:09 +02:00
commit da36bb38a9
84 files changed
+1812 -394

No files matched your search

+2 -1
View File
@@ -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
View File
@@ -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-----
+5 -3
View File
@@ -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: |
+1 -1
View File
@@ -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
+8 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2 -1
View File
@@ -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)." %}
Youll need to either check out the source code or download the latest source release. Assuming youve got the latest source release, unzip it to a directory:
+1 -1
View File
@@ -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."
+7 -1
View File
@@ -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/)
+86 -1
View File
@@ -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;
}
}
@@ -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;
}
}
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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"
@@ -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]
@@ -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>
@@ -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>
@@ -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>
@@ -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