--- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeImpl.java 2017-08-10 09:08:38.553394000 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeImpl.java 2017-08-10 09:08:36.022145400 +0530 @@ -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: --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java 2017-08-10 09:09:05.055432100 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java 2017-08-10 09:09:00.382974800 +0530 @@ -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; } --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java 2017-08-10 09:09:18.074666300 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java 2017-08-10 09:09:15.974042100 +0530 @@ -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) { --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java 2017-08-10 09:09:31.760151900 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java 2017-08-10 09:09:30.292238600 +0530 @@ -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); } --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/UnaryNode.java 2017-08-10 09:09:40.773698200 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/UnaryNode.java 2017-08-10 09:09:38.867602000 +0530 @@ -58,8 +58,8 @@ private static final List 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(); --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java 2017-08-10 09:09:55.818178900 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java 2017-08-10 09:09:53.347091100 +0530 @@ -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); } --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java 2017-08-10 09:10:24.862174700 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java 2017-08-10 09:10:11.197243100 +0530 @@ -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(); --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/TokenType.java 2017-08-10 09:11:01.577833500 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/TokenType.java 2017-08-10 09:10:58.536223000 +0530 @@ -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), --- old/test/script/nosecurity/parserapi.js.EXPECTED 2017-08-10 09:11:17.190958800 +0530 +++ new/test/script/nosecurity/parserapi.js.EXPECTED 2017-08-10 09:11:14.349884100 +0530 @@ -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", --- old/test/script/nosecurity/parservisitor.js.EXPECTED 2017-08-10 09:11:35.974538900 +0530 +++ new/test/script/nosecurity/parservisitor.js.EXPECTED 2017-08-10 09:11:31.961840100 +0530 @@ -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 --- old/test/script/nosecurity/treeapi/array_access.js.EXPECTED 2017-08-10 09:11:50.986563600 +0530 +++ new/test/script/nosecurity/treeapi/array_access.js.EXPECTED 2017-08-10 09:11:48.695454400 +0530 @@ -73,7 +73,7 @@ "startPosition": "121" }, "endPosition": "122", - "kind": "MINUS", + "kind": "UNARY_MINUS", "startPosition": "120" }, "startPosition": "114" --- old/test/script/nosecurity/treeapi/unary.js.EXPECTED 2017-08-10 09:12:23.564227700 +0530 +++ new/test/script/nosecurity/treeapi/unary.js.EXPECTED 2017-08-10 09:12:19.393298200 +0530 @@ -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" }, { --- /dev/null 2017-08-10 09:12:43.000000000 +0530 +++ new/test/script/nosecurity/JDK-8185252.js 2017-08-10 09:12:40.882113700 +0530 @@ -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 = <