From 6bd21c2a5f19fdba45c2acf4f6d5492e7355d1e4 Mon Sep 17 00:00:00 2001 From: songqi Date: Sat, 4 Feb 2023 14:17:37 +0800 Subject: [PATCH] Reset parent scope for AstNode in Transformer For nodes moved in Transformer, the parent scope of nodes should be reset to the scope after the move. Issue: I6ET0H Tests: parse/compile/tsc/262 Signed-off-by: songqi Change-Id: Iea69da5d2b66129fd0909901459f736355680529 --- es2panda/binder/scope.h | 10 +- es2panda/parser/transformer/transformer.cpp | 143 +++++++++++++++++- es2panda/parser/transformer/transformer.h | 3 + .../test-ts-class-property-1-expected.txt | 2 + .../classes/test-ts-class-property-1.ts | 30 ++++ 5 files changed, 181 insertions(+), 7 deletions(-) create mode 100644 es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-1-expected.txt create mode 100644 es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-1.ts diff --git a/es2panda/binder/scope.h b/es2panda/binder/scope.h index d2bc3419d4..4100e25ed9 100644 --- a/es2panda/binder/scope.h +++ b/es2panda/binder/scope.h @@ -234,6 +234,11 @@ public: return parent_; } + void SetParent(Scope *parent) + { + parent_ = parent; + } + const compiler::IRNode *ScopeStart() const { return startIns_; @@ -355,11 +360,6 @@ protected: bool AddLocal(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, [[maybe_unused]] ScriptExtension extension); - void SetParent(Scope *parent) - { - parent_ = parent; - } - Scope *parent_ {}; ArenaVector decls_; VariableMap bindings_; diff --git a/es2panda/parser/transformer/transformer.cpp b/es2panda/parser/transformer/transformer.cpp index d1c8b5f08b..40c5757639 100644 --- a/es2panda/parser/transformer/transformer.cpp +++ b/es2panda/parser/transformer/transformer.cpp @@ -18,6 +18,7 @@ #include #include "binder/scope.h" +#include "ir/base/catchClause.h" #include "ir/base/classDefinition.h" #include "ir/base/classProperty.h" #include "ir/base/decorator.h" @@ -30,9 +31,9 @@ #include "ir/expressions/classExpression.h" #include "ir/expressions/functionExpression.h" #include "ir/expressions/identifier.h" -#include "ir/expressions/literals/stringLiteral.h" -#include "ir/expressions/literals/numberLiteral.h" #include "ir/expressions/literals/bigIntLiteral.h" +#include "ir/expressions/literals/numberLiteral.h" +#include "ir/expressions/literals/stringLiteral.h" #include "ir/expressions/memberExpression.h" #include "ir/expressions/objectExpression.h" #include "ir/expressions/sequenceExpression.h" @@ -44,19 +45,31 @@ #include "ir/module/exportSpecifier.h" #include "ir/statements/blockStatement.h" #include "ir/statements/classDeclaration.h" +#include "ir/statements/doWhileStatement.h" #include "ir/statements/emptyStatement.h" #include "ir/statements/expressionStatement.h" +#include "ir/statements/forInStatement.h" +#include "ir/statements/forOfStatement.h" +#include "ir/statements/forUpdateStatement.h" #include "ir/statements/functionDeclaration.h" +#include "ir/statements/switchStatement.h" #include "ir/statements/variableDeclaration.h" #include "ir/statements/variableDeclarator.h" +#include "ir/statements/whileStatement.h" +#include "ir/ts/tsConstructorType.h" #include "ir/ts/tsEnumDeclaration.h" #include "ir/ts/tsEnumMember.h" +#include "ir/ts/tsFunctionType.h" #include "ir/ts/tsImportEqualsDeclaration.h" +#include "ir/ts/tsInterfaceDeclaration.h" +#include "ir/ts/tsMethodSignature.h" #include "ir/ts/tsModuleBlock.h" #include "ir/ts/tsModuleDeclaration.h" #include "ir/ts/tsParameterProperty.h" #include "ir/ts/tsPrivateIdentifier.h" #include "ir/ts/tsQualifiedName.h" +#include "ir/ts/tsSignatureDeclaration.h" +#include "ir/ts/tsTypeParameterDeclaration.h" #include "util/helpers.h" namespace panda::es2panda::parser { @@ -558,6 +571,8 @@ std::vector Transformer::VisitInstanceProperty(ir::Cl return {}; } + auto ctorScopeCtx = binder::LexicalScope::Enter(Binder(), node->Ctor()->Function()->Scope()); + ir::BlockStatement *blockStat = node->Ctor()->Function()->Body()->AsBlockStatement(); size_t insertPos = (node->Super() == nullptr) ? 0 : 1; for (auto *it : addToCtor) { @@ -571,6 +586,7 @@ std::vector Transformer::VisitInstanceProperty(ir::Cl auto assignment = AllocNode(left, it->Value(), lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + ResetParentScopeForAstNode(assignment); blockStat->AddStatementAtPos(insertPos, AllocNode(assignment)); insertPos++; } @@ -1959,4 +1975,127 @@ void Transformer::RemoveOriginNodeValueForClassPerporty(const ir::ClassDefinitio } } +void Transformer::ResetParentScopeForAstNodes(const ir::AstNode *parent) const +{ + parent->Iterate([this](auto *childNode) { ResetParentScopeForAstNode(childNode); }); +} + +void Transformer::ResetParentScopeForAstNode(ir::AstNode *childNode) const +{ + switch (childNode->Type()) { + case ir::AstNodeType::SCRIPT_FUNCTION: { + auto scope = childNode->AsScriptFunction()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::CATCH_CLAUSE: { + auto scope = childNode->AsCatchClause()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::CLASS_DEFINITION: { + auto scope = childNode->AsClassDefinition()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::BLOCK_STATEMENT: { + auto scope = childNode->AsBlockStatement()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::DO_WHILE_STATEMENT: { + auto scope = childNode->AsDoWhileStatement()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::WHILE_STATEMENT: { + auto scope = childNode->AsWhileStatement()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::FOR_IN_STATEMENT: { + auto scope = childNode->AsForInStatement()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::FOR_OF_STATEMENT: { + auto scope = childNode->AsForOfStatement()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::FOR_UPDATE_STATEMENT: { + auto scope = childNode->AsForUpdateStatement()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::SWITCH_STATEMENT: { + auto scope = childNode->AsSwitchStatement()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::TS_ENUM_DECLARATION: { + auto scope = childNode->AsTSEnumDeclaration()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::TS_INTERFACE_DECLARATION: { + auto scope = childNode->AsTSInterfaceDeclaration()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::TS_METHOD_SIGNATURE: { + auto scope = childNode->AsTSMethodSignature()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::TS_MODULE_DECLARATION: { + auto scope = childNode->AsTSModuleDeclaration()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::TS_SIGNATURE_DECLARATION: { + auto scope = childNode->AsTSSignatureDeclaration()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::TS_TYPE_PARAMETER_DECLARATION: { + auto scope = childNode->AsTSTypeParameterDeclaration()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::TS_CONSTRUCTOR_TYPE: { + auto scope = childNode->AsTSConstructorType()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + case ir::AstNodeType::TS_FUNCTION_TYPE: { + auto scope = childNode->AsTSFunctionType()->Scope(); + ASSERT(scope != nullptr); + scope->SetParent(Scope()); + break; + } + default: { + ResetParentScopeForAstNodes(childNode); + break; + } + } +} + } // namespace panda::es2panda::parser diff --git a/es2panda/parser/transformer/transformer.h b/es2panda/parser/transformer/transformer.h index fb3179ef37..d6eb2670b7 100644 --- a/es2panda/parser/transformer/transformer.h +++ b/es2panda/parser/transformer/transformer.h @@ -192,6 +192,9 @@ private: void CheckTransformedAstNodes(const ir::AstNode *parent, bool *passed) const; void CheckTransformedAstNode(const ir::AstNode *parent, ir::AstNode *childNode, bool *passed) const; + void ResetParentScopeForAstNodes(const ir::AstNode *parent) const; + void ResetParentScopeForAstNode(ir::AstNode *childNode) const; + void RemoveOriginNodeValueForClassPerporty(const ir::ClassDefinition *node); template diff --git a/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-1-expected.txt b/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-1-expected.txt new file mode 100644 index 0000000000..a5c8806279 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-1-expected.txt @@ -0,0 +1,2 @@ +3 +3 diff --git a/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-1.ts b/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-1.ts new file mode 100644 index 0000000000..8be7f48d9c --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-1.ts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 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. + */ + + +const f = (a) => {return a;} + +class C{ + constructor() { + const x=1; + function f2(){ + return x; + } + } + g = (c) => {const b = f(1) + c; print(b);return b;} +} + +var c = new C(); +print(c.g(2)); -- Gitee