forked from phoedos/pmd
Merge branch 'master' into pmd/7.0.x
This commit is contained in:
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
#
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 %}
|
||||
|
||||
|
@ -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<Boolean> REPORT_PRIVATE_DESCRIPTOR =
|
||||
booleanProperty("reportPrivate")
|
||||
.desc("Report private classes and methods").defaultValue(false).build();
|
||||
|
||||
private static final PropertyDescriptor<Boolean> 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;
|
||||
}
|
||||
|
@ -18,13 +18,15 @@ Rules that are related to code documentation.
|
||||
<description>
|
||||
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.
|
||||
</description>
|
||||
|
@ -48,6 +48,15 @@ private class Foo { }
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>private class should have comment if specified</description>
|
||||
<rule-property name="reportPrivate">true</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
private class Foo { }
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>class comment should have description</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
@ -109,6 +118,15 @@ private interface Foo { }
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>private interface should have comment if specified</description>
|
||||
<rule-property name="reportPrivate">true</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
private interface Foo { }
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>interface comment should have description</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
@ -168,6 +186,62 @@ public class Foo {
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>private method does not need comment</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* @description Foo
|
||||
*/
|
||||
public class Foo {
|
||||
private void bar() { }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
|
||||
<test-code>
|
||||
<description>private method should have comment if specified</description>
|
||||
<rule-property name="reportPrivate">true</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* @description Foo
|
||||
*/
|
||||
public class Foo {
|
||||
private void bar() { }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>protected method does not need comment</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* @description Foo
|
||||
*/
|
||||
public class Foo {
|
||||
protected void bar() { }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
|
||||
<test-code>
|
||||
<description>protected method should have comment if specified</description>
|
||||
<rule-property name="reportProtected">true</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* @description Foo
|
||||
*/
|
||||
public class Foo {
|
||||
protected void bar() { }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>public override method does not need comment</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
@ -355,6 +429,60 @@ public class Foo {
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>private property does not need a comment</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* @description Foo
|
||||
*/
|
||||
public class Foo {
|
||||
private Object Bar { get; set; }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>private property should have a comment if specified</description>
|
||||
<rule-property name="reportPrivate">true</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* @description Foo
|
||||
*/
|
||||
public class Foo {
|
||||
private Object Bar { get; set; }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>protected property does not need a comment</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* @description Foo
|
||||
*/
|
||||
public class Foo {
|
||||
protected Object Bar { get; set; }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>protected property should have a comment if specified</description>
|
||||
<rule-property name="reportProtected">true</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* @description Foo
|
||||
*/
|
||||
public class Foo {
|
||||
protected Object Bar { get; set; }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>property comment should have description</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
|
@ -2660,7 +2660,7 @@ ASTFetchStatement FetchStatement() :
|
||||
ASTEmbeddedSqlStatement EmbeddedSqlStatement() :
|
||||
{}
|
||||
{
|
||||
<EXECUTE> <IMMEDIATE> (StringLiteral() | Expression())
|
||||
<EXECUTE> <IMMEDIATE> StringExpression()
|
||||
[ <INTO> Name() ("," Name())* ]
|
||||
[ <USING> [ <IN> [ <OUT> ] | <OUT> ] Expression() ("," [ <IN> [ <OUT> ] | <OUT> ] Expression())* ]
|
||||
[ ( <RETURN> | <RETURNING> ) <INTO> Expression() ("," Expression())*] ";"
|
||||
|
@ -73,4 +73,9 @@ public class PLSQLParserTest extends AbstractPLSQLParserTst {
|
||||
public void testCaseIssue1454() {
|
||||
plsql.parseResource("CaseIssue1454.pls");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteImmediateIssue3106() {
|
||||
plsql.parseResource("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;
|
Reference in New Issue
Block a user