forked from phoedos/pmd
Merge branch 'master' of github.com:pmd/pmd into lua-types
This commit is contained in:
commit
c59ee1d55d
@ -1053,7 +1053,8 @@
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/86377278?v=4",
|
||||
"profile": "https://github.com/aaronhurst-google",
|
||||
"contributions": [
|
||||
"bug"
|
||||
"bug",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -5917,7 +5918,8 @@
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/35368290?v=4",
|
||||
"profile": "https://github.com/tprouvot",
|
||||
"contributions": [
|
||||
"bug"
|
||||
"bug",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -6768,6 +6770,42 @@
|
||||
"code",
|
||||
"financial"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "abyss638",
|
||||
"name": "Simon Abykov",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/90252673?v=4",
|
||||
"profile": "https://github.com/abyss638",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "eklimo",
|
||||
"name": "Edward Klimoshenko",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/39220927?v=4",
|
||||
"profile": "https://github.com/eklimo",
|
||||
"contributions": [
|
||||
"bug",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "nvuillam",
|
||||
"name": "Nicolas Vuillamy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/17500430?v=4",
|
||||
"profile": "https://github.com/nvuillam",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},{
|
||||
"login": "pacvz",
|
||||
"name": "pacvz",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/35453365?v=4",
|
||||
"profile": "https://github.com/pacvz",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
@ -27,6 +27,15 @@ function build() {
|
||||
pmd_ci_utils_determine_build_env pmd/pmd
|
||||
echo
|
||||
|
||||
if ! pmd_ci_utils_is_fork_or_pull_request; then
|
||||
if [ "${PMD_CI_BRANCH}" = "experimental-apex-parser" ]; then
|
||||
pmd_ci_log_group_start "Build with mvnw"
|
||||
./mvnw clean install --show-version --errors --batch-mode --no-transfer-progress "${PMD_MAVEN_EXTRA_OPTS[@]}"
|
||||
pmd_ci_log_group_end
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if pmd_ci_utils_is_fork_or_pull_request; then
|
||||
pmd_ci_log_group_start "Build with mvnw"
|
||||
./mvnw clean install --show-version --errors --batch-mode --no-transfer-progress "${PMD_MAVEN_EXTRA_OPTS[@]}"
|
||||
|
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
@ -5,6 +5,7 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- experimental-apex-parser
|
||||
tags:
|
||||
- '**'
|
||||
pull_request:
|
||||
|
@ -1,9 +1,9 @@
|
||||
repository: pmd/pmd
|
||||
|
||||
pmd:
|
||||
version: 6.49.0-SNAPSHOT
|
||||
previous_version: 6.48.0
|
||||
date: 31-August-2022
|
||||
version: 6.50.0-SNAPSHOT
|
||||
previous_version: 6.49.0
|
||||
date: 30-September-2022
|
||||
release_type: minor
|
||||
|
||||
# release types: major, minor, bugfix
|
||||
|
@ -125,6 +125,23 @@ the breaking API changes will be performed in 7.0.0.
|
||||
an API is tagged as `@Deprecated` or not in the latest minor release. During the development of 7.0.0,
|
||||
we may decide to remove some APIs that were not tagged as deprecated, though we'll try to avoid it." %}
|
||||
|
||||
#### 6.49.0
|
||||
|
||||
##### Deprecated API
|
||||
|
||||
* In order to reduce the dependency on Apex Jorje classes, the following methods have been deprecated.
|
||||
These methods all leaked internal Jorje enums. These enums have been replaced now by enums the
|
||||
PMD's AST package.
|
||||
* {% jdoc !!apex::lang.apex.ast.ASTAssignmentExpression#getOperator() %}
|
||||
* {% jdoc !!apex::lang.apex.ast.ASTBinaryExpression#getOperator() %}
|
||||
* {% jdoc !!apex::lang.apex.ast.ASTBooleanExpression#getOperator() %}
|
||||
* {% jdoc !!apex::lang.apex.ast.ASTPostfixExpression#getOperator() %}
|
||||
* {% jdoc !!apex::lang.apex.ast.ASTPrefixExpression#getOperator() %}
|
||||
|
||||
All these classes have now a new `getOp()` method. Existing code should be refactored to use this method instead.
|
||||
It returns the new enums, like {% jdoc apex::lang.apex.ast.AssignmentOperator %}, and avoids
|
||||
the dependency to Jorje.
|
||||
|
||||
#### 6.48.0
|
||||
|
||||
##### CPD CLI
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -104,9 +104,9 @@ Example:
|
||||
<file path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java" totalNumberOfTokens="523"/>
|
||||
<file path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java" totalNumberOfTokens="120"/>
|
||||
<duplication lines="33" tokens="239">
|
||||
<file column="29" endcolumn="75" endline="64" line="32"
|
||||
<file column="29" endcolumn="75" endline="64" line="32" begintoken="2356" endtoken="2594"
|
||||
path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java"/>
|
||||
<file column="37" endcolumn="75" endline="100" line="68"
|
||||
<file column="37" endcolumn="75" endline="100" line="68" begintoken="5700" endtoken="5938"
|
||||
path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java"/>
|
||||
<codefragment><![CDATA[ public void testOverride() {
|
||||
final StringProperty PROPERTY1_DESCRIPTOR = new StringProperty("property1", "Test property", null, 0f);
|
||||
@ -143,11 +143,11 @@ Example:
|
||||
validateOverriddenValues(PROPERTY1_DESCRIPTOR, PROPERTY2_DESCRIPTOR, ruleReference);]]></codefragment>
|
||||
</duplication>
|
||||
<duplication lines="16" tokens="110">
|
||||
<file column="9" endcolumn="28" endline="81" line="66"
|
||||
<file column="9" endcolumn="28" endline="81" line="66" begintoken="3000" endtoken="3109"
|
||||
path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java"/>
|
||||
<file column="9" endcolumn="28" endline="103" line="88"
|
||||
<file column="9" endcolumn="28" endline="103" line="88" begintoken="3200" endtoken="3309"
|
||||
path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java"/>
|
||||
<file column="9" endcolumn="28" endline="125" line="110"
|
||||
<file column="9" endcolumn="28" endline="125" line="110" begintoken="3400" endtoken="3509"
|
||||
path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java"/>
|
||||
<codefragment><![CDATA[ JaxenXPathRuleQuery query = createQuery(xpath);
|
||||
List<String> ruleChainVisits = query.getRuleChainVisits();
|
||||
|
@ -28,4 +28,10 @@ result of the PMD maven plugin.
|
||||
|
||||
See [Other Tools / Integrations](pmd_userdocs_tools.html#github-actions)
|
||||
|
||||
## MegaLinter
|
||||
|
||||
[🦙 Mega-Linter](https://oxsecurity.github.io/megalinter/latest/) analyzes 50 languages, 22 formats, 21 tooling formats, excessive copy-pastes, spelling mistakes and security issues in your repository sources with a GitHub Action, other CI tools or locally.
|
||||
|
||||
It [natively embeds PMD](https://oxsecurity.github.io/megalinter/latest/descriptors/java_pmd/).
|
||||
|
||||
<!-- TODO: Find out about other plugins ? -->
|
||||
|
@ -5,6 +5,69 @@ permalink: pmd_release_notes_old.html
|
||||
|
||||
Previous versions of PMD can be downloaded here: https://github.com/pmd/pmd/releases
|
||||
|
||||
## 31-August-2022 - 6.49.0
|
||||
|
||||
The PMD team is pleased to announce PMD 6.49.0.
|
||||
|
||||
This is a minor release.
|
||||
|
||||
### Table Of Contents
|
||||
|
||||
* [New and noteworthy](#new-and-noteworthy)
|
||||
* [Updated PMD Designer](#updated-pmd-designer)
|
||||
* [Fixed Issues](#fixed-issues)
|
||||
* [API Changes](#api-changes)
|
||||
* [Deprecated API](#deprecated-api)
|
||||
* [External Contributions](#external-contributions)
|
||||
* [Stats](#stats)
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
#### Updated PMD Designer
|
||||
|
||||
This PMD release ships a new version of the pmd-designer.
|
||||
For the changes, see [PMD Designer Changelog](https://github.com/pmd/pmd-designer/releases/tag/6.49.0).
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
* apex
|
||||
* [#4096](https://github.com/pmd/pmd/issues/4096): \[apex] ApexAssertionsShouldIncludeMessage and ApexUnitTestClassShouldHaveAsserts: support new Assert class (introduced with Apex v56.0)
|
||||
* core
|
||||
* [#3970](https://github.com/pmd/pmd/issues/3970): \[core] FileCollector.addFile ignores language parameter
|
||||
* java-codestyle
|
||||
* [#4082](https://github.com/pmd/pmd/issues/4082): \[java] UnnecessaryImport false positive for on-demand imports of nested classes
|
||||
|
||||
### API Changes
|
||||
|
||||
#### Deprecated API
|
||||
|
||||
* In order to reduce the dependency on Apex Jorje classes, the following methods have been deprecated.
|
||||
These methods all leaked internal Jorje enums. These enums have been replaced now by enums the
|
||||
PMD's AST package.
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.49.0/net/sourceforge/pmd/lang/apex/ast/ASTAssignmentExpression.html#getOperator()"><code>ASTAssignmentExpression#getOperator</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.49.0/net/sourceforge/pmd/lang/apex/ast/ASTBinaryExpression.html#getOperator()"><code>ASTBinaryExpression#getOperator</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.49.0/net/sourceforge/pmd/lang/apex/ast/ASTBooleanExpression.html#getOperator()"><code>ASTBooleanExpression#getOperator</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.49.0/net/sourceforge/pmd/lang/apex/ast/ASTPostfixExpression.html#getOperator()"><code>ASTPostfixExpression#getOperator</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.49.0/net/sourceforge/pmd/lang/apex/ast/ASTPrefixExpression.html#getOperator()"><code>ASTPrefixExpression#getOperator</code></a>
|
||||
|
||||
All these classes have now a new `getOp()` method. Existing code should be refactored to use this method instead.
|
||||
It returns the new enums, like <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.49.0/net/sourceforge/pmd/lang/apex/ast/AssignmentOperator.html#"><code>AssignmentOperator</code></a>, and avoids
|
||||
the dependency to Jorje.
|
||||
|
||||
### External Contributions
|
||||
|
||||
* [#4081](https://github.com/pmd/pmd/pull/4081): \[apex] Remove Jorje leaks outside `ast` package - [@eklimo](https://github.com/eklimo)
|
||||
* [#4083](https://github.com/pmd/pmd/pull/4083): \[java] UnnecessaryImport false positive for on-demand imports of nested classes (fix for #4082) - [@abyss638](https://github.com/abyss638)
|
||||
* [#4092](https://github.com/pmd/pmd/pull/4092): \[apex] Implement ApexQualifiableNode for ASTUserEnum - [@aaronhurst-google](https://github.com/aaronhurst-google)
|
||||
* [#4095](https://github.com/pmd/pmd/pull/4095): \[core] CPD: Added begin and end token to XML reports - [@pacvz](https://github.com/pacvz)
|
||||
* [#4097](https://github.com/pmd/pmd/pull/4097): \[apex] ApexUnitTestClassShouldHaveAssertsRule: Support new Assert class (Apex v56.0) - [@tprouvot](https://github.com/tprouvot)
|
||||
* [#4104](https://github.com/pmd/pmd/pull/4104): \[doc] Add MegaLinter in the list of integrations - [@nvuillam](https://github.com/nvuillam)
|
||||
|
||||
### Stats
|
||||
* 49 commits
|
||||
* 10 closed tickets & PRs
|
||||
* Days since last release: 32
|
||||
|
||||
## 30-July-2022 - 6.48.0
|
||||
|
||||
The PMD team is pleased to announce PMD 6.48.0.
|
||||
|
@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.49.0-SNAPSHOT</version>
|
||||
<version>6.50.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.49.0-SNAPSHOT</version>
|
||||
<version>6.50.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -22,7 +22,15 @@ public class ASTAssignmentExpression extends AbstractApexNode<AssignmentExpressi
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getOp()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public AssignmentOp getOperator() {
|
||||
return node.getOp();
|
||||
}
|
||||
|
||||
public AssignmentOperator getOp() {
|
||||
return AssignmentOperator.valueOf(node.getOp());
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,15 @@ public class ASTBinaryExpression extends AbstractApexNode<BinaryExpression> {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getOp()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public BinaryOp getOperator() {
|
||||
return node.getOp();
|
||||
}
|
||||
|
||||
public BinaryOperator getOp() {
|
||||
return BinaryOperator.valueOf(node.getOp());
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,15 @@ public class ASTBooleanExpression extends AbstractApexNode<BooleanExpression> {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getOp()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public BooleanOp getOperator() {
|
||||
return this.node.getOp();
|
||||
}
|
||||
|
||||
public BooleanOperator getOp() {
|
||||
return BooleanOperator.valueOf(this.node.getOp());
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,15 @@ public class ASTPostfixExpression extends AbstractApexNode<PostfixExpression> {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getOp()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public PostfixOp getOperator() {
|
||||
return node.getOp();
|
||||
}
|
||||
|
||||
public PostfixOperator getOp() {
|
||||
return PostfixOperator.valueOf(node.getOp());
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,15 @@ public class ASTPrefixExpression extends AbstractApexNode<PrefixExpression> {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getOp()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public PrefixOp getOperator() {
|
||||
return node.getOp();
|
||||
}
|
||||
|
||||
public PrefixOperator getOp() {
|
||||
return PrefixOperator.valueOf(node.getOp());
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,9 @@ import net.sourceforge.pmd.annotation.InternalApi;
|
||||
|
||||
import apex.jorje.semantic.ast.compilation.UserEnum;
|
||||
|
||||
public class ASTUserEnum extends ApexRootNode<UserEnum> {
|
||||
public class ASTUserEnum extends ApexRootNode<UserEnum> implements ApexQualifiableNode {
|
||||
|
||||
private ApexQualifiedName qname;
|
||||
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
@ -30,4 +32,20 @@ public class ASTUserEnum extends ApexRootNode<UserEnum> {
|
||||
public ASTModifierNode getModifiers() {
|
||||
return getFirstChildOfType(ASTModifierNode.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApexQualifiedName getQualifiedName() {
|
||||
if (qname == null) {
|
||||
|
||||
ASTUserClass parent = this.getFirstParentOfType(ASTUserClass.class);
|
||||
|
||||
if (parent != null) {
|
||||
qname = ApexQualifiedName.ofNestedEnum(parent.getQualifiedName(), this);
|
||||
} else {
|
||||
qname = ApexQualifiedName.ofOuterEnum(this);
|
||||
}
|
||||
}
|
||||
|
||||
return qname;
|
||||
}
|
||||
}
|
||||
|
@ -148,6 +148,20 @@ public final class ApexQualifiedName implements QualifiedName {
|
||||
}
|
||||
|
||||
|
||||
static ApexQualifiedName ofOuterEnum(ASTUserEnum astUserEnum) {
|
||||
String ns = astUserEnum.getNamespace();
|
||||
String[] classes = {astUserEnum.getImage()};
|
||||
return new ApexQualifiedName(StringUtils.isEmpty(ns) ? "c" : ns, classes, null);
|
||||
}
|
||||
|
||||
|
||||
static ApexQualifiedName ofNestedEnum(ApexQualifiedName parent, ASTUserEnum astUserEnum) {
|
||||
String[] classes = Arrays.copyOf(parent.classes, parent.classes.length + 1);
|
||||
classes[classes.length - 1] = astUserEnum.getImage();
|
||||
return new ApexQualifiedName(parent.nameSpace, classes, null);
|
||||
}
|
||||
|
||||
|
||||
private static String getOperationString(ASTMethod node) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(node.getImage()).append('(');
|
||||
@ -171,18 +185,28 @@ public final class ApexQualifiedName implements QualifiedName {
|
||||
|
||||
|
||||
static ApexQualifiedName ofMethod(ASTMethod node) {
|
||||
ASTUserClassOrInterface<?> parent = node.getFirstParentOfType(ASTUserClassOrInterface.class);
|
||||
if (parent == null) {
|
||||
ASTUserTrigger trigger = node.getFirstParentOfType(ASTUserTrigger.class);
|
||||
String ns = trigger.getNamespace();
|
||||
String targetObj = trigger.getTargetName();
|
||||
|
||||
return new ApexQualifiedName(StringUtils.isEmpty(ns) ? "c" : ns, new String[]{"trigger", targetObj}, trigger.getImage()); // uses a reserved word as a class name to prevent clashes
|
||||
|
||||
} else {
|
||||
ApexQualifiedName baseName = parent.getQualifiedName();
|
||||
// Check first, as enum must be innermost potential parent
|
||||
ASTUserEnum enumParent = node.getFirstParentOfType(ASTUserEnum.class);
|
||||
if (enumParent != null) {
|
||||
ApexQualifiedName baseName = enumParent.getQualifiedName();
|
||||
|
||||
return new ApexQualifiedName(baseName.nameSpace, baseName.classes, getOperationString(node));
|
||||
}
|
||||
|
||||
ASTUserClassOrInterface<?> classParent = node.getFirstParentOfType(ASTUserClassOrInterface.class);
|
||||
if (classParent != null) {
|
||||
ApexQualifiedName baseName = classParent.getQualifiedName();
|
||||
|
||||
return new ApexQualifiedName(baseName.nameSpace, baseName.classes, getOperationString(node));
|
||||
}
|
||||
|
||||
ASTUserTrigger triggerParent = node.getFirstParentOfType(ASTUserTrigger.class);
|
||||
if (triggerParent != null) {
|
||||
String ns = triggerParent.getNamespace();
|
||||
String targetObj = triggerParent.getTargetName();
|
||||
|
||||
return new ApexQualifiedName(StringUtils.isEmpty(ns) ? "c" : ns, new String[]{"trigger", targetObj}, triggerParent.getImage()); // uses a reserved word as a class name to prevent clashes
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,12 @@ import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.lang.ast.RootNode;
|
||||
import net.sourceforge.pmd.lang.ast.SourceCodePositioner;
|
||||
|
||||
import apex.jorje.semantic.ast.AstNode;
|
||||
import apex.jorje.semantic.ast.compilation.Compilation;
|
||||
import apex.jorje.services.Version;
|
||||
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
public abstract class ApexRootNode<T extends AstNode> extends AbstractApexNode<T> implements RootNode {
|
||||
public abstract class ApexRootNode<T extends Compilation> extends AbstractApexNode<T> implements RootNode {
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
public ApexRootNode(T node) {
|
||||
|
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import apex.jorje.data.ast.AssignmentOp;
|
||||
|
||||
/**
|
||||
* Apex assignment operator
|
||||
*/
|
||||
public enum AssignmentOperator {
|
||||
EQUALS("="),
|
||||
ADDITION_EQUALS("+="),
|
||||
SUBTRACTION_EQUALS("-="),
|
||||
MULTIPLICATION_EQUALS("*="),
|
||||
DIVISION_EQUALS("/="),
|
||||
LEFT_SHIFT_EQUALS("<<="),
|
||||
RIGHT_SHIFT_SIGNED_EQUALS(">>="),
|
||||
RIGHT_SHIFT_UNSIGNED_EQUALS(">>>="),
|
||||
BITWISE_AND_EQUALS("&="),
|
||||
BITWISE_OR_EQUALS("|="),
|
||||
BITWISE_XOR_EQUALS("^=");
|
||||
|
||||
private final String symbol;
|
||||
|
||||
AssignmentOperator(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link AssignmentOperator} corresponding to the given {@link AssignmentOp}.
|
||||
*/
|
||||
public static AssignmentOperator valueOf(AssignmentOp op) {
|
||||
switch (op) {
|
||||
case EQUALS:
|
||||
return EQUALS;
|
||||
case ADDITION_EQUALS:
|
||||
return ADDITION_EQUALS;
|
||||
case SUBTRACTION_EQUALS:
|
||||
return SUBTRACTION_EQUALS;
|
||||
case MULTIPLICATION_EQUALS:
|
||||
return MULTIPLICATION_EQUALS;
|
||||
case DIVISION_EQUALS:
|
||||
return DIVISION_EQUALS;
|
||||
case LEFT_SHIFT_EQUALS:
|
||||
return LEFT_SHIFT_EQUALS;
|
||||
case RIGHT_SHIFT_EQUALS:
|
||||
return RIGHT_SHIFT_SIGNED_EQUALS;
|
||||
case UNSIGNED_RIGHT_SHIFT_EQUALS:
|
||||
return RIGHT_SHIFT_UNSIGNED_EQUALS;
|
||||
case AND_EQUALS:
|
||||
return BITWISE_AND_EQUALS;
|
||||
case OR_EQUALS:
|
||||
return BITWISE_OR_EQUALS;
|
||||
case XOR_EQUALS:
|
||||
return BITWISE_XOR_EQUALS;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid assignment operator " + op);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import apex.jorje.data.ast.BinaryOp;
|
||||
|
||||
/**
|
||||
* Apex binary operator
|
||||
*/
|
||||
public enum BinaryOperator {
|
||||
ADDITION("+"),
|
||||
SUBTRACTION("-"),
|
||||
MULTIPLICATION("*"),
|
||||
DIVISION("/"),
|
||||
LEFT_SHIFT("<<"),
|
||||
RIGHT_SHIFT_SIGNED(">>"),
|
||||
RIGHT_SHIFT_UNSIGNED(">>>"),
|
||||
BITWISE_AND("&"),
|
||||
BITWISE_OR("|"),
|
||||
BITWISE_XOR("^");
|
||||
|
||||
private final String symbol;
|
||||
|
||||
BinaryOperator(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link BinaryOperator} corresponding to the given {@link BinaryOp}.
|
||||
*/
|
||||
public static BinaryOperator valueOf(BinaryOp op) {
|
||||
switch (op) {
|
||||
case ADDITION:
|
||||
return ADDITION;
|
||||
case SUBTRACTION:
|
||||
return SUBTRACTION;
|
||||
case MULTIPLICATION:
|
||||
return MULTIPLICATION;
|
||||
case DIVISION:
|
||||
return DIVISION;
|
||||
case LEFT_SHIFT:
|
||||
return LEFT_SHIFT;
|
||||
case RIGHT_SHIFT:
|
||||
return RIGHT_SHIFT_SIGNED;
|
||||
case UNSIGNED_RIGHT_SHIFT:
|
||||
return RIGHT_SHIFT_UNSIGNED;
|
||||
case AND:
|
||||
return BITWISE_AND;
|
||||
case OR:
|
||||
return BITWISE_OR;
|
||||
case XOR:
|
||||
return BITWISE_XOR;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid binary operator " + op);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import apex.jorje.data.ast.BooleanOp;
|
||||
|
||||
/**
|
||||
* Apex boolean operator
|
||||
*/
|
||||
public enum BooleanOperator {
|
||||
EQUAL("=="),
|
||||
NOT_EQUAL("!="),
|
||||
ALT_NOT_EQUAL("<>"),
|
||||
EXACTLY_EQUAL("==="),
|
||||
EXACTLY_NOT_EQUAL("!=="),
|
||||
LESS_THAN("<"),
|
||||
GREATER_THAN(">"),
|
||||
LESS_THAN_OR_EQUAL("<="),
|
||||
GREATER_THAN_OR_EQUAL(">="),
|
||||
LOGICAL_AND("&&"),
|
||||
LOGICAL_OR("||");
|
||||
|
||||
private final String symbol;
|
||||
|
||||
BooleanOperator(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link BooleanOperator} corresponding to the given {@link BooleanOp}.
|
||||
*/
|
||||
public static BooleanOperator valueOf(BooleanOp op) {
|
||||
switch (op) {
|
||||
case DOUBLE_EQUAL:
|
||||
return EQUAL;
|
||||
case NOT_EQUAL:
|
||||
return NOT_EQUAL;
|
||||
case ALT_NOT_EQUAL:
|
||||
return ALT_NOT_EQUAL;
|
||||
case TRIPLE_EQUAL:
|
||||
return EXACTLY_EQUAL;
|
||||
case NOT_TRIPLE_EQUAL:
|
||||
return EXACTLY_NOT_EQUAL;
|
||||
case LESS_THAN:
|
||||
return LESS_THAN;
|
||||
case GREATER_THAN:
|
||||
return GREATER_THAN;
|
||||
case LESS_THAN_EQUAL:
|
||||
return LESS_THAN_OR_EQUAL;
|
||||
case GREATER_THAN_EQUAL:
|
||||
return GREATER_THAN_OR_EQUAL;
|
||||
case AND:
|
||||
return LOGICAL_AND;
|
||||
case OR:
|
||||
return LOGICAL_OR;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid boolean operator " + op);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import apex.jorje.data.ast.PostfixOp;
|
||||
|
||||
/**
|
||||
* Apex postfix operator
|
||||
*/
|
||||
public enum PostfixOperator {
|
||||
INCREMENT("++"),
|
||||
DECREMENT("--");
|
||||
|
||||
private final String symbol;
|
||||
|
||||
PostfixOperator(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link PostfixOperator} corresponding to the given {@link PostfixOp}.
|
||||
*/
|
||||
public static PostfixOperator valueOf(PostfixOp op) {
|
||||
switch (op) {
|
||||
case INC:
|
||||
return INCREMENT;
|
||||
case DEC:
|
||||
return DECREMENT;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid postfix operator " + op);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import apex.jorje.data.ast.PrefixOp;
|
||||
|
||||
/**
|
||||
* Apex prefix operator
|
||||
*/
|
||||
public enum PrefixOperator {
|
||||
POSITIVE("+"),
|
||||
NEGATIVE("-"),
|
||||
LOGICAL_NOT("!"),
|
||||
BITWISE_NOT("~"),
|
||||
INCREMENT("++"),
|
||||
DECREMENT("--");
|
||||
|
||||
private final String symbol;
|
||||
|
||||
PrefixOperator(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link PrefixOperator} corresponding to the given {@link PrefixOp}.
|
||||
*/
|
||||
public static PrefixOperator valueOf(PrefixOp op) {
|
||||
switch (op) {
|
||||
case POSITIVE:
|
||||
return POSITIVE;
|
||||
case NEGATIVE:
|
||||
return NEGATIVE;
|
||||
case NOT:
|
||||
return LOGICAL_NOT;
|
||||
case BITWISE_COMPLEMENT:
|
||||
return BITWISE_NOT;
|
||||
case INC:
|
||||
return INCREMENT;
|
||||
case DEC:
|
||||
return DECREMENT;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid prefix operator " + op);
|
||||
}
|
||||
}
|
||||
}
|
@ -12,11 +12,10 @@ import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTBooleanExpression;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTStandardCondition;
|
||||
import net.sourceforge.pmd.lang.apex.ast.BooleanOperator;
|
||||
import net.sourceforge.pmd.lang.apex.metrics.impl.visitors.StandardCycloVisitor;
|
||||
import net.sourceforge.pmd.lang.metrics.MetricOptions;
|
||||
|
||||
import apex.jorje.data.ast.BooleanOp;
|
||||
|
||||
/**
|
||||
* See the doc for the Java metric.
|
||||
*
|
||||
@ -44,8 +43,8 @@ public class CycloMetric extends AbstractApexOperationMetric {
|
||||
int complexity = 0;
|
||||
|
||||
for (ASTBooleanExpression sub : subs) {
|
||||
BooleanOp op = sub.getOperator();
|
||||
if (op != null && (op == BooleanOp.AND || op == BooleanOp.OR)) {
|
||||
BooleanOperator op = sub.getOp();
|
||||
if (op == BooleanOperator.LOGICAL_AND || op == BooleanOperator.LOGICAL_OR) {
|
||||
complexity++;
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,8 @@ import net.sourceforge.pmd.lang.apex.ast.ASTTernaryExpression;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTWhileLoopStatement;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitorAdapter;
|
||||
|
||||
import apex.jorje.data.ast.BooleanOp;
|
||||
import apex.jorje.data.ast.PrefixOp;
|
||||
import net.sourceforge.pmd.lang.apex.ast.BooleanOperator;
|
||||
import net.sourceforge.pmd.lang.apex.ast.PrefixOperator;
|
||||
|
||||
/**
|
||||
* @author Gwilym Kuiper
|
||||
@ -31,7 +30,7 @@ public class CognitiveComplexityVisitor extends ApexParserVisitorAdapter {
|
||||
private int complexity = 0;
|
||||
private int nestingLevel = 0;
|
||||
|
||||
private BooleanOp currentBooleanOperation = null;
|
||||
private BooleanOperator currentBooleanOperation = null;
|
||||
private String methodName = null;
|
||||
|
||||
public double getComplexity() {
|
||||
@ -53,7 +52,7 @@ public class CognitiveComplexityVisitor extends ApexParserVisitorAdapter {
|
||||
complexity++;
|
||||
}
|
||||
|
||||
void booleanOperation(BooleanOp op) {
|
||||
void booleanOperation(BooleanOperator op) {
|
||||
if (currentBooleanOperation != op) {
|
||||
if (op != null) {
|
||||
fundamentalComplexity();
|
||||
@ -177,8 +176,8 @@ public class CognitiveComplexityVisitor extends ApexParserVisitorAdapter {
|
||||
public Object visit(ASTBooleanExpression node, Object data) {
|
||||
State state = (State) data;
|
||||
|
||||
BooleanOp op = node.getOperator();
|
||||
if (op == BooleanOp.AND || op == BooleanOp.OR) {
|
||||
BooleanOperator op = node.getOp();
|
||||
if (op == BooleanOperator.LOGICAL_AND || op == BooleanOperator.LOGICAL_OR) {
|
||||
state.booleanOperation(op);
|
||||
}
|
||||
|
||||
@ -189,8 +188,8 @@ public class CognitiveComplexityVisitor extends ApexParserVisitorAdapter {
|
||||
public Object visit(ASTPrefixExpression node, Object data) {
|
||||
State state = (State) data;
|
||||
|
||||
PrefixOp op = node.getOperator();
|
||||
if (op == PrefixOp.NOT) {
|
||||
PrefixOperator op = node.getOp();
|
||||
if (op == PrefixOperator.LOGICAL_NOT) {
|
||||
state.booleanOperation(null);
|
||||
}
|
||||
|
||||
|
@ -12,17 +12,39 @@ public class ApexAssertionsShouldIncludeMessageRule extends AbstractApexUnitTest
|
||||
private static final String ASSERT = "System.assert";
|
||||
private static final String ASSERT_EQUALS = "System.assertEquals";
|
||||
private static final String ASSERT_NOT_EQUALS = "System.assertNotEquals";
|
||||
private static final String ARE_EQUAL = "Assert.areEqual";
|
||||
private static final String ARE_NOT_EQUAL = "Assert.areNotEqual";
|
||||
private static final String IS_FALSE = "Assert.isFalse";
|
||||
private static final String FAIL = "Assert.fail";
|
||||
private static final String IS_INSTANCE_OF_TYPE = "Assert.isInstanceOfType";
|
||||
private static final String IS_NOT_INSTANCE_OF_TYPE = "Assert.isNotInstanceOfType";
|
||||
private static final String IS_NOT_NULL = "Assert.isNotNull";
|
||||
private static final String IS_NULL = "Assert.isNull";
|
||||
private static final String IS_TRUE = "Assert.isTrue";
|
||||
|
||||
@Override
|
||||
public Object visit(ASTMethodCallExpression node, Object data) {
|
||||
String methodName = node.getFullMethodName();
|
||||
|
||||
if (ASSERT.equalsIgnoreCase(methodName) && node.getNumChildren() == 2) {
|
||||
if (FAIL.equalsIgnoreCase(methodName) && node.getNumChildren() == 1) {
|
||||
addViolationWithMessage(data, node,
|
||||
"''{0}'' should have 1 parameters.",
|
||||
new Object[] { FAIL });
|
||||
} else if ((ASSERT.equalsIgnoreCase(methodName)
|
||||
|| IS_FALSE.equalsIgnoreCase(methodName)
|
||||
|| IS_NOT_NULL.equalsIgnoreCase(methodName)
|
||||
|| IS_NULL.equalsIgnoreCase(methodName)
|
||||
|| IS_TRUE.equalsIgnoreCase(methodName))
|
||||
&& node.getNumChildren() == 2) {
|
||||
addViolationWithMessage(data, node,
|
||||
"''{0}'' should have 2 parameters.",
|
||||
new Object[] { ASSERT });
|
||||
new Object[] { methodName });
|
||||
} else if ((ASSERT_EQUALS.equalsIgnoreCase(methodName)
|
||||
|| ASSERT_NOT_EQUALS.equalsIgnoreCase(methodName))
|
||||
|| ASSERT_NOT_EQUALS.equalsIgnoreCase(methodName)
|
||||
|| ARE_EQUAL.equalsIgnoreCase(methodName)
|
||||
|| ARE_NOT_EQUAL.equalsIgnoreCase(methodName)
|
||||
|| IS_INSTANCE_OF_TYPE.equalsIgnoreCase(methodName)
|
||||
|| IS_NOT_INSTANCE_OF_TYPE.equalsIgnoreCase(methodName))
|
||||
&& node.getNumChildren() == 3) {
|
||||
addViolationWithMessage(data, node,
|
||||
"''{0}'' should have 3 parameters.",
|
||||
|
@ -37,18 +37,39 @@ public class ApexUnitTestClassShouldHaveAssertsRule extends AbstractApexUnitTest
|
||||
ASSERT_METHODS.add("system.assert");
|
||||
ASSERT_METHODS.add("system.assertequals");
|
||||
ASSERT_METHODS.add("system.assertnotequals");
|
||||
ASSERT_METHODS.add("assert.areequal");
|
||||
ASSERT_METHODS.add("assert.arenotequal");
|
||||
ASSERT_METHODS.add("assert.fail");
|
||||
ASSERT_METHODS.add("assert.isfalse");
|
||||
ASSERT_METHODS.add("assert.isinstanceoftype");
|
||||
ASSERT_METHODS.add("assert.isnotinstanceoftype");
|
||||
ASSERT_METHODS.add("assert.isnull");
|
||||
ASSERT_METHODS.add("assert.isnotnull");
|
||||
ASSERT_METHODS.add("assert.istrue");
|
||||
// Fully-qualified variants...rare but still valid/possible
|
||||
ASSERT_METHODS.add("system.system.assert");
|
||||
ASSERT_METHODS.add("system.system.assertequals");
|
||||
ASSERT_METHODS.add("system.system.assertnotequals");
|
||||
ASSERT_METHODS.add("system.assert.areequal");
|
||||
ASSERT_METHODS.add("system.assert.arenotequal");
|
||||
ASSERT_METHODS.add("system.assert.fail");
|
||||
ASSERT_METHODS.add("system.assert.isfalse");
|
||||
ASSERT_METHODS.add("system.assert.isinstanceoftype");
|
||||
ASSERT_METHODS.add("system.assert.isnotinstanceoftype");
|
||||
ASSERT_METHODS.add("system.assert.isnull");
|
||||
ASSERT_METHODS.add("system.assert.isnotnull");
|
||||
ASSERT_METHODS.add("system.assert.istrue");
|
||||
}
|
||||
|
||||
// Using a string property instead of a regex property to ensure that the compiled pattern can be case-insensitive
|
||||
private static final PropertyDescriptor<String> ADDITIONAL_ASSERT_METHOD_PATTERN_DESCRIPTOR =
|
||||
stringProperty("additionalAssertMethodPattern")
|
||||
.desc("A regular expression for one or more custom test assertion method patterns.").defaultValue("").build();
|
||||
// Using a string property instead of a regex property to ensure that the
|
||||
// compiled pattern can be case-insensitive
|
||||
private static final PropertyDescriptor<String> ADDITIONAL_ASSERT_METHOD_PATTERN_DESCRIPTOR = stringProperty(
|
||||
"additionalAssertMethodPattern")
|
||||
.desc("A regular expression for one or more custom test assertion method patterns.").defaultValue("")
|
||||
.build();
|
||||
|
||||
// A simple compiled pattern cache to ensure that we only ever try to compile the configured pattern once for a given run
|
||||
// A simple compiled pattern cache to ensure that we only ever try to compile
|
||||
// the configured pattern once for a given run
|
||||
private Optional<Pattern> compiledAdditionalAssertMethodPattern = null;
|
||||
|
||||
public ApexUnitTestClassShouldHaveAssertsRule() {
|
||||
@ -81,7 +102,8 @@ public class ApexUnitTestClassShouldHaveAssertsRule extends AbstractApexUnitTest
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find assert method invocations the simple way and we have a configured pattern, try it
|
||||
// If we didn't find assert method invocations the simple way and we have a
|
||||
// configured pattern, try it
|
||||
if (!isAssertFound) {
|
||||
final String additionalAssertMethodPattern = getProperty(ADDITIONAL_ASSERT_METHOD_PATTERN_DESCRIPTOR);
|
||||
final Pattern compiledPattern = getCompiledAdditionalAssertMethodPattern(additionalAssertMethodPattern);
|
||||
@ -105,12 +127,15 @@ public class ApexUnitTestClassShouldHaveAssertsRule extends AbstractApexUnitTest
|
||||
|
||||
private Pattern getCompiledAdditionalAssertMethodPattern(String additionalAssertMethodPattern) {
|
||||
if (StringUtils.isNotBlank(additionalAssertMethodPattern)) {
|
||||
// Check for presence first since we will cache a null value for patterns that don't compile
|
||||
// Check for presence first since we will cache a null value for patterns that
|
||||
// don't compile
|
||||
if (compiledAdditionalAssertMethodPattern == null) {
|
||||
try {
|
||||
compiledAdditionalAssertMethodPattern = Optional.of(Pattern.compile(additionalAssertMethodPattern, Pattern.CASE_INSENSITIVE));
|
||||
compiledAdditionalAssertMethodPattern = Optional
|
||||
.of(Pattern.compile(additionalAssertMethodPattern, Pattern.CASE_INSENSITIVE));
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Cache a null compiled pattern so that we won't try to compile this one again during the run
|
||||
// Cache a null compiled pattern so that we won't try to compile this one again
|
||||
// during the run
|
||||
compiledAdditionalAssertMethodPattern = Optional.ofNullable(null);
|
||||
throw e;
|
||||
}
|
||||
|
@ -7,13 +7,11 @@ package net.sourceforge.pmd.lang.apex.ast;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import apex.jorje.semantic.ast.compilation.Compilation;
|
||||
|
||||
public class ASTFieldTest extends ApexParserTestBase {
|
||||
|
||||
@Test
|
||||
public void testGetType() {
|
||||
ApexNode<Compilation> node = parse("public class Foo { private String myField = 'a'; }");
|
||||
ApexNode<?> node = parse("public class Foo { private String myField = 'a'; }");
|
||||
ASTField field = node.getFirstDescendantOfType(ASTField.class);
|
||||
|
||||
Assert.assertEquals("myField", field.getImage());
|
||||
@ -23,7 +21,7 @@ public class ASTFieldTest extends ApexParserTestBase {
|
||||
|
||||
@Test
|
||||
public void testGetValue() {
|
||||
ApexNode<Compilation> node = parse("public class Foo { private String myField = 'a'; }");
|
||||
ApexNode<?> node = parse("public class Foo { private String myField = 'a'; }");
|
||||
ASTField field = node.getFirstDescendantOfType(ASTField.class);
|
||||
|
||||
Assert.assertEquals("a", field.getValue());
|
||||
@ -31,7 +29,7 @@ public class ASTFieldTest extends ApexParserTestBase {
|
||||
|
||||
@Test
|
||||
public void testGetNoValue() {
|
||||
ApexNode<Compilation> node = parse("public class Foo { private String myField; }");
|
||||
ApexNode<?> node = parse("public class Foo { private String myField; }");
|
||||
ASTField field = node.getFirstDescendantOfType(ASTField.class);
|
||||
|
||||
Assert.assertNull(field.getValue());
|
||||
|
@ -9,13 +9,11 @@ import java.util.List;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import apex.jorje.semantic.ast.compilation.Compilation;
|
||||
|
||||
public class ASTMethodTest extends ApexParserTestBase {
|
||||
|
||||
@Test
|
||||
public void testConstructorName() {
|
||||
ApexNode<Compilation> node = parse("public class Foo { public Foo() {} public void bar() {} }");
|
||||
ApexNode<?> node = parse("public class Foo { public Foo() {} public void bar() {} }");
|
||||
Assert.assertSame(ASTUserClass.class, node.getClass());
|
||||
List<ASTMethod> methods = node.findChildrenOfType(ASTMethod.class);
|
||||
Assert.assertEquals("Foo", methods.get(0).getImage()); // constructor
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user