From cf054a1427fb044c41da68d869df4a9aa72e50ab Mon Sep 17 00:00:00 2001 From: Edward Klimoshenko Date: Sun, 21 Aug 2022 11:31:11 +0000 Subject: [PATCH] Build `switch` statements --- .../pmd/lang/apex/ast/ASTElseWhenBlock.java | 10 +++---- .../pmd/lang/apex/ast/ASTSwitchStatement.java | 10 +++---- .../pmd/lang/apex/ast/ASTTypeWhenBlock.java | 21 ++++---------- .../pmd/lang/apex/ast/ASTValueWhenBlock.java | 11 +++---- .../pmd/lang/apex/ast/ApexTreeBuilder.kt | 29 +++++++++++++++++++ 5 files changed, 47 insertions(+), 34 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTElseWhenBlock.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTElseWhenBlock.java index 62882df606..3969bb783f 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTElseWhenBlock.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTElseWhenBlock.java @@ -4,16 +4,14 @@ package net.sourceforge.pmd.lang.apex.ast; -import com.google.summit.ast.Node; +import com.google.summit.ast.statement.SwitchStatement; -public final class ASTElseWhenBlock extends AbstractApexNode.Single { +public final class ASTElseWhenBlock extends AbstractApexNode.Single { - - ASTElseWhenBlock(Node node) { - super(node); + ASTElseWhenBlock(SwitchStatement.WhenElse whenElse) { + super(whenElse); } - @Override public Object jjtAccept(ApexParserVisitor visitor, Object data) { return visitor.visit(this, data); diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSwitchStatement.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSwitchStatement.java index 1b8b629730..ee7e7ccf61 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSwitchStatement.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSwitchStatement.java @@ -4,16 +4,14 @@ package net.sourceforge.pmd.lang.apex.ast; -import com.google.summit.ast.Node; +import com.google.summit.ast.statement.SwitchStatement; -public final class ASTSwitchStatement extends AbstractApexNode.Single { +public final class ASTSwitchStatement extends AbstractApexNode.Single { - - ASTSwitchStatement(Node node) { - super(node); + ASTSwitchStatement(SwitchStatement switchStatement) { + super(switchStatement); } - @Override public Object jjtAccept(ApexParserVisitor visitor, Object data) { return visitor.visit(this, data); diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTTypeWhenBlock.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTTypeWhenBlock.java index e18f6b41d4..3fee5c32a4 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTTypeWhenBlock.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTTypeWhenBlock.java @@ -4,29 +4,20 @@ package net.sourceforge.pmd.lang.apex.ast; -import com.google.summit.ast.Node; -import org.apache.commons.lang3.reflect.FieldUtils; +import com.google.summit.ast.statement.SwitchStatement; -public final class ASTTypeWhenBlock extends AbstractApexNode.Single { +public final class ASTTypeWhenBlock extends AbstractApexNode.Single { - - ASTTypeWhenBlock(Node node) { - super(node); + ASTTypeWhenBlock(SwitchStatement.WhenType whenType) { + super(whenType); } public String getType() { - // return String.valueOf(node.getTypeRef()); - // TODO(b/239648780) - return null; + return node.getType().asCodeString(); } public String getName() { - // unfortunately the name is not exposed... - try { - return String.valueOf(FieldUtils.readDeclaredField(node, "name", true)); - } catch (IllegalArgumentException | ReflectiveOperationException e) { - return null; - } + return node.getVariableDeclaration().getId().getString(); } @Override diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTValueWhenBlock.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTValueWhenBlock.java index 740ebaad9d..c50c854c3e 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTValueWhenBlock.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTValueWhenBlock.java @@ -4,17 +4,14 @@ package net.sourceforge.pmd.lang.apex.ast; +import com.google.summit.ast.statement.SwitchStatement; -import com.google.summit.ast.Node; +public final class ASTValueWhenBlock extends AbstractApexNode.Single { -public final class ASTValueWhenBlock extends AbstractApexNode.Single { - - - ASTValueWhenBlock(Node node) { - super(node); + ASTValueWhenBlock(SwitchStatement.WhenValue whenValue) { + super(whenValue); } - @Override public Object jjtAccept(ApexParserVisitor visitor, Object data) { return visitor.visit(this, data); diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeBuilder.kt b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeBuilder.kt index 62567f8fc8..a474ea0141 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeBuilder.kt +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeBuilder.kt @@ -53,6 +53,7 @@ import com.google.summit.ast.statement.ExpressionStatement import com.google.summit.ast.statement.ForLoopStatement import com.google.summit.ast.statement.IfStatement import com.google.summit.ast.statement.Statement +import com.google.summit.ast.statement.SwitchStatement import com.google.summit.ast.statement.VariableDeclarationStatement import com.google.summit.ast.statement.WhileLoopStatement @@ -134,6 +135,8 @@ class ApexTreeBuilder(val sourceCode: String, val parserOptions: ApexParserOptio is DoWhileLoopStatement -> buildDoWhileLoopStatement(node) is WhileLoopStatement -> buildWhileLoopStatement(node) is ForLoopStatement -> buildForLoopStatement(node) + is SwitchStatement -> ASTSwitchStatement(node).apply { buildChildren(node, parent = this) } + is SwitchStatement.When -> buildSwitchWhen(node) is Identifier, is KeywordModifier, is TypeRef -> null @@ -584,6 +587,32 @@ class ApexTreeBuilder(val sourceCode: String, val parserOptions: ApexParserOptio ) } + /** + * Builds an [ASTValueWhenBlock], [ASTTypeWhenBlock], or [ASTElseWhenBlock] wrapper for the + * [SwitchStatement.When]. + */ + private fun buildSwitchWhen(node: SwitchStatement.When) = + when (node) { + is SwitchStatement.WhenValue -> + ASTValueWhenBlock(node).apply { + node.values.forEach { value -> + when (value) { + is LiteralExpression, + is UnaryExpression /* negative */ -> + ASTLiteralCase(value).apply { buildAndSetParent(value, parent = this) } + is VariableExpression -> ASTIdentifierCase(value) + else -> throw ParseException("Invalid when value type") + }.also { it.setParent(this) } + } + + buildChildren(node, parent = this, exclude = { it in node.values }) + } + is SwitchStatement.WhenType -> + ASTTypeWhenBlock(node).apply { buildChildren(node, parent = this) } + is SwitchStatement.WhenElse -> + ASTElseWhenBlock(node).apply { buildChildren(node, parent = this) } + } + /** Builds an [ASTStandardCondition] wrapper for the [condition]. */ private fun buildCondition(condition: Node) = ASTStandardCondition(condition).apply { buildAndSetParent(condition, this) }