diff --git a/es2panda/parser/expressionParser.cpp b/es2panda/parser/expressionParser.cpp index 9fb0e7cea752d657442b56465b01c5c054928673..9aae19465e63a029cec872ca37bfdc4e8657c65c 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 723076cab39745eeec2bb27a5122e6c8040458ef..88a1d6256b106b4cc4b0f444ecdbc4c63339e71d 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 de716a4cd74085561f5e0abfb6084be61d684b0e..02180f3ac26ac04d7e6d09986f5cca85e58e4aa7 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 0000000000000000000000000000000000000000..a028b15217a287bd9476b5cbe3a8ea23d173d98c --- /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 0000000000000000000000000000000000000000..9649a8860814cc94c80d0213746b86d2e5c86b00 --- /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 0000000000000000000000000000000000000000..e9787b480ed65c5b951a2a3ff94669de74f8991b --- /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 0000000000000000000000000000000000000000..3a918c9a9059a934d3bc65fd87aa0501bfbd068b --- /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)