From 267fa6a442e47757bd4bb599c6e45b3123f3cc31 Mon Sep 17 00:00:00 2001 From: hufeng Date: Thu, 24 Nov 2022 07:10:39 +0000 Subject: [PATCH 1/2] Fix parsing continue with labeled target Signed-off-by: hufeng Change-Id: I0e1505181461cd646020503f0e90c5d870262868 --- es2panda/parser/statementParser.cpp | 2 +- ...led-iteration-continue-target-expected.txt | 1 + .../test-labeled-iteration-continue-target.js | 7 + ...led-iteration-continue-target-expected.txt | 210 ++++++++++++++++++ .../test-labeled-iteration-continue-target.js | 6 + es2panda/test/test_tsc_ignore_list.txt | 1 - 6 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 es2panda/test/compiler/js/language/statements/labeled/test-labeled-iteration-continue-target-expected.txt create mode 100644 es2panda/test/compiler/js/language/statements/labeled/test-labeled-iteration-continue-target.js create mode 100644 es2panda/test/parser/js/test-labeled-iteration-continue-target-expected.txt create mode 100644 es2panda/test/parser/js/test-labeled-iteration-continue-target.js diff --git a/es2panda/parser/statementParser.cpp b/es2panda/parser/statementParser.cpp index d32213d971..f6ebd0c614 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"); } 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 0000000000..9766475a41 --- /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 0000000000..3aeb237278 --- /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 0000000000..6f1d4caf17 --- /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 0000000000..56b1b14efc --- /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 ec89e64c81..ecaf004dd5 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 -- Gitee From 9baa63d454ce729e850d239acc74284a67d9a1d8 Mon Sep 17 00:00:00 2001 From: hufeng Date: Wed, 23 Nov 2022 08:18:41 +0000 Subject: [PATCH 2/2] Fix destructuring assignment in loopStatement Signed-off-by: hufeng Change-Id: I20b5c4d3cc51c1cf65b835464838cb0399361daf --- es2panda/compiler/base/destructuring.cpp | 26 ++++++++++++------- es2panda/compiler/base/lreference.cpp | 4 ++- es2panda/parser/statementParser.cpp | 6 ++++- ...rray-expr-destructring-in-for-expected.txt | 2 ++ .../test-array-expr-destructring-in-for.js | 11 ++++++++ ...-obj-expr-destructring-in-for-expected.txt | 2 ++ .../test-obj-expr-destructring-in-for.js | 11 ++++++++ 7 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 es2panda/test/compiler/js/language/destructuring/test-array-expr-destructring-in-for-expected.txt create mode 100644 es2panda/test/compiler/js/language/destructuring/test-array-expr-destructring-in-for.js create mode 100644 es2panda/test/compiler/js/language/destructuring/test-obj-expr-destructring-in-for-expected.txt create mode 100644 es2panda/test/compiler/js/language/destructuring/test-obj-expr-destructring-in-for.js diff --git a/es2panda/compiler/base/destructuring.cpp b/es2panda/compiler/base/destructuring.cpp index 5761a02177..24af709a12 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 53587e65b4..e354250c80 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 f6ebd0c614..1768922cea 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -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 0000000000..fad30353bb --- /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 0000000000..4cf992e1b1 --- /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 0000000000..fad30353bb --- /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 0000000000..6c8d0204c0 --- /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); +} -- Gitee