From e8e7bd1a12dc2ed4c31e3e26e6de5ecb6ba554a7 Mon Sep 17 00:00:00 2001 From: liyue Date: Thu, 7 Mar 2024 06:39:18 +0000 Subject: [PATCH] Fix parsing conditional expressions error when encountering function type Issue: I96MME Tests: all es2abc tests Signed-off-by: liyue Change-Id: Ib048767615c9ef4dedf8127b0ff661fa365ebbd4 --- es2panda/parser/parserImpl.cpp | 16 +- .../test-conditional-expression-expected.txt | 1 + .../compiler/test-conditional-expression.ts | 22 + .../test-conditional-expression-expected.txt | 480 ++++++++++++++++++ .../parser/ts/test-conditional-expression.ts | 19 + 5 files changed, 535 insertions(+), 3 deletions(-) create mode 100644 es2panda/test/compiler/ts/cases/compiler/test-conditional-expression-expected.txt create mode 100644 es2panda/test/compiler/ts/cases/compiler/test-conditional-expression.ts create mode 100644 es2panda/test/parser/ts/test-conditional-expression-expected.txt create mode 100644 es2panda/test/parser/ts/test-conditional-expression.ts diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index a8c4fb7f50..b85c69a47e 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -1866,7 +1866,10 @@ ir::Expression *ParserImpl::ParseTsParenthesizedOrFunctionType(ir::Expression *t TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS; ir::Expression *type = ParseTsTypeAnnotation(&options); - if (throwError && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { + if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { + if (!throwError) { + return nullptr; + } ThrowSyntaxError("')' expected"); } @@ -1914,10 +1917,17 @@ ir::Expression *ParserImpl::ParseTsFunctionType(lexer::SourcePosition startLoc, lexer_->NextToken(); // eat '=>' - TypeAnnotationParsingOptions options = - TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; + TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; + if (throwError) { + options |= TypeAnnotationParsingOptions::THROW_ERROR; + } + ir::Expression *returnTypeAnnotation = ParseTsTypeAnnotation(&options); + if (returnTypeAnnotation == nullptr) { + return nullptr; + } + ir::Expression *funcType = nullptr; if (isConstructionType) { diff --git a/es2panda/test/compiler/ts/cases/compiler/test-conditional-expression-expected.txt b/es2panda/test/compiler/ts/cases/compiler/test-conditional-expression-expected.txt new file mode 100644 index 0000000000..7ed6ff82de --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-conditional-expression-expected.txt @@ -0,0 +1 @@ +5 diff --git a/es2panda/test/compiler/ts/cases/compiler/test-conditional-expression.ts b/es2panda/test/compiler/ts/cases/compiler/test-conditional-expression.ts new file mode 100644 index 0000000000..06be5ca5a7 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-conditional-expression.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 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. + */ + + +function foo(testBool: boolean) { + return testBool ? (x: number, y: number) => (x < y ? x : y) : (x: number, y: number) => (x > y ? x : y) +} +const resultFunction = foo(true); +const result = resultFunction(5, 10); +print(result); diff --git a/es2panda/test/parser/ts/test-conditional-expression-expected.txt b/es2panda/test/parser/ts/test-conditional-expression-expected.txt new file mode 100644 index 0000000000..667c66eb36 --- /dev/null +++ b/es2panda/test/parser/ts/test-conditional-expression-expected.txt @@ -0,0 +1,480 @@ +{ + "type": "Program", + "statements": [ + { + "type": "FunctionDeclaration", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "Identifier", + "name": "testBool", + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 22 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ConditionalExpression", + "test": { + "type": "Identifier", + "name": "testBool", + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + "consequent": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": true, + "params": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 25 + } + } + }, + { + "type": "Identifier", + "name": "y", + "typeAnnotation": { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 18, + "column": 38 + }, + "end": { + "line": 18, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 36 + } + } + } + ], + "body": { + "type": "ConditionalExpression", + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "x", + "loc": { + "start": { + "line": 18, + "column": 50 + }, + "end": { + "line": 18, + "column": 51 + } + } + }, + "right": { + "type": "Identifier", + "name": "y", + "loc": { + "start": { + "line": 18, + "column": 54 + }, + "end": { + "line": 18, + "column": 55 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 50 + }, + "end": { + "line": 18, + "column": 55 + } + } + }, + "consequent": { + "type": "Identifier", + "name": "x", + "loc": { + "start": { + "line": 18, + "column": 58 + }, + "end": { + "line": 18, + "column": 59 + } + } + }, + "alternate": { + "type": "Identifier", + "name": "y", + "loc": { + "start": { + "line": 18, + "column": 62 + }, + "end": { + "line": 18, + "column": 63 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 49 + }, + "end": { + "line": 18, + "column": 64 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 23 + }, + "end": { + "line": 18, + "column": 64 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 23 + }, + "end": { + "line": 18, + "column": 64 + } + } + }, + "alternate": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": true, + "params": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 18, + "column": 71 + }, + "end": { + "line": 18, + "column": 77 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 68 + }, + "end": { + "line": 18, + "column": 69 + } + } + }, + { + "type": "Identifier", + "name": "y", + "typeAnnotation": { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 18, + "column": 82 + }, + "end": { + "line": 18, + "column": 88 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 79 + }, + "end": { + "line": 18, + "column": 80 + } + } + } + ], + "body": { + "type": "ConditionalExpression", + "test": { + "type": "BinaryExpression", + "operator": ">", + "left": { + "type": "Identifier", + "name": "x", + "loc": { + "start": { + "line": 18, + "column": 94 + }, + "end": { + "line": 18, + "column": 95 + } + } + }, + "right": { + "type": "Identifier", + "name": "y", + "loc": { + "start": { + "line": 18, + "column": 98 + }, + "end": { + "line": 18, + "column": 99 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 94 + }, + "end": { + "line": 18, + "column": 99 + } + } + }, + "consequent": { + "type": "Identifier", + "name": "x", + "loc": { + "start": { + "line": 18, + "column": 102 + }, + "end": { + "line": 18, + "column": 103 + } + } + }, + "alternate": { + "type": "Identifier", + "name": "y", + "loc": { + "start": { + "line": 18, + "column": 106 + }, + "end": { + "line": 18, + "column": 107 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 93 + }, + "end": { + "line": 18, + "column": 108 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 67 + }, + "end": { + "line": 18, + "column": 108 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 67 + }, + "end": { + "line": 18, + "column": 108 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 108 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 108 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 33 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 19, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 20, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test-conditional-expression.ts b/es2panda/test/parser/ts/test-conditional-expression.ts new file mode 100644 index 0000000000..df689a56c5 --- /dev/null +++ b/es2panda/test/parser/ts/test-conditional-expression.ts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 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. + */ + + +function foo(testBool: boolean) { + return testBool ? (x: number, y: number) => (x < y ? x : y) : (x: number, y: number) => (x > y ? x : y) +} -- Gitee