forked from phoedos/pmd
Build if
statements
Change-Id: I4db2d2dfd028ae820c73f9fcb5fff4fa5e6c3ece
This commit is contained in:
parent
72bb311aba
commit
bd8e47edd1
@ -4,15 +4,16 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import com.google.summit.ast.Node;
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
|
||||
public class ASTIfBlockStatement extends AbstractApexNode.Single<Node> {
|
||||
import com.google.summit.ast.statement.IfStatement;
|
||||
|
||||
public class ASTIfBlockStatement extends AbstractApexNode.Single<IfStatement> {
|
||||
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
public ASTIfBlockStatement(Node ifBlockStatement) {
|
||||
super(ifBlockStatement);
|
||||
public ASTIfBlockStatement(IfStatement ifStatement) {
|
||||
super(ifStatement);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -4,15 +4,19 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import com.google.summit.ast.Node;
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
|
||||
public class ASTIfElseBlockStatement extends AbstractApexNode.Single<Node> {
|
||||
import com.google.summit.ast.statement.IfStatement;
|
||||
|
||||
public class ASTIfElseBlockStatement extends AbstractApexNode.Single<IfStatement> {
|
||||
|
||||
private final boolean hasElseStatement;
|
||||
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
public ASTIfElseBlockStatement(Node ifElseBlockStatement) {
|
||||
super(ifElseBlockStatement);
|
||||
public ASTIfElseBlockStatement(IfStatement ifStatement, boolean hasElseStatement) {
|
||||
super(ifStatement);
|
||||
this.hasElseStatement = hasElseStatement;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -21,8 +25,6 @@ public class ASTIfElseBlockStatement extends AbstractApexNode.Single<Node> {
|
||||
}
|
||||
|
||||
public boolean hasElseStatement() {
|
||||
// return node.hasElseStatement();
|
||||
// TODO(b/239648780)
|
||||
return false;
|
||||
return hasElseStatement;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ import com.google.summit.ast.modifier.KeywordModifier.Keyword
|
||||
import com.google.summit.ast.modifier.Modifier
|
||||
import com.google.summit.ast.statement.CompoundStatement
|
||||
import com.google.summit.ast.statement.ExpressionStatement
|
||||
import com.google.summit.ast.statement.IfStatement
|
||||
import com.google.summit.ast.statement.Statement
|
||||
|
||||
@Deprecated("internal")
|
||||
@InternalApi
|
||||
@ -117,6 +119,8 @@ class ApexTreeBuilder(val sourceCode: String, val parserOptions: ApexParserOptio
|
||||
is ValuesInitializer -> buildValuesInitializer(node)
|
||||
is MapInitializer -> buildMapInitializer(node)
|
||||
is SizedArrayInitializer -> buildSizedArrayInitializer(node)
|
||||
is DmlStatement -> buildDmlStatement(node)
|
||||
is IfStatement -> buildIfStatement(node)
|
||||
is Identifier,
|
||||
is KeywordModifier,
|
||||
is TypeRef -> null
|
||||
@ -424,6 +428,60 @@ class ApexTreeBuilder(val sourceCode: String, val parserOptions: ApexParserOptio
|
||||
private fun buildSizedArrayInitializer(node: SizedArrayInitializer) =
|
||||
ASTNewListInitExpression(node).apply { buildChildren(node, parent = this) }
|
||||
|
||||
/** Builds an [ApexNode] wrapper for the [DmlStatement]. */
|
||||
private fun buildDmlStatement(node: DmlStatement) =
|
||||
when (node) {
|
||||
is DmlStatement.Insert -> ASTDmlInsertStatement(node)
|
||||
is DmlStatement.Update -> ASTDmlUpdateStatement(node)
|
||||
is DmlStatement.Delete -> ASTDmlDeleteStatement(node)
|
||||
is DmlStatement.Undelete -> ASTDmlUndeleteStatement(node)
|
||||
is DmlStatement.Upsert -> ASTDmlUpsertStatement(node)
|
||||
is DmlStatement.Merge -> ASTDmlMergeStatement(node)
|
||||
}.apply { buildChildren(node, parent = this) }
|
||||
|
||||
/** Wraps the body of a control statement with an [ASTBlockStatement] if it isn't already one. */
|
||||
private fun wrapBody(body: Statement, parent: ApexNode<*>) =
|
||||
when (body) {
|
||||
is CompoundStatement -> build(body, parent) as ASTBlockStatement
|
||||
else -> ASTBlockStatement(body).apply { buildAndSetParent(body, parent = this) }
|
||||
}
|
||||
|
||||
/** Builds an [ASTIfElseBlockStatement] wrapper for the [IfStatement]. */
|
||||
private fun buildIfStatement(node: IfStatement): ASTIfElseBlockStatement {
|
||||
val (ifBlocks, elseBlock) = flattenIfStatement(node)
|
||||
|
||||
/** Builds an [ASTIfBlockStatement] wrapper for the [if block][IfStatement]. */
|
||||
fun buildIfBlock(ifBlock: IfStatement) =
|
||||
ASTIfBlockStatement(ifBlock).apply {
|
||||
buildCondition(ifBlock.condition).also { it.setParent(this) }
|
||||
wrapBody(ifBlock.thenStatement, parent = this).also { it.setParent(this) }
|
||||
}
|
||||
|
||||
return ASTIfElseBlockStatement(node, elseBlock != null).apply {
|
||||
ifBlocks.forEach { ifBlock -> buildIfBlock(ifBlock).also { it.setParent(this) } }
|
||||
if (elseBlock != null) {
|
||||
wrapBody(elseBlock, parent = this).also { it.setParent(this) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Result of [flattenIfStatement]. */
|
||||
private data class FlatIfStatement(val ifBlocks: List<IfStatement>, val elseBlock: Statement?)
|
||||
|
||||
/** Flattens an [IfStatement] into a list of [IfStatement]s. */
|
||||
private fun flattenIfStatement(
|
||||
node: Statement?,
|
||||
ifBlocks: List<IfStatement> = emptyList()
|
||||
): FlatIfStatement =
|
||||
when (node) {
|
||||
is IfStatement ->
|
||||
// Extract node and continue flattening
|
||||
flattenIfStatement(node = node.elseStatement, ifBlocks = ifBlocks + node)
|
||||
else ->
|
||||
// Can't flatten
|
||||
FlatIfStatement(ifBlocks, elseBlock = node)
|
||||
}
|
||||
|
||||
/** Builds an [ASTStandardCondition] wrapper for the [condition]. */
|
||||
private fun buildCondition(condition: Node?) =
|
||||
ASTStandardCondition(condition).apply { buildAndSetParent(condition, this) }
|
||||
|
Loading…
x
Reference in New Issue
Block a user