8185252: Unary minus and plus use wrong node Kind
Reviewed-by: sundar, hannesw
This commit is contained in:
parent
4b359d10e4
commit
25eea31231
@ -75,6 +75,8 @@ abstract class TreeImpl implements Tree {
|
||||
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 @@ abstract class TreeImpl implements Tree {
|
||||
return Kind.POSTFIX_INCREMENT;
|
||||
case ASSIGN_ADD:
|
||||
return Kind.PLUS_ASSIGNMENT;
|
||||
case NEG:
|
||||
return Kind.UNARY_MINUS;
|
||||
case SUB:
|
||||
return Kind.MINUS;
|
||||
case DECPREFIX:
|
||||
|
@ -1027,7 +1027,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enterSUB(final UnaryNode unaryNode) {
|
||||
public boolean enterNEG(final UnaryNode unaryNode) {
|
||||
loadSUB(unaryNode, resultBounds);
|
||||
return false;
|
||||
}
|
||||
@ -1105,7 +1105,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enterADD(final UnaryNode unaryNode) {
|
||||
public boolean enterPOS(final UnaryNode unaryNode) {
|
||||
loadADD(unaryNode, resultBounds);
|
||||
return false;
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ final class FoldConstants extends SimpleNodeVisitor implements Loggable {
|
||||
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 @@ final class FoldConstants extends SimpleNodeVisitor implements Loggable {
|
||||
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) {
|
||||
|
@ -317,7 +317,7 @@ final class WeighNodes extends NodeOperatorVisitor<LexicalContext> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node leaveADD(final UnaryNode unaryNode) {
|
||||
public Node leavePOS(final UnaryNode unaryNode) {
|
||||
return unaryNodeWeight(unaryNode);
|
||||
}
|
||||
|
||||
@ -348,7 +348,7 @@ final class WeighNodes extends NodeOperatorVisitor<LexicalContext> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node leaveSUB(final UnaryNode unaryNode) {
|
||||
public Node leaveNEG(final UnaryNode unaryNode) {
|
||||
return unaryNodeWeight(unaryNode);
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,8 @@ public final class UnaryNode extends Expression implements Assignment<Expression
|
||||
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 @@ public final class UnaryNode extends Expression implements Assignment<Expression
|
||||
@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 @@ public final class UnaryNode extends Expression implements Assignment<Expression
|
||||
}
|
||||
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 @@ public final class UnaryNode extends Expression implements Assignment<Expression
|
||||
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();
|
||||
|
@ -47,8 +47,8 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
@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 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
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 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
@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 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
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 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
* @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 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
* @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 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
* @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 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
* @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);
|
||||
}
|
||||
|
||||
|
@ -4391,10 +4391,15 @@ public class Parser extends AbstractParser implements Loggable {
|
||||
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();
|
||||
|
@ -63,10 +63,12 @@ public enum TokenType {
|
||||
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),
|
||||
|
114
nashorn/test/script/nosecurity/JDK-8185252.js
Normal file
114
nashorn/test/script/nosecurity/JDK-8185252.js
Normal file
@ -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))
|
||||
}
|
||||
})))
|
24
nashorn/test/script/nosecurity/JDK-8185252.js.EXPECTED
Normal file
24
nashorn/test/script/nosecurity/JDK-8185252.js.EXPECTED
Normal file
@ -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"
|
||||
}
|
||||
]
|
@ -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",
|
||||
|
@ -75,8 +75,8 @@ in visitUnary POSTFIX_INCREMENT x
|
||||
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
|
||||
|
@ -73,7 +73,7 @@
|
||||
"startPosition": "121"
|
||||
},
|
||||
"endPosition": "122",
|
||||
"kind": "MINUS",
|
||||
"kind": "UNARY_MINUS",
|
||||
"startPosition": "120"
|
||||
},
|
||||
"startPosition": "114"
|
||||
|
@ -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"
|
||||
},
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user