From cfcfbb9292c78ea1e4098854ee0cfdbb301dfec9 Mon Sep 17 00:00:00 2001 From: shawn_hu_ls Date: Thu, 1 Sep 2022 01:01:09 +0800 Subject: [PATCH] Add missing type arguments info for NewExpression in parser Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I5P3G7?from=project-issue Signed-off-by: shawn_hu_ls --- es2panda/ir/expressions/newExpression.cpp | 8 +- es2panda/ir/expressions/newExpression.h | 14 +- es2panda/parser/expressionParser.cpp | 22 +- .../ts/test-new-expression1-expected.txt | 339 +++++++++++++ .../test/parser/ts/test-new-expression1.ts | 20 + .../ts/test-new-expression2-expected.txt | 287 +++++++++++ .../test/parser/ts/test-new-expression2.ts | 19 + .../ts/test-new-expression3-expected.txt | 455 ++++++++++++++++++ .../test/parser/ts/test-new-expression3.ts | 20 + 9 files changed, 1176 insertions(+), 8 deletions(-) create mode 100644 es2panda/test/parser/ts/test-new-expression1-expected.txt create mode 100644 es2panda/test/parser/ts/test-new-expression1.ts create mode 100644 es2panda/test/parser/ts/test-new-expression2-expected.txt create mode 100644 es2panda/test/parser/ts/test-new-expression2.ts create mode 100644 es2panda/test/parser/ts/test-new-expression3-expected.txt create mode 100644 es2panda/test/parser/ts/test-new-expression3.ts diff --git a/es2panda/ir/expressions/newExpression.cpp b/es2panda/ir/expressions/newExpression.cpp index 071e44f32ec..937eee65c5e 100644 --- a/es2panda/ir/expressions/newExpression.cpp +++ b/es2panda/ir/expressions/newExpression.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace panda::es2panda::ir { @@ -27,6 +28,10 @@ void NewExpression::Iterate(const NodeTraverser &cb) const { cb(callee_); + if (typeParams_) { + cb(typeParams_); + } + for (auto *it : arguments_) { cb(it); } @@ -34,7 +39,8 @@ void NewExpression::Iterate(const NodeTraverser &cb) const void NewExpression::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", "NewExpression"}, {"callee", callee_}, {"arguments", arguments_}}); + dumper->Add({{"type", "NewExpression"}, {"callee", callee_}, {"typeParameters", AstDumper::Optional(typeParams_)}, + {"arguments", arguments_}}); } void NewExpression::Compile(compiler::PandaGen *pg) const diff --git a/es2panda/ir/expressions/newExpression.h b/es2panda/ir/expressions/newExpression.h index cad89d3980a..d4d88bd1402 100644 --- a/es2panda/ir/expressions/newExpression.h +++ b/es2panda/ir/expressions/newExpression.h @@ -29,10 +29,14 @@ class Type; namespace panda::es2panda::ir { +class TSTypeParameterInstantiation; + class NewExpression : public Expression { public: - explicit NewExpression(Expression *callee, ArenaVector &&arguments) - : Expression(AstNodeType::NEW_EXPRESSION), callee_(callee), arguments_(std::move(arguments)) + explicit NewExpression(Expression *callee, TSTypeParameterInstantiation *typeParams, + ArenaVector &&arguments) + : Expression(AstNodeType::NEW_EXPRESSION), callee_(callee), + typeParams_(typeParams), arguments_(std::move(arguments)) { } @@ -41,6 +45,11 @@ public: return callee_; } + const TSTypeParameterInstantiation *TypeParams() const + { + return typeParams_; + } + const ArenaVector &Arguments() const { return arguments_; @@ -53,6 +62,7 @@ public: private: Expression *callee_; + TSTypeParameterInstantiation *typeParams_; ArenaVector arguments_; }; diff --git a/es2panda/parser/expressionParser.cpp b/es2panda/parser/expressionParser.cpp index 86f2df8516c..e0ee93fc2a0 100644 --- a/es2panda/parser/expressionParser.cpp +++ b/es2panda/parser/expressionParser.cpp @@ -877,11 +877,25 @@ ir::NewExpression *ParserImpl::ParseNewExpression() ThrowSyntaxError("Cannot use new with import(...)"); } + // parse type params of NewExpression + lexer::SourcePosition endLoc = callee->End(); + ir::TSTypeParameterInstantiation *typeParamInst = nullptr; + if (Extension() == ScriptExtension::TS) { + if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) { + lexer_->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); + } + if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { + typeParamInst = ParseTsTypeParameterInstantiation(); + if (typeParamInst != nullptr) { + endLoc = typeParamInst->End(); + } + } + } + ArenaVector arguments(Allocator()->Adapter()); if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { - lexer::SourcePosition endLoc = callee->End(); - auto *newExprNode = AllocNode(callee, std::move(arguments)); + auto *newExprNode = AllocNode(callee, typeParamInst, std::move(arguments)); newExprNode->SetRange({start, endLoc}); return newExprNode; @@ -910,7 +924,7 @@ ir::NewExpression *ParserImpl::ParseNewExpression() } } - auto *newExprNode = AllocNode(callee, std::move(arguments)); + auto *newExprNode = AllocNode(callee, typeParamInst, std::move(arguments)); newExprNode->SetRange({start, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -1464,8 +1478,6 @@ bool ParserImpl::ParsePotentialTsGenericFunctionCall(ir::Expression **returnExpr (*returnExpression)->AsCallExpression()->SetTypeParams(typeParams); return false; } - - return true; } if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) { diff --git a/es2panda/test/parser/ts/test-new-expression1-expected.txt b/es2panda/test/parser/ts/test-new-expression1-expected.txt new file mode 100644 index 00000000000..0d49edae023 --- /dev/null +++ b/es2panda/test/parser/ts/test-new-expression1-expected.txt @@ -0,0 +1,339 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "superClass": null, + "implements": [], + "constructor": { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 17, + "column": 2 + } + } + }, + "body": [], + "indexSignatures": [], + "loc": { + "start": { + "line": 16, + "column": 12 + }, + "end": { + "line": 17, + "column": 2 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 17, + "column": 2 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "TSTypeReference", + "typeName": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 10 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 19, + "column": 11 + }, + "end": { + "line": 19, + "column": 17 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 10 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "init": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 25 + }, + "end": { + "line": 19, + "column": 26 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 19, + "column": 27 + }, + "end": { + "line": 19, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 26 + }, + "end": { + "line": 19, + "column": 34 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 19, + "column": 21 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 36 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 37 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test-new-expression1.ts b/es2panda/test/parser/ts/test-new-expression1.ts new file mode 100644 index 00000000000..00470d96ef0 --- /dev/null +++ b/es2panda/test/parser/ts/test-new-expression1.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +class A { +} + +let a : A = new A(); + diff --git a/es2panda/test/parser/ts/test-new-expression2-expected.txt b/es2panda/test/parser/ts/test-new-expression2-expected.txt new file mode 100644 index 00000000000..5342510be6c --- /dev/null +++ b/es2panda/test/parser/ts/test-new-expression2-expected.txt @@ -0,0 +1,287 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./typescript", + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "specifiers": [ + { + "type": "ImportDefaultSpecifier", + "local": { + "type": "Identifier", + "name": "ns", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 10 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "TSTypeReference", + "typeName": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "ns", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 11 + } + } + }, + "right": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 20 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 13 + }, + "end": { + "line": 18, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "init": { + "type": "NewExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "ns", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 30 + } + } + }, + "property": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 31 + }, + "end": { + "line": 18, + "column": 32 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 32 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 18, + "column": 33 + }, + "end": { + "line": 18, + "column": 39 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 32 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 42 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 43 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 20, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test-new-expression2.ts b/es2panda/test/parser/ts/test-new-expression2.ts new file mode 100644 index 00000000000..5f21fe4cd79 --- /dev/null +++ b/es2panda/test/parser/ts/test-new-expression2.ts @@ -0,0 +1,19 @@ +/* + * 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. + */ + +import ns from "./typescript" + +let a : ns.A = new ns.A(); + diff --git a/es2panda/test/parser/ts/test-new-expression3-expected.txt b/es2panda/test/parser/ts/test-new-expression3-expected.txt new file mode 100644 index 00000000000..b5a15c8b0d5 --- /dev/null +++ b/es2panda/test/parser/ts/test-new-expression3-expected.txt @@ -0,0 +1,455 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 12 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "superClass": null, + "implements": [], + "constructor": { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 17, + "column": 2 + } + } + }, + "body": [], + "indexSignatures": [], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 17, + "column": 2 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 17, + "column": 2 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "TSTypeReference", + "typeName": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "TSFunctionType", + "params": [], + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 11 + }, + "end": { + "line": 19, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 11 + }, + "end": { + "line": 19, + "column": 13 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 13 + } + } + }, + "returnType": { + "type": "TSTypeLiteral", + "members": [], + "loc": { + "start": { + "line": 19, + "column": 19 + }, + "end": { + "line": 19, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 9 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "init": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 29 + }, + "end": { + "line": 19, + "column": 30 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "TSFunctionType", + "params": [], + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 32 + }, + "end": { + "line": 19, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 32 + }, + "end": { + "line": 19, + "column": 34 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 31 + }, + "end": { + "line": 19, + "column": 34 + } + } + }, + "returnType": { + "type": "TSTypeLiteral", + "members": [], + "loc": { + "start": { + "line": 19, + "column": 40 + }, + "end": { + "line": 19, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 31 + }, + "end": { + "line": 19, + "column": 42 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 19, + "column": 43 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 19, + "column": 25 + }, + "end": { + "line": 19, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 45 + } + } + } + ], + "kind": "var", + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 45 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test-new-expression3.ts b/es2panda/test/parser/ts/test-new-expression3.ts new file mode 100644 index 00000000000..8f3c2d5bfe3 --- /dev/null +++ b/es2panda/test/parser/ts/test-new-expression3.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +class A { +} + +var a: A<() => {}> = new A<() => {}>() + -- Gitee