From 348fbca609864fa96790fc7f71370244fbf691b3 Mon Sep 17 00:00:00 2001 From: xucheng46 Date: Fri, 23 Sep 2022 20:23:25 +0800 Subject: [PATCH] Enable this parameter in es2abc ts function Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I5U2Q2 Test: test262, parser tests, compiler tests Signed-off-by: xucheng46 Change-Id: If981bfcf7ffc768a1f2a6f3604ea63e640f17ce5 --- es2panda/binder/scope.h | 5 ++++ es2panda/ir/base/scriptFunction.cpp | 8 ++++++ es2panda/ir/base/scriptFunction.h | 15 ++++++++++- es2panda/parser/commonjs.cpp | 2 +- es2panda/parser/expressionParser.cpp | 3 ++- es2panda/parser/parserImpl.cpp | 6 +++-- es2panda/parser/transformer/transformer.cpp | 2 +- .../functions/test-ts-function-1-expected.txt | 1 + .../functions/test-ts-function-1.ts | 21 +++++++++++++++ .../functions/test-ts-function-2-expected.txt | 3 +++ .../functions/test-ts-function-2.ts | 26 +++++++++++++++++++ 11 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-1-expected.txt create mode 100644 es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-1.ts create mode 100644 es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-2-expected.txt create mode 100644 es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-2.ts diff --git a/es2panda/binder/scope.h b/es2panda/binder/scope.h index 7375e89530..70be5ce9a7 100644 --- a/es2panda/binder/scope.h +++ b/es2panda/binder/scope.h @@ -508,6 +508,11 @@ public: bool AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, [[maybe_unused]] ScriptExtension extension) override; + void RemoveThisParam() + { + params_.erase(params_.begin()); + } + friend class FunctionScope; template friend class ScopeWithParamScope; diff --git a/es2panda/ir/base/scriptFunction.cpp b/es2panda/ir/base/scriptFunction.cpp index 52a766ed10..3716b630cc 100644 --- a/es2panda/ir/base/scriptFunction.cpp +++ b/es2panda/ir/base/scriptFunction.cpp @@ -60,6 +60,10 @@ void ScriptFunction::Iterate(const NodeTraverser &cb) const cb(id_); } + if (thisParam_) { + cb(thisParam_); + } + if (typeParams_) { cb(typeParams_); } @@ -106,6 +110,10 @@ void ScriptFunction::UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) auto paramScopeCtx = binder::LexicalScope::Enter(binder, scope_->ParamScope()); + if (thisParam_) { + thisParam_ = std::get(cb(thisParam_))->AsExpression(); + } + if (typeParams_) { typeParams_ = std::get(cb(typeParams_))->AsTSTypeParameterDeclaration(); } diff --git a/es2panda/ir/base/scriptFunction.h b/es2panda/ir/base/scriptFunction.h index 5a0db1202e..aaf29adb90 100644 --- a/es2panda/ir/base/scriptFunction.h +++ b/es2panda/ir/base/scriptFunction.h @@ -17,6 +17,7 @@ #define ES2PANDA_PARSER_INCLUDE_AST_SCRIPT_FUNCTION_H #include +#include #include namespace panda::es2panda::compiler { @@ -40,7 +41,7 @@ class ScriptFunction : public AstNode { public: explicit ScriptFunction(binder::FunctionScope *scope, ArenaVector &¶ms, TSTypeParameterDeclaration *typeParams, AstNode *body, Expression *returnTypeAnnotation, - ir::ScriptFunctionFlags flags, bool declare) + ir::ScriptFunctionFlags flags, bool declare, bool isTsFunction) : AstNode(AstNodeType::SCRIPT_FUNCTION), scope_(scope), id_(nullptr), @@ -52,6 +53,15 @@ public: declare_(declare), exportDefault_(false) { + thisParam_ = nullptr; + if (isTsFunction && !params_.empty()) { + auto *firstParam = params_.front(); + if (firstParam->IsIdentifier() && firstParam->AsIdentifier()->Name().Is(THIS_PARAM)) { + thisParam_ = firstParam; + params_.erase(params_.begin()); + scope_->ParamScope()->RemoveThisParam(); + } + } } const Identifier *Id() const @@ -164,8 +174,11 @@ public: void UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) override; private: + static constexpr std::string_view THIS_PARAM = "this"; + binder::FunctionScope *scope_; Identifier *id_; + Expression *thisParam_; ArenaVector params_; TSTypeParameterDeclaration *typeParams_; AstNode *body_; diff --git a/es2panda/parser/commonjs.cpp b/es2panda/parser/commonjs.cpp index cd28c9d198..d60656615b 100644 --- a/es2panda/parser/commonjs.cpp +++ b/es2panda/parser/commonjs.cpp @@ -74,7 +74,7 @@ void ParserImpl::ParseCommonjs() auto *funcNode = AllocNode(functionScope, std::move(params), nullptr, program_.Ast(), nullptr, - functionContext.Flags(), false); + functionContext.Flags(), false, Extension() == ScriptExtension::TS); functionScope->BindNode(funcNode); funcParamScope->BindNode(funcNode); diff --git a/es2panda/parser/expressionParser.cpp b/es2panda/parser/expressionParser.cpp index 56bbe33c8d..0c3b413990 100644 --- a/es2panda/parser/expressionParser.cpp +++ b/es2panda/parser/expressionParser.cpp @@ -396,7 +396,8 @@ ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowF } funcNode = AllocNode(functionScope, std::move(desc->params), typeParamDecl, body, - returnTypeAnnotation, arrowFunctionContext->Flags(), false); + returnTypeAnnotation, arrowFunctionContext->Flags(), false, + Extension() == ScriptExtension::TS); funcNode->SetRange({desc->startLoc, endLoc}); functionScope->BindNode(funcNode); desc->paramScope->BindNode(funcNode); diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index dd1b69eb33..4d6fc72bfa 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -2555,7 +2555,8 @@ ir::MethodDefinition *ParserImpl::CreateImplicitConstructor(bool hasSuperClass, auto *body = AllocNode(scope, std::move(statements)); auto *func = AllocNode(scope, std::move(params), nullptr, isDeclare ? nullptr : body, nullptr, - ir::ScriptFunctionFlags::CONSTRUCTOR, isDeclare); + ir::ScriptFunctionFlags::CONSTRUCTOR, isDeclare, + Extension() == ScriptExtension::TS); scope->BindNode(func); paramScope->BindNode(func); scope->BindParamScope(paramScope); @@ -3248,7 +3249,8 @@ ir::ScriptFunction *ParserImpl::ParseFunction(ParserStatus newStatus, bool isDec auto *funcNode = AllocNode(functionScope, std::move(params), typeParamDecl, body, returnTypeAnnotation, - functionContext.Flags(), isDeclare && letDeclare); + functionContext.Flags(), isDeclare && letDeclare, + Extension() == ScriptExtension::TS); functionScope->BindNode(funcNode); funcParamScope->BindNode(funcNode); funcNode->SetRange({startLoc, endLoc}); diff --git a/es2panda/parser/transformer/transformer.cpp b/es2panda/parser/transformer/transformer.cpp index 19afc1c9fd..7802fc5c75 100644 --- a/es2panda/parser/transformer/transformer.cpp +++ b/es2panda/parser/transformer/transformer.cpp @@ -438,7 +438,7 @@ ir::CallExpression *Transformer::CreateCallExpressionForTsModule(ir::TSModuleDec } funcNode = AllocNode(funcScope, std::move(params), nullptr, blockNode, nullptr, - ir::ScriptFunctionFlags::NONE, false); + ir::ScriptFunctionFlags::NONE, false, Extension() == ScriptExtension::TS); funcScope->BindNode(funcNode); funcParamScope->BindNode(funcNode); diff --git a/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-1-expected.txt b/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-1-expected.txt new file mode 100644 index 0000000000..0009a01dfd --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-1-expected.txt @@ -0,0 +1 @@ +test-ts-function-1 diff --git a/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-1.ts b/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-1.ts new file mode 100644 index 0000000000..08cd39ef0c --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-1.ts @@ -0,0 +1,21 @@ +/* + * 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 f(this, a : string) { + print(a); +} + +f("test-ts-function-1"); diff --git a/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-2-expected.txt b/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-2-expected.txt new file mode 100644 index 0000000000..f897285b33 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-2-expected.txt @@ -0,0 +1,3 @@ +test-ts-function-2 +1 +true diff --git a/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-2.ts b/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-2.ts new file mode 100644 index 0000000000..54fc171214 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/functions/test-ts-function-2.ts @@ -0,0 +1,26 @@ +/* + * 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 f(this, a : string) +function f(this, a : number) +function f(this, a : boolean) +function f(this, a: string | number | boolean) { + print(a); +} + +f("test-ts-function-2"); +f(1); +f(true); -- Gitee