From 6007e8280a108a9bcbea95233106bc4b37f7a906 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: I6IYLN Tests: parse/compile/tsc/test262 Signed-off-by: songqi Change-Id: I60dc3d041607bba32878a38f882b9f703da28ba0 --- es2panda/parser/expressionParser.cpp | 13 +- 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, 420 insertions(+), 2 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 9fb0e7cea7..9aae19465e 100644 --- a/es2panda/parser/expressionParser.cpp +++ b/es2panda/parser/expressionParser.cpp @@ -663,6 +663,9 @@ void ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression) switch (lhsExpression->Type()) { case ir::AstNodeType::IDENTIFIER: case ir::AstNodeType::MEMBER_EXPRESSION: { + if (lhsExpression->IsIdentifier() && lhsExpression->AsIdentifier()->TypeAnnotation() != nullptr) { + ThrowSyntaxError("'=>' expected."); + } break; } case ir::AstNodeType::ARRAY_EXPRESSION: { @@ -670,6 +673,9 @@ void ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression) if (info.Fail()) { ThrowSyntaxError(info.msg.Utf8(), info.pos); } + if (lhsExpression->AsArrayExpression()->TypeAnnotation() != nullptr) { + ThrowSyntaxError("'=>' expected."); + } break; } case ir::AstNodeType::OBJECT_EXPRESSION: { @@ -677,6 +683,9 @@ void ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression) if (info.Fail()) { ThrowSyntaxError(info.msg.Utf8(), info.pos); } + if (lhsExpression->AsObjectExpression()->TypeAnnotation() != nullptr) { + ThrowSyntaxError("'=>' expected."); + } break; } case ir::AstNodeType::ASSIGNMENT_EXPRESSION: { @@ -1054,13 +1063,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 723076cab3..88a1d6256b 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -250,6 +250,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 de716a4cd7..02180f3ac2 100644 --- a/es2panda/parser/parserImpl.h +++ b/es2panda/parser/parserImpl.h @@ -234,6 +234,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 0000000000..a028b15217 --- /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 0000000000..9649a88608 --- /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 0000000000..e9787b480e --- /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 0000000000..3a918c9a90 --- /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