From cf28bd03b7c030f3a0b2d4c63f7fa699f4887cfe Mon Sep 17 00:00:00 2001 From: songqi Date: Thu, 5 Jan 2023 16:25:30 +0800 Subject: [PATCH] Fix parser of ArrayExpression and ObjectExpression with TypeAnnotation Issue: I7R99M Tests: parse/compile/tsc/test262 Signed-off-by: songqi Change-Id: I60dc3d041607bba32878a38f882b9f703da28ba0 --- es2panda/parser/expressionParser.cpp | 17 +- es2panda/parser/parserImpl.cpp | 7 + es2panda/parser/parserImpl.h | 1 + .../ts/test-object-expression-expected.txt | 361 ++++++++++++++++++ .../test/parser/ts/test-object-expression.ts | 20 + .../ts/test-object-expression2-expected.txt | 1 + .../test/parser/ts/test-object-expression2.ts | 19 + 7 files changed, 423 insertions(+), 3 deletions(-) create mode 100644 es2panda/test/parser/ts/test-object-expression-expected.txt create mode 100644 es2panda/test/parser/ts/test-object-expression.ts create mode 100644 es2panda/test/parser/ts/test-object-expression2-expected.txt create mode 100644 es2panda/test/parser/ts/test-object-expression2.ts diff --git a/es2panda/parser/expressionParser.cpp b/es2panda/parser/expressionParser.cpp index 1cff021a8e0..ba53678f8b7 100644 --- a/es2panda/parser/expressionParser.cpp +++ b/es2panda/parser/expressionParser.cpp @@ -666,11 +666,19 @@ void ParserImpl::CheckInvalidDestructuring(const ir::AstNode *object) const void ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression) { switch (lhsExpression->Type()) { - case ir::AstNodeType::IDENTIFIER: + case ir::AstNodeType::IDENTIFIER: { + if (lhsExpression->AsIdentifier()->TypeAnnotation() != nullptr) { + ThrowSyntaxError("'=>' expected."); + } + break; + } case ir::AstNodeType::MEMBER_EXPRESSION: { break; } case ir::AstNodeType::ARRAY_EXPRESSION: { + if (lhsExpression->AsArrayExpression()->TypeAnnotation() != nullptr) { + ThrowSyntaxError("'=>' expected."); + } auto info = lhsExpression->AsArrayExpression()->ValidateExpression(); if (info.Fail()) { ThrowSyntaxError(info.msg.Utf8(), info.pos); @@ -678,6 +686,9 @@ void ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression) break; } case ir::AstNodeType::OBJECT_EXPRESSION: { + if (lhsExpression->AsObjectExpression()->TypeAnnotation() != nullptr) { + ThrowSyntaxError("'=>' expected."); + } auto info = lhsExpression->AsObjectExpression()->ValidateExpression(); if (info.Fail()) { ThrowSyntaxError(info.msg.Utf8(), info.pos); @@ -1059,13 +1070,13 @@ ir::Expression *ParserImpl::ParsePrimaryExpression(ExpressionParseFlags flags) return regexpNode; } case lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET: { - return ParseArrayExpression(CarryPatternFlags(flags)); + return ParseArrayExpression(CarryAllowTsParamAndPatternFlags(flags)); } case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { return ParseCoverParenthesizedExpressionAndArrowParameterList(); } case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: { - return ParseObjectExpression(CarryPatternFlags(flags)); + return ParseObjectExpression(CarryAllowTsParamAndPatternFlags(flags)); } case lexer::TokenType::KEYW_FUNCTION: { return ParseFunctionExpression(); diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index 7d6653311c9..e9dbac976db 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -252,6 +252,13 @@ ExpressionParseFlags ParserImpl::CarryPatternFlags(ExpressionParseFlags flags) ExpressionParseFlags::OBJECT_PATTERN); } +ExpressionParseFlags ParserImpl::CarryAllowTsParamAndPatternFlags(ExpressionParseFlags flags) +{ + return CarryExpressionParserFlag(flags, ExpressionParseFlags::ALLOW_TS_PARAM_TOKEN | + ExpressionParseFlags::POTENTIALLY_IN_PATTERN | + ExpressionParseFlags::OBJECT_PATTERN); +} + bool ParserImpl::CurrentLiteralIsBasicType() { ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || diff --git a/es2panda/parser/parserImpl.h b/es2panda/parser/parserImpl.h index 45e49d7ab29..90b0b75f22e 100644 --- a/es2panda/parser/parserImpl.h +++ b/es2panda/parser/parserImpl.h @@ -238,6 +238,7 @@ private: bool CheckTopStatementsForRequiredDeclare(const ArenaVector &statements); static ExpressionParseFlags CarryExpressionParserFlag(ExpressionParseFlags origin, ExpressionParseFlags carry); static ExpressionParseFlags CarryPatternFlags(ExpressionParseFlags flags); + static ExpressionParseFlags CarryAllowTsParamAndPatternFlags(ExpressionParseFlags flags); bool CurrentIsBasicType(); bool CurrentLiteralIsBasicType(); static bool CheckTypeNameIsReserved(const util::StringView ¶mName); diff --git a/es2panda/test/parser/ts/test-object-expression-expected.txt b/es2panda/test/parser/ts/test-object-expression-expected.txt new file mode 100644 index 00000000000..a028b15217a --- /dev/null +++ b/es2panda/test/parser/ts/test-object-expression-expected.txt @@ -0,0 +1,361 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "TSPropertySignature", + "computed": false, + "optional": false, + "readonly": false, + "key": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "typeAnnotation": { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 17, + "column": 26 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + "id": { + "type": "Identifier", + "name": "I", + "loc": { + "start": { + "line": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 12 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ObjectPattern", + "properties": [ + { + "type": "Property", + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 4 + } + } + }, + "value": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 4 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 4 + } + } + } + ], + "typeAnnotation": { + "type": "TSTypeReference", + "typeName": { + "type": "Identifier", + "name": "I", + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 8 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 8 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 9 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ArrayPattern", + "elements": [ + { + "type": "Identifier", + "name": "b", + "loc": { + "start": { + "line": 20, + "column": 3 + }, + "end": { + "line": 20, + "column": 4 + } + } + } + ], + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 20, + "column": 6 + }, + "end": { + "line": 20, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 6 + }, + "end": { + "line": 20, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 15 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test-object-expression.ts b/es2panda/test/parser/ts/test-object-expression.ts new file mode 100644 index 00000000000..9649a886081 --- /dev/null +++ b/es2panda/test/parser/ts/test-object-expression.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +interface I { a: number } + +({a}: I) => {} +([b]:number[]) => {} diff --git a/es2panda/test/parser/ts/test-object-expression2-expected.txt b/es2panda/test/parser/ts/test-object-expression2-expected.txt new file mode 100644 index 00000000000..e9787b480ed --- /dev/null +++ b/es2panda/test/parser/ts/test-object-expression2-expected.txt @@ -0,0 +1 @@ +SyntaxError: '=>' expected. [test-object-expression2.ts:20:1] diff --git a/es2panda/test/parser/ts/test-object-expression2.ts b/es2panda/test/parser/ts/test-object-expression2.ts new file mode 100644 index 00000000000..3a918c9a905 --- /dev/null +++ b/es2panda/test/parser/ts/test-object-expression2.ts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +interface I { a: number } + +({a}:I) -- Gitee