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 b9c73c0ad85f75fccc6d04d60996a78efc32f5c3..7c633848fdad7e6d370e6d1503e1d74953b9bff9 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -1356,7 +1356,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); @@ -1502,6 +1503,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/test_tsc_ignore_list.txt b/es2panda/test/test_tsc_ignore_list.txt index 8c112aa8bc9d092e8ea0e379b2b61aba9bb8640e..53244a0ebf2e24777c67be76c3b401b54bff69e3 100644 --- a/es2panda/test/test_tsc_ignore_list.txt +++ b/es2panda/test/test_tsc_ignore_list.txt @@ -28,10 +28,6 @@ es2panda/test/TypeScript/tests/cases/compiler/parameterInitializerBeforeDestruct es2panda/test/TypeScript/tests/cases/compiler/shebang.ts es2panda/test/TypeScript/tests/cases/compiler/sigantureIsSubTypeIfTheyAreIdentical.ts es2panda/test/TypeScript/tests/cases/compiler/sourceMap-LineBreaks.ts -es2panda/test/TypeScript/tests/cases/compiler/sourceMapValidationDestructuringForArrayBindingPattern2.ts -es2panda/test/TypeScript/tests/cases/compiler/sourceMapValidationDestructuringForArrayBindingPatternDefaultValues2.ts -es2panda/test/TypeScript/tests/cases/compiler/sourceMapValidationDestructuringForObjectBindingPattern2.ts -es2panda/test/TypeScript/tests/cases/compiler/sourceMapValidationDestructuringForObjectBindingPatternDefaultValues2.ts es2panda/test/TypeScript/tests/cases/compiler/withStatementInternalComments.ts es2panda/test/TypeScript/tests/cases/conformance/async/es2017/asyncAwait_es2017.ts es2panda/test/TypeScript/tests/cases/conformance/es6/arrowFunction/emitArrowFunctionWhenUsingArguments03_ES6.ts