diff --git a/es2panda/compiler/base/destructuring.cpp b/es2panda/compiler/base/destructuring.cpp index 5761a021774bc9898ddb012a2f56585f9e508ed6..24af709a12260bfcd9baccc121e49c44c0a381e8 100644 --- a/es2panda/compiler/base/destructuring.cpp +++ b/es2panda/compiler/base/destructuring.cpp @@ -99,9 +99,11 @@ static void GenArray(PandaGen *pg, const ir::ArrayExpression *array) const ir::Expression *init = nullptr; const ir::Expression *target = element; - if (element->IsAssignmentPattern()) { - target = element->AsAssignmentPattern()->Left(); - init = element->AsAssignmentPattern()->Right(); + if (element->IsAssignmentPattern() || element->IsAssignmentExpression()) { + auto *assignment = element->IsAssignmentPattern() ? element->AsAssignmentPattern() : + element->AsAssignmentExpression(); + target = assignment->Left(); + init = assignment->Right(); } LReference lref = LReference::CreateLRef(pg, target, array->IsDeclaration()); @@ -157,9 +159,11 @@ static void GenObjectProperty(PandaGen *pg, const ir::ObjectExpression *object, const ir::Expression *key = propExpr->Key(); const ir::Expression *target = propExpr->Value(); - if (target->IsAssignmentPattern()) { - init = target->AsAssignmentPattern()->Right(); - target = target->AsAssignmentPattern()->Left(); + if (target->IsAssignmentPattern() || target->IsAssignmentExpression()) { + auto *assignment = target->IsAssignmentPattern() ? target->AsAssignmentPattern() : + target->AsAssignmentExpression(); + init = assignment->Right(); + target = assignment->Left(); } // compile key @@ -249,10 +253,14 @@ void Destructuring::Compile(PandaGen *pg, const ir::Expression *pattern) VReg rhs = pg->AllocReg(); pg->StoreAccumulator(pattern, rhs); - if (pattern->IsArrayPattern()) { - GenArray(pg, pattern->AsArrayPattern()); + if (pattern->IsArrayPattern() || pattern->IsArrayExpression()) { + auto *arrExpr = pattern->IsArrayPattern() ? pattern->AsArrayPattern() : + pattern->AsArrayExpression(); + GenArray(pg, arrExpr); } else { - GenObject(pg, pattern->AsObjectPattern(), rhs); + auto *objExpr = pattern->IsObjectPattern() ? pattern->AsObjectPattern() : + pattern->AsObjectExpression(); + GenObject(pg, objExpr, rhs); } pg->LoadAccumulator(pattern, rhs); diff --git a/es2panda/compiler/base/lreference.cpp b/es2panda/compiler/base/lreference.cpp index 53587e65b47a252c5401b6862c5ad985967a41de..e354250c806f0b54f04ab2943601459853c9618b 100644 --- a/es2panda/compiler/base/lreference.cpp +++ b/es2panda/compiler/base/lreference.cpp @@ -114,7 +114,9 @@ LReference LReference::CreateLRef(PandaGen *pg, const ir::AstNode *node, bool is return LReference::CreateLRef(pg, node->AsVariableDeclarator()->Id(), true); } case ir::AstNodeType::ARRAY_PATTERN: - case ir::AstNodeType::OBJECT_PATTERN: { + case ir::AstNodeType::OBJECT_PATTERN: + case ir::AstNodeType::ARRAY_EXPRESSION: + case ir::AstNodeType::OBJECT_EXPRESSION: { return {node, pg, isDeclaration, ReferenceKind::DESTRUCTURING, {}}; } case ir::AstNodeType::ASSIGNMENT_PATTERN: { diff --git a/es2panda/parser/statementParser.cpp b/es2panda/parser/statementParser.cpp index d32213d971df572ace95dd4eb2644f92b8feb5cb..1768922cea834796c89dc5d592a864884f6be1ba 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -962,7 +962,7 @@ ir::ContinueStatement *ParserImpl::ParseContinueStatement() const auto &label = lexer_->GetToken().Ident(); const ParserContext *labelCtx = context_.FindLabel(label); - if (!labelCtx || !(labelCtx->Status() & ParserStatus::IN_ITERATION) || + if (!labelCtx || !(labelCtx->Status() & (ParserStatus::IN_ITERATION | ParserStatus::IN_LABELED)) || (labelCtx->Status() & ParserStatus::DISALLOW_CONTINUE)) { ThrowSyntaxError("Undefined label"); } @@ -1256,7 +1256,8 @@ std::tuple ThrowSyntaxError("Unexpected token"); } - ir::Expression *expr = ParseAssignmentExpression(leftNode); + exprFlags &= ExpressionParseFlags::POTENTIALLY_IN_PATTERN; + ir::Expression *expr = ParseAssignmentExpression(leftNode, exprFlags); if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { initNode = ParseSequenceExpression(expr); @@ -1402,6 +1403,9 @@ ir::Statement *ParserImpl::ParseForStatement() std::tie(rightNode, updateNode) = ParseForUpdate(isAwait); } else if (leftNode) { // initNode was parsed as LHS + if (leftNode->IsArrayExpression() || leftNode->IsObjectExpression()) { + exprFlags |= ExpressionParseFlags::POTENTIALLY_IN_PATTERN; + } std::tie(forKind, initNode, rightNode, updateNode) = ParseForInOf(leftNode, exprFlags, isAwait); } else if (initNode) { // initNode was parsed as VariableDeclaration and declaration size = 1 diff --git a/es2panda/test/compiler/js/language/destructuring/test-array-expr-destructring-in-for-expected.txt b/es2panda/test/compiler/js/language/destructuring/test-array-expr-destructring-in-for-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..fad30353bb1bdda6e3602542e5b0ecdab3f48352 --- /dev/null +++ b/es2panda/test/compiler/js/language/destructuring/test-array-expr-destructring-in-for-expected.txt @@ -0,0 +1,2 @@ +mower +mower diff --git a/es2panda/test/compiler/js/language/destructuring/test-array-expr-destructring-in-for.js b/es2panda/test/compiler/js/language/destructuring/test-array-expr-destructring-in-for.js new file mode 100644 index 0000000000000000000000000000000000000000..4cf992e1b1c3aa0c5344a96d0b2f35f525b30288 --- /dev/null +++ b/es2panda/test/compiler/js/language/destructuring/test-array-expr-destructring-in-for.js @@ -0,0 +1,11 @@ +let robotA = [1, "mower", "mowing"]; +let i = undefined; +let nameA = undefined; + +for ([, nameA] = robotA, i = 0; i < 1; i++) { + print(nameA); +} + +for ([, nameA = "name"] = robotA, i = 0; i < 1; i++) { + print(nameA); +} diff --git a/es2panda/test/compiler/js/language/destructuring/test-obj-expr-destructring-in-for-expected.txt b/es2panda/test/compiler/js/language/destructuring/test-obj-expr-destructring-in-for-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..fad30353bb1bdda6e3602542e5b0ecdab3f48352 --- /dev/null +++ b/es2panda/test/compiler/js/language/destructuring/test-obj-expr-destructring-in-for-expected.txt @@ -0,0 +1,2 @@ +mower +mower diff --git a/es2panda/test/compiler/js/language/destructuring/test-obj-expr-destructring-in-for.js b/es2panda/test/compiler/js/language/destructuring/test-obj-expr-destructring-in-for.js new file mode 100644 index 0000000000000000000000000000000000000000..6c8d0204c086571c2c5f47feb8c0ede837b3078e --- /dev/null +++ b/es2panda/test/compiler/js/language/destructuring/test-obj-expr-destructring-in-for.js @@ -0,0 +1,11 @@ +let robotA = {name: "mower", skill: "mowing"}; +let i = undefined; +let nameA = undefined; + +for ({name: nameA} = robotA, i = 0; i < 1; i++) { + print(nameA); +} + +for ({name: nameA = "name"} = robotA, i = 0; i < 1; i++) { + print(nameA); +} diff --git a/es2panda/test/compiler/js/language/statements/labeled/test-labeled-iteration-continue-target-expected.txt b/es2panda/test/compiler/js/language/statements/labeled/test-labeled-iteration-continue-target-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..9766475a4185a151dc9d56d614ffb9aaea3bfd42 --- /dev/null +++ b/es2panda/test/compiler/js/language/statements/labeled/test-labeled-iteration-continue-target-expected.txt @@ -0,0 +1 @@ +ok diff --git a/es2panda/test/compiler/js/language/statements/labeled/test-labeled-iteration-continue-target.js b/es2panda/test/compiler/js/language/statements/labeled/test-labeled-iteration-continue-target.js new file mode 100644 index 0000000000000000000000000000000000000000..3aeb237278d571ae8377417280ef3a9515742e88 --- /dev/null +++ b/es2panda/test/compiler/js/language/statements/labeled/test-labeled-iteration-continue-target.js @@ -0,0 +1,7 @@ +let a = 1; +target1: +target2: +while(a--) { + continue target1; +} +print("ok"); \ No newline at end of file diff --git a/es2panda/test/parser/js/test-labeled-iteration-continue-target-expected.txt b/es2panda/test/parser/js/test-labeled-iteration-continue-target-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f1d4caf172c20ade4efcd5d4b3af9582794f636 --- /dev/null +++ b/es2panda/test/parser/js/test-labeled-iteration-continue-target-expected.txt @@ -0,0 +1,210 @@ +{ + "type": "Program", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 6 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 10 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 11 + } + } + }, + { + "type": "LabelledStatement", + "label": { + "type": "Identifier", + "name": "target1", + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 8 + } + } + }, + "body": { + "type": "LabelledStatement", + "label": { + "type": "Identifier", + "name": "target2", + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 3, + "column": 8 + } + } + }, + "body": { + "type": "WhileStatement", + "test": { + "type": "UpdateExpression", + "operator": "--", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 4, + "column": 7 + }, + "end": { + "line": 4, + "column": 8 + } + } + }, + "loc": { + "start": { + "line": 4, + "column": 7 + }, + "end": { + "line": 4, + "column": 10 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ContinueStatement", + "label": { + "type": "Identifier", + "name": "target1", + "loc": { + "start": { + "line": 5, + "column": 14 + }, + "end": { + "line": 5, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 5, + "column": 5 + }, + "end": { + "line": 5, + "column": 22 + } + } + } + ], + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 6, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 4, + "column": 1 + }, + "end": { + "line": 6, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 6, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 6, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 6, + "column": 2 + } + } +} diff --git a/es2panda/test/parser/js/test-labeled-iteration-continue-target.js b/es2panda/test/parser/js/test-labeled-iteration-continue-target.js new file mode 100644 index 0000000000000000000000000000000000000000..56b1b14efc55d637cdbd37c55ce12f6805771522 --- /dev/null +++ b/es2panda/test/parser/js/test-labeled-iteration-continue-target.js @@ -0,0 +1,6 @@ +let a = 1; +target1: +target2: +while(a--) { + continue target1; +} \ No newline at end of file diff --git a/es2panda/test/test_tsc_ignore_list.txt b/es2panda/test/test_tsc_ignore_list.txt index ec89e64c815b7db9ddbfb7968fe7909836f71fc1..ecaf004dd532b9f15d2b94e90b4d095195986b2a 100644 --- a/es2panda/test/test_tsc_ignore_list.txt +++ b/es2panda/test/test_tsc_ignore_list.txt @@ -105,7 +105,6 @@ es2panda/test/TypeScript/tests/cases/conformance/interfaces/interfaceDeclaration es2panda/test/TypeScript/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts es2panda/test/TypeScript/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression6.ts es2panda/test/TypeScript/tests/cases/conformance/parser/ecmascript5/RegressionTests/parser579071.ts -es2panda/test/TypeScript/tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueTarget3.ts es2panda/test/TypeScript/tests/cases/conformance/parser/ecmascript5/parserUnicodeWhitespaceCharacter1.ts es2panda/test/TypeScript/tests/cases/conformance/scanner/ecmascript3/scannerES3NumericLiteral2.ts es2panda/test/TypeScript/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts