author | sdama |
Mon, 14 Nov 2016 22:33:33 -0800 | |
changeset 41983 | eb674141ab03 |
parent 41982 | d7226731ac08 |
child 41984 | 8b4d9196a120 |
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IRTranslator.java Fri Nov 11 18:56:37 2016 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IRTranslator.java Mon Nov 14 22:33:33 2016 -0800 @@ -384,7 +384,7 @@ final List<CatchTreeImpl> catchTrees = new ArrayList<>(catchNodes.size()); for (final CatchNode catchNode : catchNodes) { catchTrees.add(new CatchTreeImpl(catchNode, - translateIdent(catchNode.getException()), + translateExpr(catchNode.getException()), (BlockTree) translateBlock(catchNode.getBody()), translateExpr(catchNode.getExceptionCondition()))); }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java Fri Nov 11 18:56:37 2016 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java Mon Nov 14 22:33:33 2016 -0800 @@ -462,7 +462,7 @@ @Override public boolean enterCatchNode(final CatchNode catchNode) { - final IdentNode exception = catchNode.getException(); + final IdentNode exception = catchNode.getExceptionIdentifier(); final Block block = lc.getCurrentBlock(); start(catchNode);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Fri Nov 11 18:56:37 2016 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Mon Nov 14 22:33:33 2016 -0800 @@ -3255,7 +3255,7 @@ enterBlock(catchBlock); final CatchNode catchNode = (CatchNode)catchBlocks.get(i).getStatements().get(0); - final IdentNode exception = catchNode.getException(); + final IdentNode exception = catchNode.getExceptionIdentifier(); final Expression exceptionCondition = catchNode.getExceptionCondition(); final Block catchBody = catchNode.getBody();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java Fri Nov 11 18:56:37 2016 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java Mon Nov 14 22:33:33 2016 -0800 @@ -1053,7 +1053,7 @@ joinOnLabel(catchLabel); for(final CatchNode catchNode: tryNode.getCatches()) { - final IdentNode exception = catchNode.getException(); + final IdentNode exception = catchNode.getExceptionIdentifier(); onAssignment(exception, LvarType.OBJECT); final Expression condition = catchNode.getExceptionCondition(); if(condition != null) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java Fri Nov 11 18:56:37 2016 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java Mon Nov 14 22:33:33 2016 -0800 @@ -178,6 +178,15 @@ } @Override + public boolean enterCatchNode(final CatchNode catchNode) { + Expression exception = catchNode.getException(); + if ((exception != null) && !(exception instanceof IdentNode)) { + throwNotImplementedYet("es6.destructuring", exception); + } + return true; + } + + @Override public Node leaveCatchNode(final CatchNode catchNode) { return addStatement(catchNode); }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/CatchNode.java Fri Nov 11 18:56:37 2016 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/CatchNode.java Mon Nov 14 22:33:33 2016 -0800 @@ -35,8 +35,8 @@ public final class CatchNode extends Statement { private static final long serialVersionUID = 1L; - /** Exception identifier. */ - private final IdentNode exception; + /** Exception binding identifier or binding pattern. */ + private final Expression exception; /** Exception condition. */ private final Expression exceptionCondition; @@ -52,21 +52,27 @@ * @param lineNumber lineNumber * @param token token * @param finish finish - * @param exception variable name of exception + * @param exception variable name or pattern of exception * @param exceptionCondition exception condition * @param body catch body * @param isSyntheticRethrow true if this node is a synthetically generated rethrow node. */ - public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, + public CatchNode(final int lineNumber, final long token, final int finish, final Expression exception, final Expression exceptionCondition, final Block body, final boolean isSyntheticRethrow) { super(lineNumber, token, finish); - this.exception = exception == null ? null : exception.setIsInitializedHere(); + if (exception instanceof IdentNode) { + this.exception = ((IdentNode) exception).setIsInitializedHere(); + } else if ((exception instanceof LiteralNode.ArrayLiteralNode) || (exception instanceof ObjectNode)) { + this.exception = exception; + } else { + throw new IllegalArgumentException("invalid catch parameter"); + } this.exceptionCondition = exceptionCondition; - this.body = body; + this.body = body; this.isSyntheticRethrow = isSyntheticRethrow; } - private CatchNode(final CatchNode catchNode, final IdentNode exception, final Expression exceptionCondition, + private CatchNode(final CatchNode catchNode, final Expression exception, final Expression exceptionCondition, final Block body, final boolean isSyntheticRethrow) { super(catchNode); this.exception = exception; @@ -83,11 +89,10 @@ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { if (visitor.enterCatchNode(this)) { return visitor.leaveCatchNode( - setException((IdentNode)exception.accept(visitor)). - setExceptionCondition(exceptionCondition == null ? null : (Expression)exceptionCondition.accept(visitor)). - setBody((Block)body.accept(visitor))); + setException((Expression) exception.accept(visitor)). + setExceptionCondition(exceptionCondition == null ? null : (Expression) exceptionCondition.accept(visitor)). + setBody((Block) body.accept(visitor))); } - return this; } @@ -109,14 +114,25 @@ } /** - * Get the identifier representing the exception thrown - * @return the exception identifier + * Get the binding pattern representing the exception thrown + * + * @return the exception binding pattern */ - public IdentNode getException() { + public Expression getException() { return exception; } /** + * Get the identifier representing the exception thrown + * + * @return the exception identifier + * @throws ClassCastException if exception set is not binding identifier + */ + public IdentNode getExceptionIdentifier() { + return (IdentNode) exception; + } + + /** * Get the exception condition for this catch block * @return the exception condition */ @@ -146,13 +162,19 @@ /** * Resets the exception of a catch block - * @param exception new exception + * + * @param exception new exception which can be binding identifier or binding + * pattern * @return new catch node if changed, same otherwise */ - public CatchNode setException(final IdentNode exception) { + public CatchNode setException(final Expression exception) { if (this.exception == exception) { return this; } + /*check if exception is legitimate*/ + if (!((exception instanceof IdentNode) || (exception instanceof LiteralNode.ArrayLiteralNode) || (exception instanceof ObjectNode))) { + throw new IllegalArgumentException("invalid catch parameter"); + } return new CatchNode(this, exception, exceptionCondition, body, isSyntheticRethrow); }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Fri Nov 11 18:56:37 2016 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Mon Nov 14 22:33:33 2016 -0800 @@ -2619,13 +2619,23 @@ next(); expect(LPAREN); - // FIXME: ES6 catch parameter can be a BindingIdentifier or a BindingPattern - // We need to generalize this here! + // ES6 catch parameter can be a BindingIdentifier or a BindingPattern // http://www.ecma-international.org/ecma-262/6.0/ - final IdentNode exception = getIdent(); - - // ECMA 12.4.1 strict mode restrictions - verifyStrictIdent(exception, "catch argument"); + final String contextString = "catch argument"; + final Expression exception = bindingIdentifierOrPattern(contextString); + final boolean isDestructuring = !(exception instanceof IdentNode); + if (isDestructuring) { + verifyDestructuringBindingPattern(exception, new Consumer<IdentNode>() { + @Override + public void accept(final IdentNode identNode) { + verifyIdent(identNode, contextString); + } + }); + } else { + // ECMA 12.4.1 strict mode restrictions + verifyStrictIdent((IdentNode) exception, "catch argument"); + } + // Nashorn extension: catch clause can have optional // condition. So, a single try can have more than one
--- a/nashorn/test/script/basic/es6/destructuring.js Fri Nov 11 18:56:37 2016 +0100 +++ b/nashorn/test/script/basic/es6/destructuring.js Mon Nov 14 22:33:33 2016 -0800 @@ -62,4 +62,11 @@ check("(function([x]) { return x; })()"); check("for (var [[x, y, z] = [4, 5, 6]] = [7, 8, 9]; iterCount < 1; ) ;"); check("for ([ arrow = () => {} ] of [[]]) ;"); +check("try { throw null;} catch({}) { }"); +check("try { throw {} } catch ({}) { }"); +check("try { throw [] } catch ([,]) { }"); +check("try { throw { w: [7, undefined, ] }} catch ({ w: [x, y, z] = [4, 5, 6] }) { }"); +check("try { throw { a: 2, b: 3} } catch ({a, b}) { }"); +check("try { throw [null] } catch ([[x]]) { }"); +check("try { throw { w: undefined } } catch ({ w: { x, y, z } = { x: 4, y: 5, z: 6 } }) { }");
--- a/nashorn/test/script/basic/es6/destructuring.js.EXPECTED Fri Nov 11 18:56:37 2016 +0100 +++ b/nashorn/test/script/basic/es6/destructuring.js.EXPECTED Mon Nov 14 22:33:33 2016 -0800 @@ -70,3 +70,24 @@ java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:0 ES6 destructuring is not yet implemented for ([ arrow = () => {} ] of [[]]) ; ^ +java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:25 ES6 destructuring is not yet implemented +try { throw null;} catch({}) { } + ^ +java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:24 ES6 destructuring is not yet implemented +try { throw {} } catch ({}) { } + ^ +java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:24 ES6 destructuring is not yet implemented +try { throw [] } catch ([,]) { } + ^ +java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:44 ES6 destructuring is not yet implemented +try { throw { w: [7, undefined, ] }} catch ({ w: [x, y, z] = [4, 5, 6] }) { } + ^ +java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:35 ES6 destructuring is not yet implemented +try { throw { a: 2, b: 3} } catch ({a, b}) { } + ^ +java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:28 ES6 destructuring is not yet implemented +try { throw [null] } catch ([[x]]) { } + ^ +java.lang.RuntimeException: test/script/basic/es6/destructuring.js#35:6<eval>:1:38 ES6 destructuring is not yet implemented +try { throw { w: undefined } } catch ({ w: { x, y, z } = { x: 4, y: 5, z: 6 } }) { } + ^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/nosecurity/treeapi/destructuring_catch.js Mon Nov 14 22:33:33 2016 -0800 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, 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. + */ + +/** + * Tests to check representation of ES6 catch parameter as binding pattern. + * + * @test + * @option -scripting + * @run + */ + +load(__DIR__ + "utils.js") + +var code = <<EOF + +try { throw null;} catch({}) { } +try { throw {} } catch ({}) { } +try { throw [] } catch ([,]) { } +try { throw { w: [7, undefined, ] }} catch ({ w: [x, y, z] = [4, 5, 6] }) { } +try { throw { a: 2, b: 3} } catch ({a, b}) { } +try { throw [null] } catch ([[x]]) { } +try { throw { w: undefined } } catch ({ w: { x, y, z } = { x: 4, y: 5, z: 6 } }) { } + +EOF + +parse("destructuring_catch.js", code, "--language=es6", new (Java.extend(visitor_es6, { + visitCatch : function (node, obj) { + obj.push(convert(node)) + } +}))) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/nosecurity/treeapi/destructuring_catch.js.EXPECTED Mon Nov 14 22:33:33 2016 -0800 @@ -0,0 +1,399 @@ +[ + { + "condition": "null", + "endPosition": "33", + "kind": "CATCH", + "parameter": { + "endPosition": "28", + "kind": "OBJECT_LITERAL", + "startPosition": "26", + "properties": [] + }, + "block": { + "endPosition": "33", + "kind": "BLOCK", + "statements": [], + "startPosition": "30" + }, + "startPosition": "20" + }, + { + "condition": "null", + "endPosition": "65", + "kind": "CATCH", + "parameter": { + "endPosition": "60", + "kind": "OBJECT_LITERAL", + "startPosition": "58", + "properties": [] + }, + "block": { + "endPosition": "65", + "kind": "BLOCK", + "statements": [], + "startPosition": "62" + }, + "startPosition": "51" + }, + { + "condition": "null", + "endPosition": "98", + "kind": "CATCH", + "parameter": { + "endPosition": "93", + "kind": "ARRAY_LITERAL", + "elements": [ + null + ], + "startPosition": "90" + }, + "block": { + "endPosition": "98", + "kind": "BLOCK", + "statements": [], + "startPosition": "95" + }, + "startPosition": "83" + }, + { + "condition": "null", + "endPosition": "176", + "kind": "CATCH", + "parameter": { + "endPosition": "171", + "kind": "OBJECT_LITERAL", + "startPosition": "143", + "properties": [ + { + "getter": "null", + "endPosition": "169", + "kind": "PROPERTY", + "setter": "null", + "value": { + "expression": { + "endPosition": "169", + "kind": "ARRAY_LITERAL", + "elements": [ + { + "endPosition": "162", + "kind": "NUMBER_LITERAL", + "value": "4", + "startPosition": "161" + }, + { + "endPosition": "165", + "kind": "NUMBER_LITERAL", + "value": "5", + "startPosition": "164" + }, + { + "endPosition": "168", + "kind": "NUMBER_LITERAL", + "value": "6", + "startPosition": "167" + } + ], + "startPosition": "160" + }, + "endPosition": "169", + "kind": "ASSIGNMENT", + "variable": { + "endPosition": "157", + "kind": "ARRAY_LITERAL", + "elements": [ + { + "endPosition": "150", + "kind": "IDENTIFIER", + "name": "x", + "startPosition": "149" + }, + { + "endPosition": "153", + "kind": "IDENTIFIER", + "name": "y", + "startPosition": "152" + }, + { + "endPosition": "156", + "kind": "IDENTIFIER", + "name": "z", + "startPosition": "155" + } + ], + "startPosition": "148" + }, + "startPosition": "148" + }, + "startPosition": "145", + "key": { + "endPosition": "146", + "kind": "IDENTIFIER", + "name": "w", + "startPosition": "145" + } + } + ] + }, + "block": { + "endPosition": "176", + "kind": "BLOCK", + "statements": [], + "startPosition": "173" + }, + "startPosition": "136" + }, + { + "condition": "null", + "endPosition": "223", + "kind": "CATCH", + "parameter": { + "endPosition": "218", + "kind": "OBJECT_LITERAL", + "startPosition": "212", + "properties": [ + { + "getter": "null", + "endPosition": "214", + "kind": "PROPERTY", + "setter": "null", + "value": { + "endPosition": "214", + "kind": "IDENTIFIER", + "name": "a", + "startPosition": "213" + }, + "startPosition": "213", + "key": { + "endPosition": "214", + "kind": "IDENTIFIER", + "name": "a", + "startPosition": "213" + } + }, + { + "getter": "null", + "endPosition": "217", + "kind": "PROPERTY", + "setter": "null", + "value": { + "endPosition": "217", + "kind": "IDENTIFIER", + "name": "b", + "startPosition": "216" + }, + "startPosition": "216", + "key": { + "endPosition": "217", + "kind": "IDENTIFIER", + "name": "b", + "startPosition": "216" + } + } + ] + }, + "block": { + "endPosition": "223", + "kind": "BLOCK", + "statements": [], + "startPosition": "220" + }, + "startPosition": "205" + }, + { + "condition": "null", + "endPosition": "262", + "kind": "CATCH", + "parameter": { + "endPosition": "257", + "kind": "ARRAY_LITERAL", + "elements": [ + { + "endPosition": "256", + "kind": "ARRAY_LITERAL", + "elements": [ + { + "endPosition": "255", + "kind": "IDENTIFIER", + "name": "x", + "startPosition": "254" + } + ], + "startPosition": "253" + } + ], + "startPosition": "252" + }, + "block": { + "endPosition": "262", + "kind": "BLOCK", + "statements": [], + "startPosition": "259" + }, + "startPosition": "245" + }, + { + "condition": "null", + "endPosition": "347", + "kind": "CATCH", + "parameter": { + "endPosition": "342", + "kind": "OBJECT_LITERAL", + "startPosition": "301", + "properties": [ + { + "getter": "null", + "endPosition": "340", + "kind": "PROPERTY", + "setter": "null", + "value": { + "expression": { + "endPosition": "340", + "kind": "OBJECT_LITERAL", + "startPosition": "320", + "properties": [ + { + "getter": "null", + "endPosition": "326", + "kind": "PROPERTY", + "setter": "null", + "value": { + "endPosition": "326", + "kind": "NUMBER_LITERAL", + "value": "4", + "startPosition": "325" + }, + "startPosition": "322", + "key": { + "endPosition": "323", + "kind": "IDENTIFIER", + "name": "x", + "startPosition": "322" + } + }, + { + "getter": "null", + "endPosition": "332", + "kind": "PROPERTY", + "setter": "null", + "value": { + "endPosition": "332", + "kind": "NUMBER_LITERAL", + "value": "5", + "startPosition": "331" + }, + "startPosition": "328", + "key": { + "endPosition": "329", + "kind": "IDENTIFIER", + "name": "y", + "startPosition": "328" + } + }, + { + "getter": "null", + "endPosition": "338", + "kind": "PROPERTY", + "setter": "null", + "value": { + "endPosition": "338", + "kind": "NUMBER_LITERAL", + "value": "6", + "startPosition": "337" + }, + "startPosition": "334", + "key": { + "endPosition": "335", + "kind": "IDENTIFIER", + "name": "z", + "startPosition": "334" + } + } + ] + }, + "endPosition": "340", + "kind": "ASSIGNMENT", + "variable": { + "endPosition": "317", + "kind": "OBJECT_LITERAL", + "startPosition": "306", + "properties": [ + { + "getter": "null", + "endPosition": "309", + "kind": "PROPERTY", + "setter": "null", + "value": { + "endPosition": "309", + "kind": "IDENTIFIER", + "name": "x", + "startPosition": "308" + }, + "startPosition": "308", + "key": { + "endPosition": "309", + "kind": "IDENTIFIER", + "name": "x", + "startPosition": "308" + } + }, + { + "getter": "null", + "endPosition": "312", + "kind": "PROPERTY", + "setter": "null", + "value": { + "endPosition": "312", + "kind": "IDENTIFIER", + "name": "y", + "startPosition": "311" + }, + "startPosition": "311", + "key": { + "endPosition": "312", + "kind": "IDENTIFIER", + "name": "y", + "startPosition": "311" + } + }, + { + "getter": "null", + "endPosition": "315", + "kind": "PROPERTY", + "setter": "null", + "value": { + "endPosition": "315", + "kind": "IDENTIFIER", + "name": "z", + "startPosition": "314" + }, + "startPosition": "314", + "key": { + "endPosition": "315", + "kind": "IDENTIFIER", + "name": "z", + "startPosition": "314" + } + } + ] + }, + "startPosition": "306" + }, + "startPosition": "303", + "key": { + "endPosition": "304", + "kind": "IDENTIFIER", + "name": "w", + "startPosition": "303" + } + } + ] + }, + "block": { + "endPosition": "347", + "kind": "BLOCK", + "statements": [], + "startPosition": "344" + }, + "startPosition": "294" + } +]