Fix support of - and + prefix operators in JS parser

Treat number literal that represents minimum integer as integer node in
JS AST.

Treat +<number_literal> JS AST as unary node (+) containing single
number literal
This commit is contained in:
Alexey Andreev
2017-05-22 17:32:00 +03:00
parent 590954e9a8
commit 1dae687e7d
5 changed files with 28 additions and 32 deletions
@@ -681,7 +681,13 @@ public class JsAstMapper {
}
private static JsExpression mapIntNumber(Node numberNode) {
return new JsIntLiteral((int) numberNode.getDouble());
double value = numberNode.getDouble();
if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE) {
return new JsIntLiteral((int) numberNode.getDouble());
}
else {
return new JsDoubleLiteral(numberNode.getDouble());
}
}
private static JsExpression mapDoubleNumber(Node numberNode) {
@@ -1032,8 +1038,17 @@ public class JsAstMapper {
private JsExpression mapUnaryVariant(Node unOp) throws JsParserException {
switch (unOp.getOperation()) {
case TokenStream.SUB:
case TokenStream.SUB: {
Node operand = unOp.getFirstChild();
if (operand.getType() == TokenStream.NUMBER_INT) {
double value = operand.getDouble();
if (-value >= Integer.MIN_VALUE) {
return new JsIntLiteral((int) -value);
}
}
return mapPrefixOperation(JsUnaryOperator.NEG, unOp);
}
case TokenStream.NOT:
return mapPrefixOperation(JsUnaryOperator.NOT, unOp);
@@ -1045,13 +1060,7 @@ public class JsAstMapper {
return mapPrefixOperation(JsUnaryOperator.TYPEOF, unOp);
case TokenStream.ADD:
if (!isJsNumber(unOp.getFirstChild())) {
return mapPrefixOperation(JsUnaryOperator.POS, unOp);
}
else {
// Pretend we didn't see it.
return mapExpression(unOp.getFirstChild());
}
return mapPrefixOperation(JsUnaryOperator.POS, unOp);
case TokenStream.VOID:
return mapPrefixOperation(JsUnaryOperator.VOID, unOp);
@@ -1098,11 +1107,6 @@ public class JsAstMapper {
withNode);
}
private boolean isJsNumber(Node jsNode) {
int type = jsNode.getType();
return type == TokenStream.NUMBER || type == TokenStream.NUMBER;
}
private <T extends JsNode> T withLocation(T astNode, Node node) {
CodePosition location = node.getPosition();
if (location != null) {
@@ -106,8 +106,8 @@ public class IRFactory {
/**
* Number (for literals)
*/
public Node createNumber(int number, CodePosition location) {
return Node.newNumber(number, location);
public Node createIntNumber(double number, CodePosition location) {
return Node.newIntNumber(number, location);
}
public Node createNumber(double number, CodePosition location) {
@@ -45,14 +45,8 @@ package com.google.gwt.dev.js.rhino;
public class Node implements Cloneable {
private static class NumberNode extends Node {
NumberNode(int number, CodePosition location) {
super(TokenStream.NUMBER_INT, location);
this.number = number;
}
NumberNode(double number, CodePosition position) {
super(TokenStream.NUMBER, position);
NumberNode(int type, double number, CodePosition position) {
super(type, position);
this.number = number;
}
@@ -181,12 +175,12 @@ public class Node implements Cloneable {
this.position = position;
}
public static Node newNumber(int number, CodePosition position) {
return new NumberNode(number, position);
public static Node newIntNumber(double number, CodePosition position) {
return new NumberNode(TokenStream.NUMBER_INT, number, position);
}
public static Node newNumber(double number, CodePosition position) {
return new NumberNode(number, position);
return new NumberNode(TokenStream.NUMBER, number, position);
}
public static Node newString(String str, CodePosition position) {
@@ -1068,8 +1068,7 @@ public class Parser extends Observable {
property = nf.createString(ts.getString(), ts.tokenPosition);
break;
case TokenStream.NUMBER_INT:
int n = (int) ts.getNumber();
property = nf.createNumber(n, ts.tokenPosition);
property = nf.createIntNumber(ts.getNumber(), ts.tokenPosition);
break;
case TokenStream.NUMBER:
double d = ts.getNumber();
@@ -1114,8 +1113,7 @@ public class Parser extends Observable {
return nf.createName(name, position);
case TokenStream.NUMBER_INT:
int n = (int) ts.getNumber();
return nf.createNumber(n, position);
return nf.createIntNumber(ts.getNumber(), position);
case TokenStream.NUMBER:
double d = ts.getNumber();
@@ -802,7 +802,7 @@ public class TokenStream {
this.number = dval;
if (isInteger && this.number >= Integer.MIN_VALUE && this.number <= Integer.MAX_VALUE) {
if (isInteger) {
return NUMBER_INT;
}