Merge branch 'master' into issue-2615
This commit is contained in:
@ -49,7 +49,7 @@ jobs:
|
||||
env: BUILD=publish
|
||||
|
||||
before_install:
|
||||
- bash .travis/before_install.sh "11.0.7+10"
|
||||
- bash .travis/before_install.sh "11.0.8+10"
|
||||
- source ${HOME}/java.env
|
||||
install: true
|
||||
before_script: true
|
||||
|
@ -4,7 +4,7 @@ set -e
|
||||
source .travis/logger.sh
|
||||
source .travis/common-functions.sh
|
||||
|
||||
VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec)
|
||||
VERSION=$(get_pom_version)
|
||||
log_info "Building PMD Coveralls.io report ${VERSION} on branch ${TRAVIS_BRANCH}"
|
||||
|
||||
if ! travis_isPush; then
|
||||
|
@ -7,7 +7,7 @@ source .travis/github-releases-api.sh
|
||||
source .travis/sourceforge-api.sh
|
||||
source .travis/regression-tester.sh
|
||||
|
||||
VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec)
|
||||
VERSION=$(get_pom_version)
|
||||
log_info "Building PMD ${VERSION} on branch ${TRAVIS_BRANCH}"
|
||||
|
||||
MVN_BUILD_FLAGS="-B -V"
|
||||
|
@ -8,7 +8,7 @@ source .travis/sourceforge-api.sh
|
||||
source .travis/pmd-code-api.sh
|
||||
|
||||
function main() {
|
||||
VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec)
|
||||
VERSION=$(get_pom_version)
|
||||
log_info "Building PMD Documentation ${VERSION} on branch ${TRAVIS_BRANCH}"
|
||||
|
||||
#
|
||||
|
@ -6,7 +6,7 @@ source .travis/common-functions.sh
|
||||
source .travis/github-releases-api.sh
|
||||
source .travis/sourceforge-api.sh
|
||||
|
||||
VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec)
|
||||
VERSION=$(get_pom_version)
|
||||
log_info "PMD Release ${VERSION}"
|
||||
|
||||
if ! travis_isPush; then
|
||||
|
@ -4,7 +4,7 @@ set -e
|
||||
source .travis/logger.sh
|
||||
source .travis/common-functions.sh
|
||||
|
||||
VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec)
|
||||
VERSION=$(get_pom_version)
|
||||
log_info "Building PMD Sonar ${VERSION} on branch ${TRAVIS_BRANCH}"
|
||||
|
||||
if ! travis_isPush; then
|
||||
|
@ -53,3 +53,7 @@ function travis_isWindows() {
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function get_pom_version() {
|
||||
echo $(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:3.0.0:exec)
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ echo "Releasing PMD"
|
||||
echo "-------------------------------------------"
|
||||
|
||||
# see also https://gist.github.com/pdunnavant/4743895
|
||||
CURRENT_VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec)
|
||||
CURRENT_VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:3.0.0:exec)
|
||||
RELEASE_VERSION=${CURRENT_VERSION%-SNAPSHOT}
|
||||
MAJOR=$(echo $RELEASE_VERSION | cut -d . -f 1)
|
||||
MINOR=$(echo $RELEASE_VERSION | cut -d . -f 2)
|
||||
|
@ -36,6 +36,7 @@ require_relative 'jdoc_namespace_tag'
|
||||
# * The (erased) types of method arguments must be fully qualified. This is the same
|
||||
# convention as in javadoc {@link} tags, so you can use you're IDE's javadoc auto-
|
||||
# complete and copy-paste. Namespaces also can be used for method arguments if they're from PMD.
|
||||
# * Use the name <init> to reference a constructor
|
||||
#
|
||||
#
|
||||
# * Defining custom namespaces
|
||||
@ -90,13 +91,15 @@ require_relative 'jdoc_namespace_tag'
|
||||
# - Include spaces in any part of the reference
|
||||
# - Use double or single quotes around the arguments
|
||||
# - Use the "#" suffix to reference a nested type, instead, use a dot "." and reference it like a normal type name
|
||||
# - Use `[]` instead of `...` for vararg parameters
|
||||
# - Use the type name instead of `<init>` for a constructor
|
||||
#
|
||||
#
|
||||
class JavadocTag < Liquid::Tag
|
||||
|
||||
QNAME_NO_NAMESPACE_REGEX = /((?:\w+\.)*\w+)/
|
||||
|
||||
ARG_REGEX = Regexp.new(Regexp.union(JDocNamespaceDeclaration::NAMESPACED_FQCN_REGEX, QNAME_NO_NAMESPACE_REGEX).source + '(\[\])*')
|
||||
ARG_REGEX = Regexp.new(Regexp.union(JDocNamespaceDeclaration::NAMESPACED_FQCN_REGEX, QNAME_NO_NAMESPACE_REGEX).source + '(\[\])*(...)?')
|
||||
ARGUMENTS_REGEX = Regexp.new('\(\)|\((' + ARG_REGEX.source + "(?:,(?:" + ARG_REGEX.source + "))*" + ')\)')
|
||||
|
||||
|
||||
@ -174,7 +177,7 @@ class JavadocTag < Liquid::Tag
|
||||
def self.get_visible_name(opts, type_fqcn, member_suffix, is_package_ref, resolved_type)
|
||||
|
||||
# method or field
|
||||
if member_suffix && Regexp.new('(\w+)(' + ARGUMENTS_REGEX.source + ")?") =~ member_suffix
|
||||
if member_suffix && Regexp.new('(\w+|<init>)(' + ARGUMENTS_REGEX.source + ")?") =~ member_suffix
|
||||
|
||||
suffix = $1 # method or field name
|
||||
|
||||
|
@ -14,16 +14,53 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
### Fixed Issues
|
||||
#### New Rules
|
||||
|
||||
* The new Java rule {% rule "java/bestpractices/UnusedAssignment" %} (`java-bestpractices`) finds assignments
|
||||
to variables, that are never used and are useless. The new rule is supposed to entirely replace
|
||||
{% rule "java/errorprone/DataflowAnomalyAnalysis" %}.
|
||||
|
||||
### Fixed Issues
|
||||
* apex
|
||||
* [#2610](https://github.com/pmd/pmd/pull/2610): \[apex] Support top-level enums in rules
|
||||
* apex-bestpractices
|
||||
* [#2626](https://github.com/pmd/pmd/issues/2626): \[apex] UnusedLocalVariable - false positive on case insensitivity allowed in Apex
|
||||
* apex-security
|
||||
* [#2620](https://github.com/pmd/pmd/issues/2620): \[visualforce] False positive on VfUnescapeEl with new Message Channel feature
|
||||
* core
|
||||
* [#710](https://github.com/pmd/pmd/issues/710): \[core] Review used dependencies
|
||||
* [#2594](https://github.com/pmd/pmd/issues/2594): \[core] Update exec-maven-plugin and align it in all project
|
||||
* [#2615](https://github.com/pmd/pmd/issues/2615): \[core] PMD/CPD produces invalid XML (insufficient escaping/wrong encoding)
|
||||
* java-design
|
||||
* [#2174](https://github.com/pmd/pmd/issues/2174): \[java] LawOfDemeter: False positive with 'this' pointer
|
||||
* [#2189](https://github.com/pmd/pmd/issues/2189): \[java] LawOfDemeter: False positive when casting to derived class
|
||||
* java-errorprone
|
||||
* [#2578](https://github.com/pmd/pmd/issues/2578): \[java] AvoidCallingFinalize detects some false positives
|
||||
* [#2634](https://github.com/pmd/pmd/issues/2634): \[java] NullPointerException in rule ProperCloneImplementation
|
||||
* java-performance
|
||||
* [#1736](https://github.com/pmd/pmd/issues/1736): \[java] UseStringBufferForStringAppends: False positive if only one concatenation
|
||||
* [#2207](https://github.com/pmd/pmd/issues/2207): \[java] AvoidInstantiatingObjectsInLoops: False positive - should not flag objects when assigned to lists/arrays
|
||||
|
||||
### API Changes
|
||||
|
||||
#### Deprecated API
|
||||
|
||||
##### For removal
|
||||
|
||||
* {% jdoc core::lang.rule.RuleChainVisitor %} and all implementations in language modules
|
||||
* {% jdoc core::lang.rule.AbstractRuleChainVisitor %}
|
||||
* {% jdoc core::lang.Language#getRuleChainVisitorClass() %}
|
||||
* {% jdoc core::lang.BaseLanguageModule#<init>(java.lang.String,java.lang.String,java.lang.String,java.lang.Class,java.lang.String...) %}
|
||||
|
||||
|
||||
### External Contributions
|
||||
* [#2558](https://github.com/pmd/pmd/pull/2558): \[java] Fix issue #1736 and issue #2207 - [Young Chan](https://github.com/YYoungC)
|
||||
* [#2560](https://github.com/pmd/pmd/pull/2560): \[java] Fix false positives of LawOfDemeter: this and cast expressions - [xioayuge](https://github.com/xioayuge)
|
||||
* [#2590](https://github.com/pmd/pmd/pull/2590): Update libraries snyk is referring to as `unsafe` - [Artem Krosheninnikov](https://github.com/KroArtem)
|
||||
* [#2597](https://github.com/pmd/pmd/pull/2597): \[dependencies] Fix issue #2594, update exec-maven-plugin everywhere - [Artem Krosheninnikov](https://github.com/KroArtem)
|
||||
* [#2621](https://github.com/pmd/pmd/pull/2621): \[visualforce] add new safe resource for VfUnescapeEl - [Peter Chittum](https://github.com/pchittum)
|
||||
* [#2640](https://github.com/pmd/pmd/pull/2640): \[java] NullPointerException in rule ProperCloneImplementation - [Mykhailo Palahuta](https://github.com/Drofff)
|
||||
* [#2643](https://github.com/pmd/pmd/pull/2643): \[java] AvoidCallingFinalize detects some false positives (2578) - [Mykhailo Palahuta](https://github.com/Drofff)
|
||||
|
||||
{% endtocmaker %}
|
||||
|
||||
|
@ -54,12 +54,12 @@
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.1.7</version>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
<version>1.1.7</version>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
@ -89,7 +89,6 @@
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr-runtime</artifactId>
|
||||
<version>3.5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
@ -119,7 +118,7 @@
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.17</version>
|
||||
<version>1.26</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>aopalliance</groupId>
|
||||
|
209
pmd-apex/pom.xml
209
pmd-apex/pom.xml
@ -1,125 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>pmd-apex</artifactId>
|
||||
<name>PMD Apex</name>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>pmd-apex</artifactId>
|
||||
<name>PMD Apex</name>
|
||||
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.26.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.26.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>8</java.version>
|
||||
</properties>
|
||||
<properties>
|
||||
<java.version>8</java.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${basedir}/src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<configuration>
|
||||
<useDefaultDelimiters>false</useDefaultDelimiters>
|
||||
<delimiters>
|
||||
<delimiter>${*}</delimiter>
|
||||
</delimiters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>pmd-apex-jorje</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>lib</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>pmd-apex-jorje</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.saxon</groupId>
|
||||
<artifactId>saxon</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.stefanbirkner</groupId>
|
||||
<artifactId>system-rules</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-lang-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>designer</id>
|
||||
<build>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${basedir}/src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<configuration>
|
||||
<mainClass>net.sourceforge.pmd.util.designer.Designer</mainClass>
|
||||
<includePluginDependencies>true</includePluginDependencies>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-java</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<configuration>
|
||||
<useDefaultDelimiters>false</useDefaultDelimiters>
|
||||
<delimiters>
|
||||
<delimiter>${*}</delimiter>
|
||||
</delimiters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr-runtime</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>pmd-apex-jorje</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>lib</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>pmd-apex-jorje</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.stefanbirkner</groupId>
|
||||
<artifactId>system-rules</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-lang-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -5,18 +5,20 @@
|
||||
package net.sourceforge.pmd.lang.apex;
|
||||
|
||||
import net.sourceforge.pmd.lang.BaseLanguageModule;
|
||||
import net.sourceforge.pmd.lang.apex.rule.ApexRuleChainVisitor;
|
||||
import net.sourceforge.pmd.util.CollectionUtil;
|
||||
|
||||
import apex.jorje.services.Version;
|
||||
|
||||
public class ApexLanguageModule extends BaseLanguageModule {
|
||||
private static final String FIRST_EXTENSION = "cls";
|
||||
private static final String[] REMAINING_EXTENSIONS = {"trigger"};
|
||||
|
||||
public static final String NAME = "Apex";
|
||||
public static final String TERSE_NAME = "apex";
|
||||
public static final String[] EXTENSIONS = { "cls", "trigger" };
|
||||
public static final String[] EXTENSIONS = CollectionUtil.listOf(FIRST_EXTENSION, REMAINING_EXTENSIONS).toArray(new String[0]);
|
||||
|
||||
public ApexLanguageModule() {
|
||||
super(NAME, null, TERSE_NAME, ApexRuleChainVisitor.class, EXTENSIONS);
|
||||
super(NAME, null, TERSE_NAME, FIRST_EXTENSION, REMAINING_EXTENSIONS);
|
||||
addVersion(String.valueOf((int) Version.CURRENT.getExternal()), new ApexHandler(), true);
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,6 @@ package net.sourceforge.pmd.lang.apex.metrics;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface;
|
||||
@ -136,7 +134,6 @@ public final class ApexMetrics {
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
public static List<ASTMethod> findOps(ASTUserClassOrInterface<?> node) {
|
||||
List<ASTMethod> candidates = node.findChildrenOfType(ASTMethod.class);
|
||||
List<ASTMethod> result = new ArrayList<>(candidates);
|
||||
|
@ -8,6 +8,7 @@ import java.util.Stack;
|
||||
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserEnum;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserTrigger;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitorReducedAdapter;
|
||||
|
||||
@ -41,6 +42,12 @@ public class ApexMultifileVisitor extends ApexParserVisitorReducedAdapter {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object visit(ASTUserEnum node, Object data) {
|
||||
return data; // ignore
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object visit(ASTMethod node, Object data) {
|
||||
stack.peek().addOperation(node.getQualifiedName().getOperation(), node.getSignature());
|
||||
|
@ -137,12 +137,8 @@ public abstract class AbstractApexRule extends AbstractRule
|
||||
|
||||
protected void visitAll(List<? extends Node> nodes, RuleContext ctx) {
|
||||
for (Object element : nodes) {
|
||||
if (element instanceof ASTUserClass) {
|
||||
visit((ASTUserClass) element, ctx);
|
||||
} else if (element instanceof ASTUserInterface) {
|
||||
visit((ASTUserInterface) element, ctx);
|
||||
} else if (element instanceof ASTUserTrigger) {
|
||||
visit((ASTUserTrigger) element, ctx);
|
||||
if (element instanceof ApexNode<?>) {
|
||||
((ApexNode<?>) element).jjtAccept(this, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,14 @@ import net.sourceforge.pmd.lang.apex.ast.ApexNode;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitor;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.rule.AbstractRuleChainVisitor;
|
||||
import net.sourceforge.pmd.lang.rule.RuleChainVisitor;
|
||||
import net.sourceforge.pmd.lang.rule.XPathRule;
|
||||
|
||||
/**
|
||||
* @deprecated for removal with PMD 7. A language dependent rule chain visitor is not needed anymore.
|
||||
* See {@link RuleChainVisitor}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ApexRuleChainVisitor extends AbstractRuleChainVisitor {
|
||||
|
||||
@Override
|
||||
|
@ -129,13 +129,6 @@ public class StdCyclomaticComplexityRule extends AbstractApexRule {
|
||||
|
||||
@Override
|
||||
public Object visit(ASTUserEnum node, Object data) {
|
||||
entryStack.push(new Entry());
|
||||
super.visit(node, data);
|
||||
Entry classEntry = entryStack.pop();
|
||||
if (classEntry.getComplexityAverage() >= reportLevel || classEntry.highestDecisionPoints >= reportLevel) {
|
||||
addViolation(data, node, new String[] { "class", node.getImage(),
|
||||
classEntry.getComplexityAverage() + "(Highest = " + classEntry.highestDecisionPoints + ')', });
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.rule;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTAnonymousClass;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserEnum;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserInterface;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserTrigger;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexParserTestBase;
|
||||
|
||||
import apex.jorje.semantic.ast.compilation.Compilation;
|
||||
|
||||
public class AbstractApexRuleTest extends ApexParserTestBase {
|
||||
|
||||
@Test
|
||||
public void shouldVisitTopLevelClass() {
|
||||
run("class Foo { }");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVisitTopLevelInterface() {
|
||||
run("interface Foo { }");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVisitTopLevelTrigger() {
|
||||
run("trigger Foo on Account (before insert, before update) { }");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVisitTopLevelEnum() {
|
||||
run("enum Foo { }");
|
||||
}
|
||||
|
||||
private void run(String code) {
|
||||
ApexNode<Compilation> node = parse(code);
|
||||
RuleContext ctx = new RuleContext();
|
||||
ctx.setLanguageVersion(apex.getDefaultVersion());
|
||||
TopLevelRule rule = new TopLevelRule();
|
||||
rule.apply(Collections.singletonList(node), ctx);
|
||||
assertEquals(1, ctx.getReport().size());
|
||||
}
|
||||
|
||||
private static class TopLevelRule extends AbstractApexRule {
|
||||
@Override
|
||||
public Object visit(ASTUserClass node, Object data) {
|
||||
addViolation(data, node);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTUserInterface node, Object data) {
|
||||
addViolation(data, node);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTUserTrigger node, Object data) {
|
||||
addViolation(data, node);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTUserEnum node, Object data) {
|
||||
addViolation(data, node);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTAnonymousClass node, Object data) {
|
||||
addViolation(data, node);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
@ -63,6 +63,14 @@ public class Foo {
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>top-level enum all is well</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public enum FooEnum { }
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>test class default is title case</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
@ -121,6 +129,17 @@ public class Foo {
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>top-level enum default is title case</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-messages>
|
||||
<message>The enum name 'fooEnum' doesn't match '[A-Z][a-zA-Z0-9_]*'</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
public enum fooEnum { }
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>custom test class pattern</description>
|
||||
<rule-property name="testClassPattern">[a-zA-Z0-9_]+</rule-property>
|
||||
@ -157,4 +176,22 @@ public class FOO_CLASS { }
|
||||
public interface FOO_INTERFACE { }
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>custom enum pattern</description>
|
||||
<rule-property name="enumPattern">E[a-zA-Z0-9_]+</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public enum EFOO_ENUM { }
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>custom enum pattern</description>
|
||||
<rule-property name="enumPattern">E[a-zA-Z0-9_]+</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public enum FooEnum { }
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
||||
|
@ -97,6 +97,12 @@
|
||||
<artifactId>ant</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.javacc</groupId>
|
||||
<artifactId>javacc</artifactId>
|
||||
<scope>provided</scope> <!-- only needed for generating the parser via ant -->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
@ -122,10 +128,7 @@
|
||||
-->
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.javacc</groupId>
|
||||
<artifactId>javacc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.saxon</groupId>
|
||||
<artifactId>saxon</artifactId>
|
||||
|
@ -11,6 +11,9 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sourceforge.pmd.lang.internal.DefaultRulechainVisitor;
|
||||
import net.sourceforge.pmd.util.CollectionUtil;
|
||||
|
||||
/**
|
||||
* Created by christoferdutz on 21.09.14.
|
||||
*/
|
||||
@ -25,6 +28,12 @@ public abstract class BaseLanguageModule implements Language {
|
||||
protected Map<String, LanguageVersion> versions;
|
||||
protected LanguageVersion defaultVersion;
|
||||
|
||||
/**
|
||||
* @deprecated Use the other constructor. It doesn't require a
|
||||
* rulechain visitor class, but forces you to mention at least
|
||||
* one file extension.
|
||||
*/
|
||||
@Deprecated
|
||||
public BaseLanguageModule(String name, String shortName, String terseName, Class<?> ruleChainVisitorClass,
|
||||
String... extensions) {
|
||||
this.name = name;
|
||||
@ -34,6 +43,18 @@ public abstract class BaseLanguageModule implements Language {
|
||||
this.extensions = Arrays.asList(extensions);
|
||||
}
|
||||
|
||||
public BaseLanguageModule(String name,
|
||||
String shortName,
|
||||
String terseName,
|
||||
String firstExtension,
|
||||
String... otherExtensions) {
|
||||
this.name = name;
|
||||
this.shortName = shortName;
|
||||
this.terseName = terseName;
|
||||
this.ruleChainVisitorClass = DefaultRulechainVisitor.class;
|
||||
this.extensions = CollectionUtil.listOf(firstExtension, otherExtensions);
|
||||
}
|
||||
|
||||
private void addVersion(String version, LanguageVersionHandler languageVersionHandler, boolean isDefault, String... versionAliases) {
|
||||
if (versions == null) {
|
||||
versions = new HashMap<>();
|
||||
@ -177,4 +198,6 @@ public abstract class BaseLanguageModule implements Language {
|
||||
public int compareTo(Language o) {
|
||||
return getName().compareTo(o.getName());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -77,7 +77,10 @@ public interface Language extends Comparable<Language> {
|
||||
*
|
||||
* @return The RuleChainVisitor class.
|
||||
* @see net.sourceforge.pmd.lang.rule.RuleChainVisitor
|
||||
*
|
||||
* @deprecated Will be removed in PMD 7, avoid using this
|
||||
*/
|
||||
@Deprecated
|
||||
Class<?> getRuleChainVisitorClass();
|
||||
|
||||
/**
|
||||
|
@ -71,7 +71,16 @@ public final class LanguageRegistry {
|
||||
// TODO This is unnecessary, if the incomplete language modules have been removed.
|
||||
List<Language> languages = new ArrayList<>();
|
||||
for (Language language : getInstance().languages.values()) {
|
||||
if (language.getRuleChainVisitorClass() != null) {
|
||||
LanguageVersionHandler languageVersionHandler = language.getDefaultVersion().getLanguageVersionHandler();
|
||||
boolean pmdSupported = false;
|
||||
|
||||
if (languageVersionHandler != null) {
|
||||
ParserOptions defaultParserOptions = languageVersionHandler.getDefaultParserOptions();
|
||||
Parser parser = languageVersionHandler.getParser(defaultParserOptions);
|
||||
pmdSupported = parser.canParse();
|
||||
}
|
||||
|
||||
if (pmdSupported) {
|
||||
languages.add(language);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.rule.AbstractRuleChainVisitor;
|
||||
import net.sourceforge.pmd.lang.rule.RuleChainVisitor;
|
||||
|
||||
/**
|
||||
* @deprecated See {@link RuleChainVisitor}
|
||||
*/
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
public class DefaultRulechainVisitor extends AbstractRuleChainVisitor {
|
||||
|
||||
@Override
|
||||
protected void visit(Rule rule, Node node, RuleContext ctx) {
|
||||
rule.apply(Collections.singletonList(node), ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void indexNodes(List<Node> nodes, RuleContext ctx) {
|
||||
for (Node node : nodes) {
|
||||
indexNodeRec(node);
|
||||
}
|
||||
}
|
||||
|
||||
protected void indexNodeRec(Node top) {
|
||||
indexNode(top);
|
||||
for (Node child : top.children()) {
|
||||
indexNodeRec(child);
|
||||
}
|
||||
}
|
||||
}
|
@ -28,7 +28,10 @@ import net.sourceforge.pmd.lang.ast.Node;
|
||||
* This is a base class for RuleChainVisitor implementations which extracts
|
||||
* interesting nodes from an AST, and lets each Rule visit the nodes it has
|
||||
* expressed interest in.
|
||||
*
|
||||
* @deprecated See {@link RuleChainVisitor}
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractRuleChainVisitor implements RuleChainVisitor {
|
||||
private static final Logger LOG = Logger.getLogger(AbstractRuleChainVisitor.class.getName());
|
||||
|
||||
|
@ -9,12 +9,18 @@ import java.util.List;
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.RuleSet;
|
||||
import net.sourceforge.pmd.lang.BaseLanguageModule;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
|
||||
/**
|
||||
* The RuleChainVisitor understands how to visit an AST for a particular
|
||||
* Language.
|
||||
*
|
||||
* @deprecated This interface will be removed. It's only used in internal
|
||||
* code. Language implementors no longer need to register a rulechain
|
||||
* visitor implementation in the {@link BaseLanguageModule} constructor.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface RuleChainVisitor {
|
||||
/**
|
||||
* Add the given rule to the visitor.
|
||||
|
@ -8,6 +8,7 @@ import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@ -187,6 +188,15 @@ public final class CollectionUtil {
|
||||
return list;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> List<T> listOf(T first, T... rest) {
|
||||
// note: 7.0.x already has a better version of that
|
||||
ArrayList<T> result = new ArrayList<>(rest.length + 1);
|
||||
result.add(first);
|
||||
Collections.addAll(result, rest);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the objects are array instances and each of their
|
||||
|
13
pmd-core/src/main/resources/rulesets/releases/6260.xml
Normal file
13
pmd-core/src/main/resources/rulesets/releases/6260.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<ruleset name="6260"
|
||||
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
|
||||
<description>
|
||||
This ruleset contains links to rules that are new in PMD v6.26.0
|
||||
</description>
|
||||
|
||||
<rule ref="category/java/bestpractices.xml/UnusedAssignment" />
|
||||
|
||||
</ruleset>
|
@ -13,7 +13,7 @@ public class Dummy2LanguageModule extends BaseLanguageModule {
|
||||
public static final String TERSE_NAME = "dummy2";
|
||||
|
||||
public Dummy2LanguageModule() {
|
||||
super(NAME, null, TERSE_NAME, null, "dummy2");
|
||||
super(NAME, null, TERSE_NAME, "dummy2");
|
||||
addVersion("1.0", new DummyLanguageModule.Handler(), true);
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user