From 1dae687e7d8b66b9dbb036e5d33c01182270a45c Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 22 May 2017 17:32:00 +0300 Subject: [PATCH] Fix support of - and + prefix operators in JS parser Treat number literal that represents minimum integer as integer node in JS AST. Treat + JS AST as unary node (+) containing single number literal --- .../com/google/gwt/dev/js/JsAstMapper.java | 32 +++++++++++-------- .../google/gwt/dev/js/rhino/IRFactory.java | 4 +-- .../src/com/google/gwt/dev/js/rhino/Node.java | 16 +++------- .../com/google/gwt/dev/js/rhino/Parser.java | 6 ++-- .../google/gwt/dev/js/rhino/TokenStream.java | 2 +- 5 files changed, 28 insertions(+), 32 deletions(-) diff --git a/js/js.parser/src/com/google/gwt/dev/js/JsAstMapper.java b/js/js.parser/src/com/google/gwt/dev/js/JsAstMapper.java index b1f8d2bd73a..b2cb01e4ae0 100644 --- a/js/js.parser/src/com/google/gwt/dev/js/JsAstMapper.java +++ b/js/js.parser/src/com/google/gwt/dev/js/JsAstMapper.java @@ -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 withLocation(T astNode, Node node) { CodePosition location = node.getPosition(); if (location != null) { diff --git a/js/js.parser/src/com/google/gwt/dev/js/rhino/IRFactory.java b/js/js.parser/src/com/google/gwt/dev/js/rhino/IRFactory.java index 1cd57442cdf..32b66fda0fb 100644 --- a/js/js.parser/src/com/google/gwt/dev/js/rhino/IRFactory.java +++ b/js/js.parser/src/com/google/gwt/dev/js/rhino/IRFactory.java @@ -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) { diff --git a/js/js.parser/src/com/google/gwt/dev/js/rhino/Node.java b/js/js.parser/src/com/google/gwt/dev/js/rhino/Node.java index fbf1a3b95f1..440f33131b5 100644 --- a/js/js.parser/src/com/google/gwt/dev/js/rhino/Node.java +++ b/js/js.parser/src/com/google/gwt/dev/js/rhino/Node.java @@ -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) { diff --git a/js/js.parser/src/com/google/gwt/dev/js/rhino/Parser.java b/js/js.parser/src/com/google/gwt/dev/js/rhino/Parser.java index 7ab3be9429d..cf38c55245e 100644 --- a/js/js.parser/src/com/google/gwt/dev/js/rhino/Parser.java +++ b/js/js.parser/src/com/google/gwt/dev/js/rhino/Parser.java @@ -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(); diff --git a/js/js.parser/src/com/google/gwt/dev/js/rhino/TokenStream.java b/js/js.parser/src/com/google/gwt/dev/js/rhino/TokenStream.java index 8464f7fba2f..52c49a10300 100644 --- a/js/js.parser/src/com/google/gwt/dev/js/rhino/TokenStream.java +++ b/js/js.parser/src/com/google/gwt/dev/js/rhino/TokenStream.java @@ -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; }