diff --git a/.ci/build-pr-win-macos.sh b/.ci/build-pr-win-macos.sh index 99a95fd050..0ed4437f10 100755 --- a/.ci/build-pr-win-macos.sh +++ b/.ci/build-pr-win-macos.sh @@ -24,7 +24,7 @@ log_group_start "Downloading maven dependencies" log_group_end log_group_start "Building with maven" - ./mvnw -e -V clean verify ${PMD_EXTRA_OPT} + ./mvnw -e -V -B clean verify ${PMD_EXTRA_OPT} log_group_end diff --git a/.ci/build.sh b/.ci/build.sh index 247f904861..1705fb5602 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -123,7 +123,7 @@ function pmd_ci_build_run() { log_info "This is a snapshot build" fi - ./mvnw clean deploy -P${mvn_profiles} -e -V -Djava8.home=${HOME}/openjdk8 + ./mvnw clean deploy -P${mvn_profiles} -e -B -V -Djava8.home=${HOME}/openjdk8 } # diff --git a/.ci/inc/maven-dependencies.inc b/.ci/inc/maven-dependencies.inc index 12d1de380a..32ab18a984 100644 --- a/.ci/inc/maven-dependencies.inc +++ b/.ci/inc/maven-dependencies.inc @@ -23,19 +23,20 @@ function maven_dependencies_resolve() { # build first the modules, that have dependencies between themselves # first build pmd-lang-test, pmd-test and pmd-core - used by all modules ./mvnw clean install -pl pmd-core,pmd-test,pmd-lang-test -DskipTests -Dpmd.skip=true \ - -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -Dmaven.source.skip=true + -B -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -Dmaven.source.skip=true # then build dependencies for pmd-visualforce needs: pmd-apex->pmd-apex-jorje+pmd-test+pmd-core ./mvnw clean install -pl pmd-core,pmd-test,pmd-lang-test,pmd-apex-jorje,pmd-apex -DskipTests -Dpmd.skip=true \ - -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -Dmaven.source.skip=true + -B -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -Dmaven.source.skip=true # the resolve most other projects. The excluded projects depend on other projects in the reactor, which is not # completely built yet, so these are excluded. - ./mvnw dependency:resolve -pl '!pmd-dist,!pmd-doc,!pmd-scala' + ./mvnw dependency:resolve -pl '!pmd-dist,!pmd-doc,!pmd-scala' -Dsilent -B - ./mvnw dependency:get -DgroupId=org.jetbrains.dokka \ + ./mvnw dependency:get -B -Dsilent \ + -DgroupId=org.jetbrains.dokka \ -DartifactId=dokka-maven-plugin \ -Dversion=${dokka_version} \ -Dpackaging=jar \ -DremoteRepositories=jcenter::default::https://jcenter.bintray.com/ - ./mvnw dependency:resolve-plugins -DexcludeGroupIds=org.jetbrains.dokka -Psign + ./mvnw dependency:resolve-plugins -B -Dsilent -DexcludeGroupIds=org.jetbrains.dokka -Psign } diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 8abb75f161..330109f07b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -19,11 +19,27 @@ This is a {{ site.pmd.release_type }} release. ### New and noteworthy +#### Modified Rules + +* The Apex rule {% rule "apex/documentation/ApexDoc" %} has two new properties: `reportPrivate` and + `reportProtected`. Previously the rule only considered public and global classes, methods, and + properties. With these properties, you can verify the existence of ApexDoc comments for private + and protected methods as well. By default, these properties are disabled to preserve backwards + compatible behavior. + ### Fixed Issues +* apex-documentation + * [#3075](https://github.com/pmd/pmd/issues/3075): \[apex] ApexDoc should support private access modifier +* plsql + * [#3106](https://github.com/pmd/pmd/issues/3106): \[plsql] ParseException while parsing EXECUTE IMMEDIATE 'drop database link ' || linkname; + ### API Changes ### External Contributions +* [#3098](https://github.com/pmd/pmd/pull/3098): \[apex] ApexDoc optionally report private and protected - [Jonathan Wiesel](https://github.com/jonathanwiesel) +* [#3107](https://github.com/pmd/pmd/pull/3107): \[plsql] Fix ParseException for EXECUTE IMMEDIATE str1||str2; - [hvbtup](https://github.com/hvbtup) + {% endtocmaker %} diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java index 5242b24394..bdcee693be 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.apex.rule.documentation; +import static net.sourceforge.pmd.properties.PropertyFactory.booleanProperty; + import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -23,8 +25,10 @@ import net.sourceforge.pmd.lang.apex.ast.ASTUserInterface; import net.sourceforge.pmd.lang.apex.ast.ApexNode; import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; import net.sourceforge.pmd.lang.rule.RuleTargetSelector; +import net.sourceforge.pmd.properties.PropertyDescriptor; public class ApexDocRule extends AbstractApexRule { + private static final Pattern DESCRIPTION_PATTERN = Pattern.compile("@description\\s"); private static final Pattern RETURN_PATTERN = Pattern.compile("@return\\s"); private static final Pattern PARAM_PATTERN = Pattern.compile("@param\\s+(\\w+)\\s"); @@ -35,12 +39,24 @@ public class ApexDocRule extends AbstractApexRule { private static final String UNEXPECTED_RETURN_MESSAGE = "Unexpected ApexDoc @return"; private static final String MISMATCHED_PARAM_MESSAGE = "Missing or mismatched ApexDoc @param"; + private static final PropertyDescriptor REPORT_PRIVATE_DESCRIPTOR = + booleanProperty("reportPrivate") + .desc("Report private classes and methods").defaultValue(false).build(); + + private static final PropertyDescriptor REPORT_PROTECTED_DESCRIPTOR = + booleanProperty("reportProtected") + .desc("Report protected methods").defaultValue(false).build(); + + public ApexDocRule() { + definePropertyDescriptor(REPORT_PRIVATE_DESCRIPTOR); + definePropertyDescriptor(REPORT_PROTECTED_DESCRIPTOR); + } + @Override protected @NonNull RuleTargetSelector buildTargetSelector() { return RuleTargetSelector.forTypes(ASTUserClass.class, ASTUserInterface.class, ASTMethod.class, ASTProperty.class); } - @Override public Object visit(ASTUserClass node, Object data) { handleClassOrInterface(node, data); @@ -135,7 +151,9 @@ public class ApexDocRule extends AbstractApexRule { ASTModifierNode modifier = node.getFirstChildOfType(ASTModifierNode.class); if (modifier != null) { - return (modifier.isPublic() || modifier.isGlobal()) && !modifier.isOverride(); + boolean flagPrivate = getProperty(REPORT_PRIVATE_DESCRIPTOR) && modifier.isPrivate(); + boolean flagProtected = getProperty(REPORT_PROTECTED_DESCRIPTOR) && modifier.isProtected(); + return (modifier.isPublic() || modifier.isGlobal() || flagPrivate || flagProtected) && !modifier.isOverride(); } return false; } diff --git a/pmd-apex/src/main/resources/category/apex/documentation.xml b/pmd-apex/src/main/resources/category/apex/documentation.xml index 29027030a9..5699ab1dff 100644 --- a/pmd-apex/src/main/resources/category/apex/documentation.xml +++ b/pmd-apex/src/main/resources/category/apex/documentation.xml @@ -18,13 +18,15 @@ Rules that are related to code documentation. This rule validates that: -* ApexDoc comments are present for classes, methods, and properties that are public or global, excluding -overrides and test classes (as well as the contents of test classes). -* ApexDoc comments should contain @description. -* ApexDoc comments on non-void, non-constructor methods should contain @return. -* ApexDoc comments on void or constructor methods should not contain @return. -* ApexDoc comments on methods with parameters should contain @param for each parameter, in the same -order as the method signature. +* ApexDoc comments are present for classes, methods, and properties that are public or global, excluding + overrides and test classes (as well as the contents of test classes). +* ApexDoc comments are present for classes, methods, and properties that are protected or private, depending + on the properties `reportPrivate` and `reportProtected`. +* ApexDoc comments should contain @description. +* ApexDoc comments on non-void, non-constructor methods should contain @return. +* ApexDoc comments on void or constructor methods should not contain @return. +* ApexDoc comments on methods with parameters should contain @param for each parameter, in the same + order as the method signature. Method overrides and tests are both exempted from having ApexDoc. diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml index d21e45d92e..0bd349a322 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml @@ -48,6 +48,15 @@ private class Foo { } ]]> + + private class should have comment if specified + true + 1 + + + class comment should have description 1 @@ -109,6 +118,15 @@ private interface Foo { } ]]> + + private interface should have comment if specified + true + 1 + + + interface comment should have description 1 @@ -168,6 +186,62 @@ public class Foo { ]]> + + private method does not need comment + 0 + + + + + + private method should have comment if specified + true + 1 + + + + + protected method does not need comment + 0 + + + + + + protected method should have comment if specified + true + 1 + + + public override method does not need comment 0 @@ -355,6 +429,60 @@ public class Foo { ]]> + + private property does not need a comment + 0 + + + + + private property should have a comment if specified + true + 1 + + + + + protected property does not need a comment + 0 + + + + + protected property should have a comment if specified + true + 1 + + + property comment should have description 1 diff --git a/pmd-plsql/etc/grammar/PLSQL.jjt b/pmd-plsql/etc/grammar/PLSQL.jjt index 097b6391ff..22f57b8ed9 100644 --- a/pmd-plsql/etc/grammar/PLSQL.jjt +++ b/pmd-plsql/etc/grammar/PLSQL.jjt @@ -2660,7 +2660,7 @@ ASTFetchStatement FetchStatement() : ASTEmbeddedSqlStatement EmbeddedSqlStatement() : {} { - (StringLiteral() | Expression()) + StringExpression() [ Name() ("," Name())* ] [ [ [ ] | ] Expression() ("," [ [ ] | ] Expression())* ] [ ( | ) Expression() ("," Expression())*] ";" diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserTest.java index 0caea6b6f7..52d71e2bcc 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserTest.java @@ -73,4 +73,9 @@ public class PLSQLParserTest extends AbstractPLSQLParserTst { public void testCaseIssue1454() { plsql.parseResource("CaseIssue1454.pls"); } + + @Test + public void testExecuteImmediateIssue3106() { + plsql.parseResource("ExecuteImmediateIssue3106.pls"); + } } diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateIssue3106.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateIssue3106.pls new file mode 100644 index 0000000000..93789405e2 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateIssue3106.pls @@ -0,0 +1,11 @@ +-- +-- BSD-style license; for more info see http://pmd.sourceforge.net/license.html +-- + +CREATE OR REPLACE PROCEDURE bar +IS + v_link varchar2(10) := 'xxx'; +BEGIN + -- EXECUTE IMMEDIATE with an expression instead of just a literal or variable. + EXECUTE IMMEDIATE 'drop database link ' || v_link; +END bar;