From 9a7acd487dea6999e6d7384174148a54ad43c97a Mon Sep 17 00:00:00 2001 From: songqi Date: Tue, 11 Oct 2022 16:20:11 +0800 Subject: [PATCH] Support for parsing MemberExpression with as keyword Issue: I5V4EE Test: test262, parser tests, compiler tests, tsc Signed-off-by: songqi Change-Id: I65ad89272d7f26151fd3ef5e346ba177b1e2b72b --- es2panda/parser/expressionParser.cpp | 13 +- es2panda/parser/parserImpl.h | 1 + .../ts/test-ts-as-expression1-expected.txt | 501 ++++++++++++++++++ .../test/parser/ts/test-ts-as-expression1.ts | 24 + es2panda/test/test_tsc_ignore_list.txt | 1 - 5 files changed, 538 insertions(+), 2 deletions(-) create mode 100644 es2panda/test/parser/ts/test-ts-as-expression1-expected.txt create mode 100644 es2panda/test/parser/ts/test-ts-as-expression1.ts diff --git a/es2panda/parser/expressionParser.cpp b/es2panda/parser/expressionParser.cpp index 56bbe33c8d..002308474a 100644 --- a/es2panda/parser/expressionParser.cpp +++ b/es2panda/parser/expressionParser.cpp @@ -1504,6 +1504,7 @@ bool ParserImpl::ParsePotentialTsGenericFunctionCall(ir::Expression **returnExpr } ir::Expression *ParserImpl::ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc, + ExpressionParseFlags flags, bool ignoreCallExpression, bool *isChainExpression) { ir::Expression *returnExpression = primaryExpr; @@ -1609,6 +1610,15 @@ ir::Expression *ParserImpl::ParsePostPrimaryExpression(ir::Expression *primaryEx lexer_->NextToken(); continue; } + case lexer::TokenType::LITERAL_IDENT: { + if (Extension() == ScriptExtension::TS && + lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_AS && + !(flags & ExpressionParseFlags::EXP_DISALLOW_AS)) { + returnExpression = ParseTsAsExpression(returnExpression, flags); + continue; + } + break; + } default: { break; } @@ -1660,7 +1670,8 @@ ir::Expression *ParserImpl::ParseMemberExpression(bool ignoreCallExpression, Exp } bool isChainExpression = false; - returnExpression = ParsePostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, &isChainExpression); + returnExpression = ParsePostPrimaryExpression(returnExpression, startLoc, flags, + ignoreCallExpression, &isChainExpression); if (!lexer_->GetToken().NewLine() && lexer::Token::IsUpdateToken(lexer_->GetToken().Type())) { lexer::SourcePosition start = returnExpression->Start(); diff --git a/es2panda/parser/parserImpl.h b/es2panda/parser/parserImpl.h index 2df27de939..c28df09b12 100644 --- a/es2panda/parser/parserImpl.h +++ b/es2panda/parser/parserImpl.h @@ -364,6 +364,7 @@ private: bool ParsePotentialTsGenericFunctionCall(ir::Expression **returnExpression, const lexer::SourcePosition &startLoc, bool ignoreCallExpression); ir::Expression *ParsePostPrimaryExpression(ir::Expression *primaryExpr, lexer::SourcePosition startLoc, + ExpressionParseFlags flags, bool ignoreCallExpression, bool *isChainExpression); ir::Expression *ParseMemberExpression(bool ignoreCallExpression = false, ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS); diff --git a/es2panda/test/parser/ts/test-ts-as-expression1-expected.txt b/es2panda/test/parser/ts/test-ts-as-expression1-expected.txt new file mode 100644 index 0000000000..1616a4cb35 --- /dev/null +++ b/es2panda/test/parser/ts/test-ts-as-expression1-expected.txt @@ -0,0 +1,501 @@ +{ + "type": "Program", + "statements": [ + { + "type": "FunctionDeclaration", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "func", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 17, + "column": 16 + } + } + } + ], + "returnType": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 35 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 45 + }, + "end": { + "line": 17, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 47 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 36 + }, + "end": { + "line": 17, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 49 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 9 + } + } + }, + "init": { + "type": "BooleanLiteral", + "value": true, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 16 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 9 + } + } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "func", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 3 + }, + "end": { + "line": 22, + "column": 7 + } + } + }, + "arguments": [ + { + "type": "LogicalExpression", + "operator": "&&", + "left": { + "type": "TSAsExpression", + "expression": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 8 + }, + "end": { + "line": 22, + "column": 12 + } + } + }, + "typeAnnotation": { + "type": "TSAnyKeyword", + "loc": { + "start": { + "line": 22, + "column": 16 + }, + "end": { + "line": 22, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 8 + }, + "end": { + "line": 22, + "column": 22 + } + } + }, + "right": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 23 + }, + "end": { + "line": 22, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 8 + }, + "end": { + "line": 22, + "column": 27 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 22, + "column": 3 + }, + "end": { + "line": 22, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 3 + }, + "end": { + "line": 22, + "column": 29 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "func", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 3 + }, + "end": { + "line": 23, + "column": 7 + } + } + }, + "arguments": [ + { + "type": "LogicalExpression", + "operator": "&&", + "left": { + "type": "TSAsExpression", + "expression": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 8 + }, + "end": { + "line": 23, + "column": 12 + } + } + }, + "typeAnnotation": { + "type": "TSAnyKeyword", + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 8 + }, + "end": { + "line": 23, + "column": 22 + } + } + }, + "right": { + "type": "TSAsExpression", + "expression": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 23 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 23, + "column": 31 + }, + "end": { + "line": 23, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 23 + }, + "end": { + "line": 23, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 8 + }, + "end": { + "line": 23, + "column": 39 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 23, + "column": 3 + }, + "end": { + "line": 23, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 3 + }, + "end": { + "line": 23, + "column": 40 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 11 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "alternate": null, + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 24, + "column": 2 + } + } +} diff --git a/es2panda/test/parser/ts/test-ts-as-expression1.ts b/es2panda/test/parser/ts/test-ts-as-expression1.ts new file mode 100644 index 0000000000..4f2efe5323 --- /dev/null +++ b/es2panda/test/parser/ts/test-ts-as-expression1.ts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 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 func(x: boolean): boolean { return x; } + +let flag = true; + +if (flag) { + func(flag as any && flag); + func(flag as any && flag as boolean); +} \ 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 716ca0e026..d7a13fa6b0 100644 --- a/es2panda/test/test_tsc_ignore_list.txt +++ b/es2panda/test/test_tsc_ignore_list.txt @@ -12,7 +12,6 @@ es2panda/test/TypeScript/tests/cases/compiler/computedPropertiesTransformedInOth es2panda/test/TypeScript/tests/cases/compiler/constructorOverloads5.ts es2panda/test/TypeScript/tests/cases/compiler/continueTarget3.ts es2panda/test/TypeScript/tests/cases/compiler/controlFlowCaching.ts -es2panda/test/TypeScript/tests/cases/compiler/controlFlowManyCallExpressionStatementsPerf.ts es2panda/test/TypeScript/tests/cases/compiler/declarationEmitDestructuringOptionalBindingParametersInOverloads.ts es2panda/test/TypeScript/tests/cases/compiler/declareIdentifierAsBeginningOfStatementExpression01.ts es2panda/test/TypeScript/tests/cases/compiler/discriminantsAndPrimitives.ts -- Gitee