1 /* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.ir; 27 28 import jdk.nashorn.internal.codegen.types.Type; 29 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 30 31 /** 32 * A wrapper for an expression that is in a position to be a join predecessor. 33 */ 34 public class JoinPredecessorExpression extends Expression implements JoinPredecessor { 35 private static final long serialVersionUID = 1L; 36 37 private final Expression expression; 38 private final LocalVariableConversion conversion; 39 40 /** 41 * A no-arg constructor does not wrap any expression on its own, but can be used as a place to contain a local 42 * variable conversion in a place where an expression can otherwise stand. 43 */ 44 public JoinPredecessorExpression() { 45 this(null); 46 } 47 48 /** 49 * A constructor for wrapping an expression and making it a join predecessor. Typically used on true and false 50 * subexpressions of the ternary node as well as on the operands of short-circuiting logical expressions {@code &&} 51 * and {@code ||}. 52 * @param expression the expression to wrap 53 */ 54 public JoinPredecessorExpression(final Expression expression) { 55 this(expression, null); 56 } 57 58 private JoinPredecessorExpression(final Expression expression, final LocalVariableConversion conversion) { 59 super(expression == null ? 0L : expression.getToken(), expression == null ? 0 : expression.getStart(), expression == null ? 0 : expression.getFinish()); 60 this.expression = expression; 61 this.conversion = conversion; 62 } 63 64 @Override 65 public JoinPredecessor setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) { 66 if(conversion == this.conversion) { 67 return this; 68 } 69 return new JoinPredecessorExpression(expression, conversion); 70 } 71 72 @Override 73 public Type getType() { 74 return expression.getType(); 75 } 76 77 @Override 78 public boolean isAlwaysFalse() { 79 return expression != null && expression.isAlwaysFalse(); 80 } 81 82 @Override 83 public boolean isAlwaysTrue() { 84 return expression != null && expression.isAlwaysTrue(); 85 } 86 87 /** 88 * Returns the underlying expression. 89 * @return the underlying expression. 90 */ 91 public Expression getExpression() { 92 return expression; 93 } 94 95 /** 96 * Sets the underlying expression. 97 * @param expression the new underlying expression 98 * @return this or modified join predecessor expression object. 99 */ 100 public JoinPredecessorExpression setExpression(final Expression expression) { 101 if(expression == this.expression) { 102 return this; 103 } 104 return new JoinPredecessorExpression(expression, conversion); 105 } 106 107 @Override 108 public LocalVariableConversion getLocalVariableConversion() { 109 return conversion; 110 } 111 112 @Override 113 public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { 114 if(visitor.enterJoinPredecessorExpression(this)) { 115 final Expression expr = getExpression(); 116 return visitor.leaveJoinPredecessorExpression(expr == null ? this : setExpression((Expression)expr.accept(visitor))); 117 } 118 return this; 119 } 120 121 @Override 122 public void toString(final StringBuilder sb, final boolean printType) { 123 if(expression != null) { 124 expression.toString(sb, printType); 125 } 126 if(conversion != null) { 127 conversion.toString(sb); 128 } 129 } 130 131 }