[apex] Finish ASTReferenceExpression

- removed method getContext() - always returned null
  Fixes TODO(b/243906211)
- Verify that getReferenceType() returns the correct values
  Fixes TODO(b/239648780)
This commit is contained in:
Andreas Dangel
2024-02-10 20:54:53 +01:00
parent ef165acebe
commit 19907a74d9
5 changed files with 66 additions and 23 deletions

View File

@ -256,6 +256,8 @@ The following previously deprecated classes have been removed:
* The constant `STATIC_INITIALIZER_METHOD_NAME` in {%jdoc apex::lang.apex.rule.codestyle.FieldDeclarationsShouldBeAtStartRule %}
has been removed. It was used to filter out synthetic methods, but these are not generated anymore with the
new parser.
* The method `getContext()` in {%jdoc apex::lang.apex.ast.ASTReferenceExpression %} has been removed.
It was not used and always returned `null`.
* pmd-java
* The interface `FinalizableNode` (introduced in 7.0.0-rc1) has been removed.
Its method `isFinal()` has been moved down to the

View File

@ -26,15 +26,7 @@ public final class ASTReferenceExpression extends AbstractApexNode.Many<Identifi
return visitor.visit(this, data);
}
/*
public IdentifierContext getContext() {
return node.getContext();
}
*/
// TODO(b/243906211)
/* TODO(b/239648780) this is not yet set to a meaningful value
public */ ReferenceType getReferenceType() {
public ReferenceType getReferenceType() {
return referenceType;
}

View File

@ -395,7 +395,7 @@ class ApexTreeBuilder(val task: ParserTask, val proc: ApexLanguageProcessor) {
else -> {
val (receiver, components, isSafe) = flattenExpression(node.receiver)
ASTMethodCallExpression(node, components).apply {
buildReferenceExpression(components, receiver, ReferenceType.METHOD, isSafe).also {
buildReferenceExpression(components, receiver, ReferenceType.METHOD, isSafe || node.isSafe).also {
it.setParent(this)
}
buildChildren(node, parent = this, exclude = { it == node.receiver })

View File

@ -0,0 +1,49 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.ast;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
class ASTReferenceExpressionTest extends ApexParserTestBase {
@Test
void referenceTypeMethodWithSafeNav() {
ASTReferenceExpression reference = parse("class Foo { static void bar() { Foo?.staticMethod(); } }")
.descendants(ASTReferenceExpression.class)
.first();
assertEquals(ReferenceType.METHOD, reference.getReferenceType());
assertTrue(reference.isSafeNav());
}
@Test
void referenceTypeMethodWithoutSafeNav() {
ASTReferenceExpression reference = parse("class Foo { static void bar() { Foo.staticMethod(); } }")
.descendants(ASTReferenceExpression.class)
.first();
assertEquals(ReferenceType.METHOD, reference.getReferenceType());
assertFalse(reference.isSafeNav());
}
@Test
void referenceTypeLoad() {
ASTReferenceExpression reference = parse("class Foo { static void bar() { Foo x = Foo?.INSTANCE; } }")
.descendants(ASTReferenceExpression.class)
.first();
assertEquals(ReferenceType.LOAD, reference.getReferenceType());
assertTrue(reference.isSafeNav());
}
@Test
void referenceTypeStore() {
ASTReferenceExpression reference = parse("class Foo { static void bar() { Foo.INSTANCE = x; } }")
.descendants(ASTReferenceExpression.class)
.first();
assertEquals(ReferenceType.STORE, reference.getReferenceType());
assertFalse(reference.isSafeNav());
}
}

View File

@ -9,7 +9,7 @@
| +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
| +- FieldDeclaration[@DefiningType = "c__Foo", @Image = "x", @Name = "x", @Namespace = null, @RealLoc = true]
| +- VariableExpression[@DefiningType = "c__Foo", @Image = "anIntegerField", @Namespace = null, @RealLoc = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.LOAD, @SObjectType = false, @SafeNav = true]
| | +- VariableExpression[@DefiningType = "c__Foo", @Image = "anObject", @Namespace = null, @RealLoc = true]
| | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false]
| +- VariableExpression[@DefiningType = "c__Foo", @Image = "x", @Namespace = null, @RealLoc = true]
@ -18,9 +18,9 @@
| +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
| +- FieldDeclaration[@DefiningType = "c__Foo", @Image = "profileUrl", @Name = "profileUrl", @Namespace = null, @RealLoc = true]
| +- MethodCallExpression[@DefiningType = "c__Foo", @FullMethodName = "toExternalForm", @InputParametersSize = 0, @MethodName = "toExternalForm", @Namespace = null, @RealLoc = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.METHOD, @SObjectType = false, @SafeNav = true]
| | +- MethodCallExpression[@DefiningType = "c__Foo", @FullMethodName = "user.getProfileUrl", @InputParametersSize = 0, @MethodName = "getProfileUrl", @Namespace = null, @RealLoc = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "user", @Namespace = null, @RealLoc = true, @SObjectType = false, @SafeNav = false]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "user", @Namespace = null, @RealLoc = true, @ReferenceType = ReferenceType.METHOD, @SObjectType = false, @SafeNav = false]
| +- VariableExpression[@DefiningType = "c__Foo", @Image = "profileUrl", @Namespace = null, @RealLoc = true]
| +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false]
+- Method[@Arity = 1, @CanonicalName = "bar1", @Constructor = false, @DefiningType = "c__Foo", @Image = "bar1", @Namespace = null, @RealLoc = true, @ReturnType = "void", @StaticInitializer = false]
@ -30,15 +30,15 @@
| +- BlockStatement[@CurlyBrace = true, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
| +- ExpressionStatement[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
| | +- VariableExpression[@DefiningType = "c__Foo", @Image = "b", @Namespace = null, @RealLoc = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.LOAD, @SObjectType = false, @SafeNav = true]
| | +- VariableExpression[@DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true]
| | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false]
| +- ExpressionStatement[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
| +- MethodCallExpression[@DefiningType = "c__Foo", @FullMethodName = "c1", @InputParametersSize = 0, @MethodName = "c1", @Namespace = null, @RealLoc = true]
| +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false]
| +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.METHOD, @SObjectType = false, @SafeNav = true]
| +- CastExpression[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
| +- VariableExpression[@DefiningType = "c__Foo", @Image = "b1", @Namespace = null, @RealLoc = true]
| +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true]
| +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.LOAD, @SObjectType = false, @SafeNav = true]
| +- VariableExpression[@DefiningType = "c__Foo", @Image = "a1", @Namespace = null, @RealLoc = true]
| +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false]
+- Method[@Arity = 2, @CanonicalName = "bar2", @Constructor = false, @DefiningType = "c__Foo", @Image = "bar2", @Namespace = null, @RealLoc = true, @ReturnType = "void", @StaticInitializer = false]
@ -50,9 +50,9 @@
| +- BlockStatement[@CurlyBrace = true, @DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
| +- ExpressionStatement[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
| | +- VariableExpression[@DefiningType = "c__Foo", @Image = "aField", @Namespace = null, @RealLoc = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.LOAD, @SObjectType = false, @SafeNav = false]
| | +- MethodCallExpression[@DefiningType = "c__Foo", @FullMethodName = "aMethod", @InputParametersSize = 0, @MethodName = "aMethod", @Namespace = null, @RealLoc = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.METHOD, @SObjectType = false, @SafeNav = true]
| | +- ArrayLoadExpression[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
| | +- VariableExpression[@DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true]
| | | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false]
@ -60,9 +60,9 @@
| | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false]
| +- ExpressionStatement[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
| +- VariableExpression[@DefiningType = "c__Foo", @Image = "aField", @Namespace = null, @RealLoc = true]
| +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true]
| +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.LOAD, @SObjectType = false, @SafeNav = true]
| +- MethodCallExpression[@DefiningType = "c__Foo", @FullMethodName = "aMethod", @InputParametersSize = 0, @MethodName = "aMethod", @Namespace = null, @RealLoc = true]
| +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = false]
| +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.METHOD, @SObjectType = false, @SafeNav = false]
| +- ArrayLoadExpression[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
| +- VariableExpression[@DefiningType = "c__Foo", @Image = "a", @Namespace = null, @RealLoc = true]
| | +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false]
@ -77,14 +77,14 @@
| +- ModifierNode[@Abstract = false, @DefiningType = "c__Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Namespace = null, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
| +- VariableDeclaration[@DefiningType = "c__Foo", @Image = "s", @Namespace = null, @RealLoc = true, @Type = "String"]
| +- VariableExpression[@DefiningType = "c__Foo", @Image = "BillingCity", @Namespace = null, @RealLoc = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.LOAD, @SObjectType = false, @SafeNav = true]
| | +- VariableExpression[@DefiningType = "c__Foo", @Image = "Account", @Namespace = null, @RealLoc = true]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "contact", @Namespace = null, @RealLoc = true, @SObjectType = false, @SafeNav = false]
| | +- ReferenceExpression[@DefiningType = "c__Foo", @Image = "contact", @Namespace = null, @RealLoc = true, @ReferenceType = ReferenceType.LOAD, @SObjectType = false, @SafeNav = false]
| +- VariableExpression[@DefiningType = "c__Foo", @Image = "s", @Namespace = null, @RealLoc = true]
| +- EmptyReferenceExpression[@DefiningType = null, @Namespace = null, @RealLoc = false]
+- ReturnStatement[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
+- VariableExpression[@DefiningType = "c__Foo", @Image = "Name", @Namespace = null, @RealLoc = true]
+- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @SObjectType = false, @SafeNav = true]
+- ReferenceExpression[@DefiningType = "c__Foo", @Image = "", @Namespace = null, @RealLoc = false, @ReferenceType = ReferenceType.LOAD, @SObjectType = false, @SafeNav = true]
+- SoqlExpression[@CanonicalQuery = "SELECT Name FROM Account WHERE Id = :accId", @DefiningType = "c__Foo", @Namespace = null, @Query = "SELECT Name FROM Account WHERE Id = :accId", @RealLoc = true]
+- BindExpressions[@DefiningType = "c__Foo", @Namespace = null, @RealLoc = true]
+- VariableExpression[@DefiningType = "c__Foo", @Image = "accId", @Namespace = null, @RealLoc = true]