8185252: Unary minus and plus use wrong node Kind
Reviewed-by: sundar, hannesw
Contributed-by: priya.lakshmi.muthuswamy@oracle.com
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeImpl.java Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeImpl.java Thu Aug 10 15:19:17 2017 +0200
@@ -75,6 +75,8 @@
return Kind.MULTIPLY;
case ASSIGN_MUL:
return Kind.MULTIPLY_ASSIGNMENT;
+ case POS:
+ return Kind.UNARY_PLUS;
case ADD:
return Kind.PLUS;
case INCPREFIX:
@@ -83,6 +85,8 @@
return Kind.POSTFIX_INCREMENT;
case ASSIGN_ADD:
return Kind.PLUS_ASSIGNMENT;
+ case NEG:
+ return Kind.UNARY_MINUS;
case SUB:
return Kind.MINUS;
case DECPREFIX:
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Thu Aug 10 15:19:17 2017 +0200
@@ -1027,7 +1027,7 @@
}
@Override
- public boolean enterSUB(final UnaryNode unaryNode) {
+ public boolean enterNEG(final UnaryNode unaryNode) {
loadSUB(unaryNode, resultBounds);
return false;
}
@@ -1105,7 +1105,7 @@
}
@Override
- public boolean enterADD(final UnaryNode unaryNode) {
+ public boolean enterPOS(final UnaryNode unaryNode) {
loadADD(unaryNode, resultBounds);
return false;
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java Thu Aug 10 15:19:17 2017 +0200
@@ -231,7 +231,7 @@
LiteralNode<?> literalNode;
switch (parent.tokenType()) {
- case ADD:
+ case POS:
if (rhsInteger) {
literalNode = LiteralNode.newInstance(token, finish, rhs.getInt32());
} else if (rhsType.isLong()) {
@@ -240,7 +240,7 @@
literalNode = LiteralNode.newInstance(token, finish, rhs.getNumber());
}
break;
- case SUB:
+ case NEG:
if (rhsInteger && rhs.getInt32() != 0) { // @see test/script/basic/minuszero.js
literalNode = LiteralNode.newInstance(token, finish, -rhs.getInt32());
} else if (rhsType.isLong() && rhs.getLong() != 0L) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java Thu Aug 10 15:19:17 2017 +0200
@@ -317,7 +317,7 @@
}
@Override
- public Node leaveADD(final UnaryNode unaryNode) {
+ public Node leavePOS(final UnaryNode unaryNode) {
return unaryNodeWeight(unaryNode);
}
@@ -348,7 +348,7 @@
}
@Override
- public Node leaveSUB(final UnaryNode unaryNode) {
+ public Node leaveNEG(final UnaryNode unaryNode) {
return unaryNodeWeight(unaryNode);
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/UnaryNode.java Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/UnaryNode.java Thu Aug 10 15:19:17 2017 +0200
@@ -58,8 +58,8 @@
private static final List<TokenType> CAN_OVERFLOW =
Collections.unmodifiableList(
Arrays.asList(new TokenType[] {
- TokenType.ADD,
- TokenType.SUB, //negate
+ TokenType.POS,
+ TokenType.NEG, //negate
TokenType.DECPREFIX,
TokenType.DECPOSTFIX,
TokenType.INCPREFIX,
@@ -125,7 +125,7 @@
@Override
public Type getWidestOperationType() {
switch (tokenType()) {
- case ADD:
+ case POS:
final Type operandType = getExpression().getType();
if(operandType == Type.BOOLEAN) {
return Type.INT;
@@ -134,7 +134,7 @@
}
assert operandType.isNumeric();
return operandType;
- case SUB:
+ case NEG:
// This might seems overly conservative until you consider that -0 can only be represented as a double.
return Type.NUMBER;
case NOT:
@@ -182,8 +182,8 @@
switch (tokenType()) {
case NEW:
return false;
- case ADD:
- case SUB:
+ case POS:
+ case NEG:
case NOT:
case BIT_NOT:
return expression.isLocal() && expression.getType().isJSPrimitive();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Thu Aug 10 15:19:17 2017 +0200
@@ -47,8 +47,8 @@
@Override
public boolean enterUnaryNode(final UnaryNode unaryNode) {
switch (unaryNode.tokenType()) {
- case ADD:
- return enterADD(unaryNode);
+ case POS:
+ return enterPOS(unaryNode);
case BIT_NOT:
return enterBIT_NOT(unaryNode);
case DELETE:
@@ -57,8 +57,8 @@
return enterNEW(unaryNode);
case NOT:
return enterNOT(unaryNode);
- case SUB:
- return enterSUB(unaryNode);
+ case NEG:
+ return enterNEG(unaryNode);
case TYPEOF:
return enterTYPEOF(unaryNode);
case VOID:
@@ -76,8 +76,8 @@
@Override
public final Node leaveUnaryNode(final UnaryNode unaryNode) {
switch (unaryNode.tokenType()) {
- case ADD:
- return leaveADD(unaryNode);
+ case POS:
+ return leavePOS(unaryNode);
case BIT_NOT:
return leaveBIT_NOT(unaryNode);
case DELETE:
@@ -86,8 +86,8 @@
return leaveNEW(unaryNode);
case NOT:
return leaveNOT(unaryNode);
- case SUB:
- return leaveSUB(unaryNode);
+ case NEG:
+ return leaveNEG(unaryNode);
case TYPEOF:
return leaveTYPEOF(unaryNode);
case VOID:
@@ -280,7 +280,7 @@
* @param unaryNode the node
* @return true if traversal should continue and node children be traversed, false otherwise
*/
- public boolean enterADD(final UnaryNode unaryNode) {
+ public boolean enterPOS(final UnaryNode unaryNode) {
return enterDefault(unaryNode);
}
@@ -290,7 +290,7 @@
* @param unaryNode the node
* @return processed node, which will replace the original one, or the original node
*/
- public Node leaveADD(final UnaryNode unaryNode) {
+ public Node leavePOS(final UnaryNode unaryNode) {
return leaveDefault(unaryNode);
}
@@ -400,7 +400,7 @@
* @param unaryNode the node
* @return true if traversal should continue and node children be traversed, false otherwise
*/
- public boolean enterSUB(final UnaryNode unaryNode) {
+ public boolean enterNEG(final UnaryNode unaryNode) {
return enterDefault(unaryNode);
}
@@ -410,7 +410,7 @@
* @param unaryNode the node
* @return processed node, which will replace the original one, or the original node
*/
- public Node leaveSUB(final UnaryNode unaryNode) {
+ public Node leaveNEG(final UnaryNode unaryNode) {
return leaveDefault(unaryNode);
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Thu Aug 10 15:19:17 2017 +0200
@@ -4391,10 +4391,15 @@
appendStatement(new ExpressionStatement(unaryLine, unaryToken, finish, expr));
return LiteralNode.newInstance(unaryToken, finish, true);
}
+ case ADD:
+ case SUB: {
+ final TokenType opType = type;
+ next();
+ final Expression expr = unaryExpression();
+ return new UnaryNode(Token.recast(unaryToken, (opType == TokenType.ADD) ? TokenType.POS : TokenType.NEG), expr);
+ }
case VOID:
case TYPEOF:
- case ADD:
- case SUB:
case BIT_NOT:
case NOT:
next();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/TokenType.java Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/TokenType.java Thu Aug 10 15:19:17 2017 +0200
@@ -63,10 +63,12 @@
RPAREN (BRACKET, ")", 0, true),
MUL (BINARY, "*", 13, true),
ASSIGN_MUL (BINARY, "*=", 2, false),
+ POS (UNARY, "+", 14, false),
ADD (BINARY, "+", 12, true),
INCPREFIX (UNARY, "++", 15, true),
ASSIGN_ADD (BINARY, "+=", 2, false),
COMMARIGHT (BINARY, ",", 1, true),
+ NEG (UNARY, "-", 14, false),
SUB (BINARY, "-", 12, true),
DECPREFIX (UNARY, "--", 15, true),
ASSIGN_SUB (BINARY, "-=", 2, false),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/nosecurity/JDK-8185252.js Thu Aug 10 15:19:17 2017 +0200
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Test that Unary minus and plus uses UNARY_MINUS and UNARY_PLUS node Kind
+ *
+ * @test
+ * @bug 8185252
+ * @option -scripting
+ * @run
+ */
+
+var parser = Java.type('jdk.nashorn.api.tree.Parser');
+var tree = Java.type('jdk.nashorn.api.tree.Tree');
+var list = Java.type('java.util.List');
+var visitor = Java.type('jdk.nashorn.api.tree.SimpleTreeVisitorES5_1');
+var cls = Java.type('java.lang.Class')
+
+function convert (value) {
+ if (!value || typeof(value) != 'object') {
+ return value;
+ }
+ var obj = Object.bindProperties({}, value)
+ var result = {}
+ for (var i in obj) {
+ if (i == "lineMap") {
+ continue;
+ }
+
+ var val = obj[i]
+ // skip these ES6 specific properties to reduce noise
+ // in the output - unless there were set to true
+ if (typeof(val) == 'boolean' && val == false) {
+ switch (i) {
+ case "computed":
+ case "static":
+ case "restParameter":
+ case "this":
+ case "super":
+ case "star":
+ case "default":
+ case "starDefaultStar":
+ case "arrow":
+ case "generator":
+ case "let":
+ case "const":
+ continue;
+ }
+ }
+
+ if (typeof(val) == 'object') {
+ if (val instanceof cls) {
+ continue;
+ }
+ if (val instanceof tree) {
+ result[i] = convert(val)
+ }
+ else if (val instanceof list) {
+ var lst = []
+ for (var j in val) {
+ lst.push(convert(val[j]))
+ }
+ result[i] = lst
+ }
+ else {
+ result[i] = String(val)
+ }
+ } else if (typeof(val) != 'function') {
+ result[i] = String(val)
+ }
+ }
+ return result
+}
+
+function parse(name, code, args, visitor, listener) {
+ var tree = parser.create(args).parse(name, code, listener || null)
+ var results = []
+ tree.accept(visitor, results)
+ print(JSON.stringify(results, null, 2))
+}
+
+
+var code = <<EOF
+
++1;
+-1;
+
+EOF
+
+parse("JDK-8185252.js", code, "-nse", new (Java.extend(visitor, {
+ visitUnary: function (node, obj) {
+ obj.push(convert(node))
+ }
+})))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/nosecurity/JDK-8185252.js.EXPECTED Thu Aug 10 15:19:17 2017 +0200
@@ -0,0 +1,24 @@
+[
+ {
+ "expression": {
+ "endPosition": "3",
+ "kind": "NUMBER_LITERAL",
+ "value": "1",
+ "startPosition": "2"
+ },
+ "endPosition": "3",
+ "kind": "UNARY_PLUS",
+ "startPosition": "1"
+ },
+ {
+ "expression": {
+ "endPosition": "7",
+ "kind": "NUMBER_LITERAL",
+ "value": "1",
+ "startPosition": "6"
+ },
+ "endPosition": "7",
+ "kind": "UNARY_MINUS",
+ "startPosition": "5"
+ }
+]
--- a/nashorn/test/script/nosecurity/parserapi.js.EXPECTED Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/test/script/nosecurity/parserapi.js.EXPECTED Thu Aug 10 15:19:17 2017 +0200
@@ -3983,7 +3983,7 @@
"startPosition": "1164"
},
"endPosition": "1165",
- "kind": "PLUS",
+ "kind": "UNARY_PLUS",
"startPosition": "1163"
},
"endPosition": "1165",
@@ -3999,7 +3999,7 @@
"startPosition": "1168"
},
"endPosition": "1169",
- "kind": "MINUS",
+ "kind": "UNARY_MINUS",
"startPosition": "1167"
},
"endPosition": "1169",
--- a/nashorn/test/script/nosecurity/parservisitor.js.EXPECTED Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/test/script/nosecurity/parservisitor.js.EXPECTED Thu Aug 10 15:19:17 2017 +0200
@@ -75,8 +75,8 @@
in visitUnary POSTFIX_DECREMENT x
in visitUnary PREFIX_INCREMENT x
in visitUnary PREFIX_DECREMENT x
-in visitUnary PLUS x
-in visitUnary MINUS x
+in visitUnary UNARY_PLUS x
+in visitUnary UNARY_MINUS x
in visitUnary BITWISE_COMPLEMENT x
in visitUnary LOGICAL_COMPLEMENT x
in visitUnary DELETE x
--- a/nashorn/test/script/nosecurity/treeapi/array_access.js.EXPECTED Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/test/script/nosecurity/treeapi/array_access.js.EXPECTED Thu Aug 10 15:19:17 2017 +0200
@@ -73,7 +73,7 @@
"startPosition": "121"
},
"endPosition": "122",
- "kind": "MINUS",
+ "kind": "UNARY_MINUS",
"startPosition": "120"
},
"startPosition": "114"
--- a/nashorn/test/script/nosecurity/treeapi/unary.js.EXPECTED Tue Aug 08 22:52:18 2017 +0000
+++ b/nashorn/test/script/nosecurity/treeapi/unary.js.EXPECTED Thu Aug 10 15:19:17 2017 +0200
@@ -84,7 +84,7 @@
"startPosition": "50"
},
"endPosition": "51",
- "kind": "PLUS",
+ "kind": "UNARY_PLUS",
"startPosition": "49"
},
{
@@ -95,7 +95,7 @@
"startPosition": "54"
},
"endPosition": "55",
- "kind": "MINUS",
+ "kind": "UNARY_MINUS",
"startPosition": "53"
},
{