41 import jdk.nashorn.internal.parser.TokenType; 42 43 /** 44 * UnaryNode nodes represent single operand operations. 45 */ 46 @Immutable 47 public final class UnaryNode extends Expression implements Assignment<Expression>, Optimistic { 48 private static final long serialVersionUID = 1L; 49 50 /** Right hand side argument. */ 51 private final Expression expression; 52 53 private final int programPoint; 54 55 private final Type type; 56 57 @Ignore 58 private static final List<TokenType> CAN_OVERFLOW = 59 Collections.unmodifiableList( 60 Arrays.asList(new TokenType[] { 61 TokenType.ADD, 62 TokenType.SUB, //negate 63 TokenType.DECPREFIX, 64 TokenType.DECPOSTFIX, 65 TokenType.INCPREFIX, 66 TokenType.INCPOSTFIX, 67 })); 68 69 /** 70 * Constructor 71 * 72 * @param token token 73 * @param rhs expression 74 */ 75 public UnaryNode(final long token, final Expression rhs) { 76 this(token, Math.min(rhs.getStart(), Token.descPosition(token)), Math.max(Token.descPosition(token) + Token.descLength(token), rhs.getFinish()), rhs); 77 } 78 79 /** 80 * Constructor 81 * 82 * @param token token 108 public boolean isAssignment() { 109 switch (tokenType()) { 110 case DECPOSTFIX: 111 case DECPREFIX: 112 case INCPOSTFIX: 113 case INCPREFIX: 114 return true; 115 default: 116 return false; 117 } 118 } 119 120 @Override 121 public boolean isSelfModifying() { 122 return isAssignment(); 123 } 124 125 @Override 126 public Type getWidestOperationType() { 127 switch (tokenType()) { 128 case ADD: 129 final Type operandType = getExpression().getType(); 130 if(operandType == Type.BOOLEAN) { 131 return Type.INT; 132 } else if(operandType.isObject()) { 133 return Type.NUMBER; 134 } 135 assert operandType.isNumeric(); 136 return operandType; 137 case SUB: 138 // This might seems overly conservative until you consider that -0 can only be represented as a double. 139 return Type.NUMBER; 140 case NOT: 141 case DELETE: 142 return Type.BOOLEAN; 143 case BIT_NOT: 144 return Type.INT; 145 case VOID: 146 return Type.UNDEFINED; 147 default: 148 return isAssignment() ? Type.NUMBER : Type.OBJECT; 149 } 150 } 151 152 @Override 153 public Expression getAssignmentDest() { 154 return isAssignment() ? getExpression() : null; 155 } 156 157 @Override 165 } 166 167 /** 168 * Assist in IR navigation. 169 * @param visitor IR navigating visitor. 170 */ 171 @Override 172 public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { 173 if (visitor.enterUnaryNode(this)) { 174 return visitor.leaveUnaryNode(setExpression((Expression)expression.accept(visitor))); 175 } 176 177 return this; 178 } 179 180 @Override 181 public boolean isLocal() { 182 switch (tokenType()) { 183 case NEW: 184 return false; 185 case ADD: 186 case SUB: 187 case NOT: 188 case BIT_NOT: 189 return expression.isLocal() && expression.getType().isJSPrimitive(); 190 case DECPOSTFIX: 191 case DECPREFIX: 192 case INCPOSTFIX: 193 case INCPREFIX: 194 return expression instanceof IdentNode && expression.isLocal() && expression.getType().isJSPrimitive(); 195 default: 196 return expression.isLocal(); 197 } 198 } 199 200 @Override 201 public void toString(final StringBuilder sb, final boolean printType) { 202 toString(sb, 203 new Runnable() { 204 @Override 205 public void run() { 206 getExpression().toString(sb, printType); | 41 import jdk.nashorn.internal.parser.TokenType; 42 43 /** 44 * UnaryNode nodes represent single operand operations. 45 */ 46 @Immutable 47 public final class UnaryNode extends Expression implements Assignment<Expression>, Optimistic { 48 private static final long serialVersionUID = 1L; 49 50 /** Right hand side argument. */ 51 private final Expression expression; 52 53 private final int programPoint; 54 55 private final Type type; 56 57 @Ignore 58 private static final List<TokenType> CAN_OVERFLOW = 59 Collections.unmodifiableList( 60 Arrays.asList(new TokenType[] { 61 TokenType.POS, 62 TokenType.NEG, //negate 63 TokenType.DECPREFIX, 64 TokenType.DECPOSTFIX, 65 TokenType.INCPREFIX, 66 TokenType.INCPOSTFIX, 67 })); 68 69 /** 70 * Constructor 71 * 72 * @param token token 73 * @param rhs expression 74 */ 75 public UnaryNode(final long token, final Expression rhs) { 76 this(token, Math.min(rhs.getStart(), Token.descPosition(token)), Math.max(Token.descPosition(token) + Token.descLength(token), rhs.getFinish()), rhs); 77 } 78 79 /** 80 * Constructor 81 * 82 * @param token token 108 public boolean isAssignment() { 109 switch (tokenType()) { 110 case DECPOSTFIX: 111 case DECPREFIX: 112 case INCPOSTFIX: 113 case INCPREFIX: 114 return true; 115 default: 116 return false; 117 } 118 } 119 120 @Override 121 public boolean isSelfModifying() { 122 return isAssignment(); 123 } 124 125 @Override 126 public Type getWidestOperationType() { 127 switch (tokenType()) { 128 case POS: 129 final Type operandType = getExpression().getType(); 130 if(operandType == Type.BOOLEAN) { 131 return Type.INT; 132 } else if(operandType.isObject()) { 133 return Type.NUMBER; 134 } 135 assert operandType.isNumeric(); 136 return operandType; 137 case NEG: 138 // This might seems overly conservative until you consider that -0 can only be represented as a double. 139 return Type.NUMBER; 140 case NOT: 141 case DELETE: 142 return Type.BOOLEAN; 143 case BIT_NOT: 144 return Type.INT; 145 case VOID: 146 return Type.UNDEFINED; 147 default: 148 return isAssignment() ? Type.NUMBER : Type.OBJECT; 149 } 150 } 151 152 @Override 153 public Expression getAssignmentDest() { 154 return isAssignment() ? getExpression() : null; 155 } 156 157 @Override 165 } 166 167 /** 168 * Assist in IR navigation. 169 * @param visitor IR navigating visitor. 170 */ 171 @Override 172 public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { 173 if (visitor.enterUnaryNode(this)) { 174 return visitor.leaveUnaryNode(setExpression((Expression)expression.accept(visitor))); 175 } 176 177 return this; 178 } 179 180 @Override 181 public boolean isLocal() { 182 switch (tokenType()) { 183 case NEW: 184 return false; 185 case POS: 186 case NEG: 187 case NOT: 188 case BIT_NOT: 189 return expression.isLocal() && expression.getType().isJSPrimitive(); 190 case DECPOSTFIX: 191 case DECPREFIX: 192 case INCPOSTFIX: 193 case INCPREFIX: 194 return expression instanceof IdentNode && expression.isLocal() && expression.getType().isJSPrimitive(); 195 default: 196 return expression.isLocal(); 197 } 198 } 199 200 @Override 201 public void toString(final StringBuilder sb, final boolean printType) { 202 toString(sb, 203 new Runnable() { 204 @Override 205 public void run() { 206 getExpression().toString(sb, printType); |