aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/ir/TernaryNode.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/ir/TernaryNode.java')
-rw-r--r--src/jdk/nashorn/internal/ir/TernaryNode.java55
1 files changed, 33 insertions, 22 deletions
diff --git a/src/jdk/nashorn/internal/ir/TernaryNode.java b/src/jdk/nashorn/internal/ir/TernaryNode.java
index 26c14b76..913262d9 100644
--- a/src/jdk/nashorn/internal/ir/TernaryNode.java
+++ b/src/jdk/nashorn/internal/ir/TernaryNode.java
@@ -25,20 +25,23 @@
package jdk.nashorn.internal.ir;
+import java.util.function.Function;
+import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.annotations.Immutable;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.TokenType;
/**
- * TernaryNode nodes represent three operand operations (?:).
+ * TernaryNode represent the ternary operator {@code ?:}. Note that for control-flow calculation reasons its branch
+ * expressions (but not its test expression) are always wrapped in instances of {@link JoinPredecessorExpression}.
*/
@Immutable
public final class TernaryNode extends Expression {
- private final Expression test;
-
- private final Expression trueExpr;
+ private static final long serialVersionUID = 1L;
- /** Third argument. */
- private final Expression falseExpr;
+ private final Expression test;
+ private final JoinPredecessorExpression trueExpr;
+ private final JoinPredecessorExpression falseExpr;
/**
* Constructor
@@ -48,14 +51,15 @@ public final class TernaryNode extends Expression {
* @param trueExpr expression evaluated when test evaluates to true
* @param falseExpr expression evaluated when test evaluates to true
*/
- public TernaryNode(final long token, final Expression test, final Expression trueExpr, final Expression falseExpr) {
+ public TernaryNode(final long token, final Expression test, final JoinPredecessorExpression trueExpr, final JoinPredecessorExpression falseExpr) {
super(token, falseExpr.getFinish());
this.test = test;
this.trueExpr = trueExpr;
this.falseExpr = falseExpr;
}
- private TernaryNode(final TernaryNode ternaryNode, final Expression test, final Expression trueExpr, final Expression falseExpr) {
+ private TernaryNode(final TernaryNode ternaryNode, final Expression test, final JoinPredecessorExpression trueExpr,
+ final JoinPredecessorExpression falseExpr) {
super(ternaryNode);
this.test = test;
this.trueExpr = trueExpr;
@@ -66,24 +70,25 @@ public final class TernaryNode extends Expression {
public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
if (visitor.enterTernaryNode(this)) {
final Expression newTest = (Expression)getTest().accept(visitor);
- final Expression newTrueExpr = (Expression)getTrueExpression().accept(visitor);
- final Expression newFalseExpr = (Expression)falseExpr.accept(visitor);
- return visitor.leaveTernaryNode(setTest(newTest).setTrueExpression(newTrueExpr).setFalseExpression1(newFalseExpr));
+ final JoinPredecessorExpression newTrueExpr = (JoinPredecessorExpression)trueExpr.accept(visitor);
+ final JoinPredecessorExpression newFalseExpr = (JoinPredecessorExpression)falseExpr.accept(visitor);
+ return visitor.leaveTernaryNode(setTest(newTest).setTrueExpression(newTrueExpr).setFalseExpression(newFalseExpr));
}
return this;
}
@Override
- public void toString(final StringBuilder sb) {
- final boolean testParen = tokenType().needsParens(getTest().tokenType(), true);
- final boolean trueParen = tokenType().needsParens(getTrueExpression().tokenType(), false);
- final boolean falseParen = tokenType().needsParens(getFalseExpression().tokenType(), false);
+ public void toString(final StringBuilder sb, final boolean printType) {
+ final TokenType tokenType = tokenType();
+ final boolean testParen = tokenType.needsParens(getTest().tokenType(), true);
+ final boolean trueParen = tokenType.needsParens(getTrueExpression().tokenType(), false);
+ final boolean falseParen = tokenType.needsParens(getFalseExpression().tokenType(), false);
if (testParen) {
sb.append('(');
}
- getTest().toString(sb);
+ getTest().toString(sb, printType);
if (testParen) {
sb.append(')');
}
@@ -93,7 +98,7 @@ public final class TernaryNode extends Expression {
if (trueParen) {
sb.append('(');
}
- getTrueExpression().toString(sb);
+ getTrueExpression().toString(sb, printType);
if (trueParen) {
sb.append(')');
}
@@ -103,7 +108,7 @@ public final class TernaryNode extends Expression {
if (falseParen) {
sb.append('(');
}
- getFalseExpression().toString(sb);
+ getFalseExpression().toString(sb, printType);
if (falseParen) {
sb.append(')');
}
@@ -116,6 +121,12 @@ public final class TernaryNode extends Expression {
&& getFalseExpression().isLocal();
}
+ @Override
+ public Type getType(final Function<Symbol, Type> localVariableTypes) {
+ return Type.widestReturnType(getTrueExpression().getType(localVariableTypes), getFalseExpression().getType(localVariableTypes));
+ }
+
+
/**
* Get the test expression for this ternary expression, i.e. "x" in x ? y : z
* @return the test expression
@@ -128,7 +139,7 @@ public final class TernaryNode extends Expression {
* Get the true expression for this ternary expression, i.e. "y" in x ? y : z
* @return the true expression
*/
- public Expression getTrueExpression() {
+ public JoinPredecessorExpression getTrueExpression() {
return trueExpr;
}
@@ -136,7 +147,7 @@ public final class TernaryNode extends Expression {
* Get the false expression for this ternary expression, i.e. "z" in x ? y : z
* @return the false expression
*/
- public Expression getFalseExpression() {
+ public JoinPredecessorExpression getFalseExpression() {
return falseExpr;
}
@@ -157,7 +168,7 @@ public final class TernaryNode extends Expression {
* @param trueExpr new true expression
* @return a node equivalent to this one except for the requested change.
*/
- public TernaryNode setTrueExpression(final Expression trueExpr) {
+ public TernaryNode setTrueExpression(final JoinPredecessorExpression trueExpr) {
if (this.trueExpr == trueExpr) {
return this;
}
@@ -169,7 +180,7 @@ public final class TernaryNode extends Expression {
* @param falseExpr new false expression
* @return a node equivalent to this one except for the requested change.
*/
- public TernaryNode setFalseExpression1(final Expression falseExpr) {
+ public TernaryNode setFalseExpression(final JoinPredecessorExpression falseExpr) {
if (this.falseExpr == falseExpr) {
return this;
}