From 9007bc6e89c79dce2771e94e08385dfa13eb6081 Mon Sep 17 00:00:00 2001 From: songqi Date: Tue, 1 Aug 2023 19:07:55 +0800 Subject: [PATCH 1/2] Reset parent for transformed AstNodes Signed-off-by: songqi Change-Id: I8984c469d65bdc12d00263eaa743e966b335e050 --- es2panda/binder/binder.cpp | 15 +++++++++++++++ es2panda/binder/binder.h | 2 ++ es2panda/parser/transformer/transformer.cpp | 4 ---- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 7496cc6aa45..bb9ff930298 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -572,6 +572,10 @@ void Binder::BuildClassDefinition(ir::ClassDefinition *classDef) ResolveReference(classDef, stmt); } + if (extension_ == ScriptExtension::TS) { + ResetParentForTransformedAtsNode(classDef, classDef->Ctor()); + } + for (auto *iter : classDef->IndexSignatures()) { ResolveReference(classDef, iter); } @@ -806,6 +810,17 @@ void Binder::ResolveReferences(const ir::AstNode *parent) parent->Iterate([this, parent](auto *childNode) { ResolveReference(parent, childNode); }); } +void Binder::ResetParentForTransformedAtsNodes(const ir::AstNode *parent) +{ + parent->Iterate([this, parent](auto *childNode) { ResetParentForTransformedAtsNode(parent, childNode); }); +} + +void Binder::ResetParentForTransformedAtsNode(const ir::AstNode *parent, ir::AstNode *childNode) +{ + childNode->SetParent(parent); + ResetParentForTransformedAtsNodes(childNode); +} + void Binder::AddMandatoryParam(const std::string_view &name) { ASSERT(scope_->IsFunctionVariableScope()); diff --git a/es2panda/binder/binder.h b/es2panda/binder/binder.h index 1f51a5ed9eb..3ec11c72f59 100644 --- a/es2panda/binder/binder.h +++ b/es2panda/binder/binder.h @@ -210,6 +210,8 @@ private: void LookupIdentReference(ir::Identifier *ident); void ResolveReference(const ir::AstNode *parent, ir::AstNode *childNode); void ResolveReferences(const ir::AstNode *parent); + void ResetParentForTransformedAtsNode(const ir::AstNode *parent, ir::AstNode *childNode); + void ResetParentForTransformedAtsNodes(const ir::AstNode *parent); void ValidateExportDecl(const ir::ExportNamedDeclaration *exportDecl); void StoreAndCheckSpecialFunctionName(std::string &internalNameStr, std::string recordName); void ReplaceConstReferenceWithInitialization(const ir::Identifier *ident, const Decl *decl); diff --git a/es2panda/parser/transformer/transformer.cpp b/es2panda/parser/transformer/transformer.cpp index 0a2b7f0f757..79aee10f767 100644 --- a/es2panda/parser/transformer/transformer.cpp +++ b/es2panda/parser/transformer/transformer.cpp @@ -2032,10 +2032,6 @@ void Transformer::CheckTransformedAstNode(const ir::AstNode *parent, ir::AstNode (childNode->AsClassProperty()->IsStatic() || childNode->AsClassProperty()->Value() != nullptr)) { return; } - if (childNode->IsMethodDefinition() && - childNode->AsMethodDefinition()->Kind() == ir::MethodDefinitionKind::CONSTRUCTOR) { - return; - } if (childNode->IsDecorator()) { return; } -- Gitee From 8c2b1eceb52aa47a7d559f267653e890cb467a20 Mon Sep 17 00:00:00 2001 From: songqi Date: Thu, 3 Aug 2023 20:18:34 +0800 Subject: [PATCH 2/2] Fix transformer for Decorators Signed-off-by: songqi Change-Id: I1b4384ecc9b36d2f9788999d49f3a95e2e59f916 --- es2panda/parser/transformer/transformer.cpp | 82 +++++++++++++++++++-- es2panda/parser/transformer/transformer.h | 6 +- 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/es2panda/parser/transformer/transformer.cpp b/es2panda/parser/transformer/transformer.cpp index 79aee10f767..8879e10bac9 100644 --- a/es2panda/parser/transformer/transformer.cpp +++ b/es2panda/parser/transformer/transformer.cpp @@ -768,7 +768,16 @@ ir::UpdateNodes Transformer::VisitClassDeclaration(ir::ClassDeclaration *node) if (it->IsMethodDefinition()) { auto *definition = it->AsMethodDefinition(); bool isStatic = definition->IsStatic(); - auto paramDecorators = CreateParamDecorators(name, definition, false, isStatic); + + auto variableDeclarations = CreateVariableDeclarationForDecorators(definition); + if (isStatic) { + staticMemberDecorators.insert(staticMemberDecorators.end(), + variableDeclarations.begin(), variableDeclarations.end()); + } else { + res.insert(res.end(), variableDeclarations.begin(), variableDeclarations.end()); + } + + auto paramDecorators = CreateParamDecorators(name, definition, variableDeclarations, false, isStatic); if (isStatic) { staticMemberDecorators.insert(staticMemberDecorators.end(), paramDecorators.begin(), paramDecorators.end()); @@ -778,7 +787,7 @@ ir::UpdateNodes Transformer::VisitClassDeclaration(ir::ClassDeclaration *node) if (!definition->HasDecorators()) { continue; } - auto methodDecorators = CreateMethodDecorators(name, definition, isStatic); + auto methodDecorators = CreateMethodDecorators(name, definition, variableDeclarations, isStatic); if (isStatic) { staticMemberDecorators.insert(staticMemberDecorators.end(), methodDecorators.begin(), methodDecorators.end()); @@ -805,14 +814,17 @@ ir::UpdateNodes Transformer::VisitClassDeclaration(ir::ClassDeclaration *node) res.insert(res.end(), staticMemberDecorators.begin(), staticMemberDecorators.end()); } + auto variableDeclarationsForCtorOrClass = CreateVariableDeclarationForDecorators(node); + res.insert(res.end(), variableDeclarationsForCtorOrClass.begin(), variableDeclarationsForCtorOrClass.end()); + // constructor decorators auto *ctor = node->Definition()->Ctor(); - auto ctorParamDecorators = CreateParamDecorators(name, ctor, true, false); + auto ctorParamDecorators = CreateParamDecorators(name, ctor, variableDeclarationsForCtorOrClass, true, false); res.insert(res.end(), ctorParamDecorators.begin(), ctorParamDecorators.end()); // class decorators if (hasClassDecorators) { - auto classDecorators = CreateClassDecorators(node); + auto classDecorators = CreateClassDecorators(node, variableDeclarationsForCtorOrClass); res.insert(res.end(), classDecorators.begin(), classDecorators.end()); } if (res.size() == 1) { @@ -821,8 +833,52 @@ ir::UpdateNodes Transformer::VisitClassDeclaration(ir::ClassDeclaration *node) return res; } +std::vector Transformer::CreateVariableDeclarationForDecorators(ir::AstNode *node) +{ + std::vector res; + + if (node->IsMethodDefinition()) { + auto methodDecorators = node->AsMethodDefinition()->Decorators(); + for (size_t i = 0; i < methodDecorators.size(); i++) { + util::StringView varName = CreateNewVariable(false); + res.push_back(CreateVariableDeclarationWithIdentify(varName, VariableParsingFlags::LET, nullptr, + false, methodDecorators[i]->Expr(), true)); + } + + auto paramsDecorators = node->AsMethodDefinition()->GetParamDecorators(); + for (size_t i = 0; i < paramsDecorators.size(); i++) { + auto paramDecorators = paramsDecorators[i].decorators; + for (size_t j = 0; j < paramDecorators.size(); j++) { + util::StringView varName = CreateNewVariable(false); + res.push_back(CreateVariableDeclarationWithIdentify(varName, VariableParsingFlags::LET, nullptr, + false, paramDecorators[j]->Expr(), true)); + } + } + } else if (node->IsClassDeclaration()) { + auto classDecorators = node->AsClassDeclaration()->Decorators(); + for (size_t i = 0; i < classDecorators.size(); i++) { + util::StringView varName = CreateNewVariable(false); + res.push_back(CreateVariableDeclarationWithIdentify(varName, VariableParsingFlags::LET, nullptr, + false, classDecorators[i]->Expr(), true)); + } + + auto ctorParamsDecorators = node->AsClassDeclaration()->Definition()->Ctor()->GetParamDecorators(); + for (size_t i = 0; i < ctorParamsDecorators.size(); i++) { + auto ctorParamDecorators = ctorParamsDecorators[i].decorators; + for (size_t j = 0; j < ctorParamDecorators.size(); j++) { + util::StringView varName = CreateNewVariable(false); + res.push_back(CreateVariableDeclarationWithIdentify(varName, VariableParsingFlags::LET, nullptr, + false, ctorParamDecorators[j]->Expr(), true)); + } + } + } + + return res; +} + std::vector Transformer::CreateParamDecorators(util::StringView className, ir::MethodDefinition *node, + const std::vector &variableDeclarations, bool isConstructor, bool isStatic) { @@ -842,6 +898,7 @@ std::vector Transformer::CreateParamDecorators(util::StringView c * Static method or constructor will use constructor function of the class instead of prototype of class */ std::vector res; + int pos = variableDeclarations.size(); auto paramsDecorators = node->GetParamDecorators(); for (int i = paramsDecorators.size() - 1; i >= 0; i--) { auto paramIndex = paramsDecorators[i].paramIndex; @@ -853,7 +910,8 @@ std::vector Transformer::CreateParamDecorators(util::StringView c CreateReferenceIdentifier(CONSTRUCTOR_NAME) : GetClassMemberName(node->Key(), node->Computed(), node)); arguments.push_back(AllocNode(paramIndex)); - auto *callExpr = AllocNode(decorators[j]->Expr(), + auto *callExpr = AllocNode( + variableDeclarations[--pos]->AsVariableDeclaration()->Declarators().front()->Id(), std::move(arguments), nullptr, false); res.push_back(AllocNode(callExpr)); } @@ -895,6 +953,7 @@ std::vector Transformer::CreatePropertyDecorators(util::StringVie std::vector Transformer::CreateMethodDecorators(util::StringView className, ir::MethodDefinition *node, + const std::vector &variableDeclarations, bool isStatic) { /* @@ -917,6 +976,7 @@ std::vector Transformer::CreateMethodDecorators(util::StringView * If the decorator has a return value, it will be set as the new property of the method */ std::vector res; + int pos = node->Decorators().size(); auto decorators = node->Decorators(); for (int i = decorators.size() - 1; i >= 0; i--) { ArenaVector arguments(Allocator()->Adapter()); @@ -924,7 +984,9 @@ std::vector Transformer::CreateMethodDecorators(util::StringView arguments.push_back(GetClassMemberName(node->Key(), node->Computed(), node)); arguments.push_back(CreateGetOwnPropertyDescriptorCall(CreateDecoratorTarget(className, isStatic), GetClassMemberName(node->Key(), node->Computed(), node))); - auto *callExpr = AllocNode(decorators[i]->Expr(), std::move(arguments), nullptr, false); + auto *callExpr = AllocNode( + variableDeclarations[--pos]->AsVariableDeclaration()->Declarators().front()->Id(), + std::move(arguments), nullptr, false); auto *getProperty = CreateGetOwnPropertyDescriptorCall(CreateDecoratorTarget(className, isStatic), GetClassMemberName(node->Key(), node->Computed(), node)); @@ -1004,7 +1066,8 @@ ir::Expression *Transformer::GetClassMemberName(ir::Expression *key, bool isComp return nullptr; } -std::vector Transformer::CreateClassDecorators(ir::ClassDeclaration *node) +std::vector Transformer::CreateClassDecorators(ir::ClassDeclaration *node, + const std::vector &variableDeclarations) { /* * Class decorators @@ -1023,11 +1086,14 @@ std::vector Transformer::CreateClassDecorators(ir::ClassDeclarati auto name = node->Definition()->GetName(); auto decorators = node->Decorators(); auto size = decorators.size(); + int pos = size; std::vector res; for (int i = size - 1; i >= 0; i--) { ArenaVector arguments(Allocator()->Adapter()); arguments.push_back(CreateReferenceIdentifier(name)); - auto *callExpr = AllocNode(decorators[i]->Expr(), std::move(arguments), nullptr, false); + auto *callExpr = AllocNode( + variableDeclarations[--pos]->AsVariableDeclaration()->Declarators().front()->Id(), + std::move(arguments), nullptr, false); auto left = CreateReferenceIdentifier(name); auto id = CreateReferenceIdentifier(name); diff --git a/es2panda/parser/transformer/transformer.h b/es2panda/parser/transformer/transformer.h index f9b2153dd4a..3a5bb3a77a8 100644 --- a/es2panda/parser/transformer/transformer.h +++ b/es2panda/parser/transformer/transformer.h @@ -124,17 +124,21 @@ private: ir::Expression *CreateTsModuleParam(util::StringView paramName, bool isExport); ir::ExpressionStatement *CreateTsModuleAssignment(util::StringView name); ir::Expression *CreateMemberExpressionFromQualified(ir::Expression *node); - std::vector CreateClassDecorators(ir::ClassDeclaration *node); + std::vector CreateClassDecorators(ir::ClassDeclaration *node, + const std::vector &variableDeclarations); std::vector CreateMethodDecorators(util::StringView className, ir::MethodDefinition *node, + const std::vector &variableDeclarations, bool isStatic); std::vector CreatePropertyDecorators(util::StringView className, ir::ClassProperty *node, bool isStatic); ir::CallExpression *CreateGetOwnPropertyDescriptorCall(ir::Expression *target, ir::Expression *key); ir::CallExpression *CreateDefinePropertyCall(ir::Expression *target, ir::Expression *key, ir::Expression *value); + std::vector CreateVariableDeclarationForDecorators(ir::AstNode *node); std::vector CreateParamDecorators(util::StringView className, ir::MethodDefinition *node, + const std::vector &variableDeclarations, bool isConstructor, bool isStatic); ir::MemberExpression *CreateClassPrototype(util::StringView className); -- Gitee