From c6f3a56868561b096b03afd712e12c696a4f7197 Mon Sep 17 00:00:00 2001 From: Mikhail Ivanov Date: Mon, 19 May 2025 09:53:29 +0300 Subject: [PATCH] Collect node history Description: Update all member-functions of AstNode to collect history Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IC9FKM Signed-off-by: Mikhail Ivanov Change-Id: I8d046fc86bae17246419540b2c64f4657918b815 --- ets2panda/checker/ETSAnalyzer.cpp | 13 +- ets2panda/checker/ETSAnalyzerHelpers.cpp | 4 +- ets2panda/checker/ets/dynamic.cpp | 4 +- ets2panda/checker/ets/function.cpp | 6 +- ets2panda/checker/ets/helpers.cpp | 4 +- ets2panda/checker/ets/object.cpp | 2 +- ets2panda/checker/ets/utilityTypeHandlers.cpp | 15 +- ets2panda/compiler/core/JSCompiler.cpp | 2 +- ets2panda/compiler/core/compilerImpl.cpp | 3 +- .../compiler/lowering/ets/ambientLowering.cpp | 2 +- .../lowering/ets/asyncMethodLowering.cpp | 2 +- .../compiler/lowering/ets/boxingForLocals.cpp | 2 +- ...defaultParametersInConstructorLowering.cpp | 4 +- .../ets/defaultParametersLowering.cpp | 4 +- .../compiler/lowering/ets/enumLowering.cpp | 16 +- .../lowering/ets/exportAnonymousConst.cpp | 4 +- .../insertOptionalParametersAnnotation.cpp | 2 +- .../ets/interfaceObjectLiteralLowering.cpp | 4 +- .../compiler/lowering/ets/lambdaLowering.cpp | 12 +- .../lowering/ets/localClassLowering.cpp | 4 +- .../compiler/lowering/ets/objectIterator.cpp | 2 +- .../lowering/ets/packageImplicitImport.cpp | 2 +- .../lowering/ets/resizableArrayLowering.cpp | 2 +- .../lowering/ets/restTupleLowering.cpp | 2 +- .../ets/topLevelStmts/globalClassHandler.cpp | 24 +-- .../topLevelStmts/globalDeclTransformer.cpp | 2 +- .../ets/topLevelStmts/importExportDecls.cpp | 2 +- .../compiler/lowering/ets/unionLowering.cpp | 2 +- ets2panda/compiler/lowering/phase.cpp | 10 + ets2panda/compiler/lowering/phase.h | 17 +- .../lowering/scopesInit/savedBindingsCtx.cpp | 7 +- .../lowering/scopesInit/scopesInitPhase.cpp | 4 +- ets2panda/compiler/lowering/util.cpp | 2 +- .../debugInfoDeserialization/classBuilder.cpp | 2 +- ets2panda/evaluate/scopedDebugInfoPlugin.cpp | 4 +- ets2panda/ir/annotationAllowed.h | 26 ++- ets2panda/ir/as/namedType.cpp | 7 +- ets2panda/ir/astNode.cpp | 109 ++++++++-- ets2panda/ir/astNode.h | 127 +++++++---- ets2panda/ir/astNodeHistory.cpp | 9 + ets2panda/ir/base/classDefinition.cpp | 178 +++++++++------- ets2panda/ir/base/classDefinition.h | 199 ++++++++++++------ ets2panda/ir/base/classElement.cpp | 11 +- ets2panda/ir/base/classElement.h | 30 ++- ets2panda/ir/base/classProperty.cpp | 115 +++++----- ets2panda/ir/base/classProperty.h | 28 ++- ets2panda/ir/base/classStaticBlock.cpp | 16 +- ets2panda/ir/base/classStaticBlock.h | 24 ++- ets2panda/ir/base/methodDefinition.cpp | 134 ++++++------ ets2panda/ir/base/methodDefinition.h | 73 +++++-- ets2panda/ir/base/scriptFunction.cpp | 98 ++++++--- ets2panda/ir/base/scriptFunction.h | 124 +++++------ ets2panda/ir/base/scriptFunctionSignature.h | 1 + ets2panda/ir/ets/etsFunctionType.cpp | 48 +++-- ets2panda/ir/ets/etsFunctionType.h | 51 +++-- ets2panda/ir/ets/etsImportDeclaration.h | 53 +++-- ets2panda/ir/ets/etsModule.cpp | 5 +- ets2panda/ir/ets/etsModule.h | 50 ++++- ets2panda/ir/ets/etsNeverType.cpp | 7 +- ets2panda/ir/ets/etsNullishTypes.cpp | 14 +- ets2panda/ir/ets/etsParameterExpression.cpp | 134 +++++++----- ets2panda/ir/ets/etsParameterExpression.h | 47 ++++- ets2panda/ir/ets/etsPrimitiveType.cpp | 7 +- ets2panda/ir/ets/etsReExportDeclaration.cpp | 35 ++- ets2panda/ir/ets/etsReExportDeclaration.h | 17 +- ets2panda/ir/ets/etsStringLiteralType.cpp | 7 +- ets2panda/ir/ets/etsStructDeclaration.h | 21 ++ ets2panda/ir/ets/etsTuple.cpp | 7 +- ets2panda/ir/ets/etsTypeReference.cpp | 34 ++- ets2panda/ir/ets/etsTypeReference.h | 20 +- ets2panda/ir/ets/etsTypeReferencePart.cpp | 113 +++++----- ets2panda/ir/ets/etsTypeReferencePart.h | 54 ++++- ets2panda/ir/ets/etsUnionType.cpp | 8 +- ets2panda/ir/ets/etsWildcardType.cpp | 8 +- ets2panda/ir/expression.h | 6 +- .../expressions/arrowFunctionExpression.cpp | 7 +- ets2panda/ir/module/importDeclaration.cpp | 40 ++-- ets2panda/ir/module/importDeclaration.h | 31 ++- ets2panda/ir/opaqueTypeNode.cpp | 7 +- .../ir/statements/annotationDeclaration.cpp | 57 ++--- .../ir/statements/annotationDeclaration.h | 61 ++++-- ets2panda/ir/statements/blockStatement.cpp | 32 +-- ets2panda/ir/statements/blockStatement.h | 45 ++-- ets2panda/ir/statements/classDeclaration.cpp | 36 ++-- ets2panda/ir/statements/classDeclaration.h | 30 ++- .../ir/statements/functionDeclaration.cpp | 48 ++--- ets2panda/ir/statements/functionDeclaration.h | 50 ++++- .../ir/statements/variableDeclaration.cpp | 80 ++++--- ets2panda/ir/statements/variableDeclaration.h | 49 ++++- ets2panda/ir/ts/tsAnyKeyword.cpp | 7 +- ets2panda/ir/ts/tsArrayType.cpp | 8 +- ets2panda/ir/ts/tsBigintKeyword.cpp | 7 +- ets2panda/ir/ts/tsBooleanKeyword.cpp | 7 +- ets2panda/ir/ts/tsConditionalType.cpp | 8 +- ets2panda/ir/ts/tsConstructorType.cpp | 7 +- ets2panda/ir/ts/tsEnumDeclaration.cpp | 67 +++--- ets2panda/ir/ts/tsEnumDeclaration.h | 70 ++++-- ets2panda/ir/ts/tsFunctionType.cpp | 7 +- ets2panda/ir/ts/tsImportType.cpp | 8 +- ets2panda/ir/ts/tsIndexedAccessType.cpp | 8 +- ets2panda/ir/ts/tsInferType.cpp | 8 +- ets2panda/ir/ts/tsInterfaceDeclaration.cpp | 114 +++++----- ets2panda/ir/ts/tsInterfaceDeclaration.h | 92 +++++--- ets2panda/ir/ts/tsIntersectionType.cpp | 8 +- ets2panda/ir/ts/tsLiteralType.cpp | 8 +- ets2panda/ir/ts/tsMappedType.cpp | 8 +- ets2panda/ir/ts/tsNamedTupleMember.cpp | 8 +- ets2panda/ir/ts/tsNeverKeyword.cpp | 7 +- ets2panda/ir/ts/tsNullKeyword.cpp | 7 +- ets2panda/ir/ts/tsNumberKeyword.cpp | 7 +- ets2panda/ir/ts/tsObjectKeyword.cpp | 7 +- ets2panda/ir/ts/tsParenthesizedType.cpp | 8 +- ets2panda/ir/ts/tsStringKeyword.cpp | 7 +- ets2panda/ir/ts/tsThisType.cpp | 7 +- ets2panda/ir/ts/tsTupleType.cpp | 8 +- ets2panda/ir/ts/tsTypeAliasDeclaration.cpp | 78 ++++--- ets2panda/ir/ts/tsTypeAliasDeclaration.h | 65 ++++-- ets2panda/ir/ts/tsTypeLiteral.cpp | 8 +- ets2panda/ir/ts/tsTypeOperator.cpp | 8 +- ets2panda/ir/ts/tsTypeParameter.cpp | 64 +++--- ets2panda/ir/ts/tsTypeParameter.h | 35 ++- .../ir/ts/tsTypeParameterDeclaration.cpp | 20 +- ets2panda/ir/ts/tsTypeParameterDeclaration.h | 40 +++- ets2panda/ir/ts/tsTypePredicate.cpp | 8 +- ets2panda/ir/ts/tsTypeQuery.cpp | 8 +- ets2panda/ir/ts/tsTypeReference.cpp | 8 +- ets2panda/ir/ts/tsUndefinedKeyword.cpp | 7 +- ets2panda/ir/ts/tsUnionType.cpp | 8 +- ets2panda/ir/ts/tsUnknownKeyword.cpp | 7 +- ets2panda/ir/ts/tsVoidKeyword.cpp | 7 +- ets2panda/ir/typed.h | 11 +- ets2panda/lexer/token/sourceLocation.h | 10 + ets2panda/parser/ETSparserNamespaces.cpp | 2 +- ets2panda/public/es2panda_lib.cpp | 2 +- .../test/unit/lowerings/node_history.cpp | 20 +- ...oceed_to_state_create_function_type_ir.cpp | 2 +- .../plugin_proceed_to_state_create_import.cpp | 8 +- ...eed_to_state_create_import_declaration.cpp | 4 +- ...ed_to_state_create_non_null_expression.cpp | 4 +- ...proceed_to_state_dynamic_class_recheck.cpp | 2 +- ...oceed_to_state_find_import_declaration.cpp | 2 +- ...ugin_proceed_to_state_find_method_decl.cpp | 2 +- ...gin_proceed_to_state_function_to_arrow.cpp | 8 +- .../plugin_proceed_to_state_run_verifier.cpp | 2 +- ...in_proceed_to_state_struct_declaration.cpp | 4 +- ...roceed_to_state_test_annotation_change.cpp | 2 +- ...ed_to_state_test_class_decl_annotation.cpp | 2 +- .../plugin_proceed_to_state_update_class.cpp | 2 +- ...d_to_state_update_function_declaration.cpp | 4 +- ...eed_to_state_update_import_declaration.cpp | 4 +- ...oceed_to_state_update_import_specifier.cpp | 4 +- ...gin_proceed_to_state_update_statements.cpp | 2 +- ...ceed_to_state_update_statements_lambda.cpp | 2 +- ets2panda/test/unit/plugin/util.cpp | 4 +- .../plugin_conversion_rule_part_i.cpp | 7 +- .../ast_verifier_getter_setter_neg_test.cpp | 6 +- ets2panda/test/unit/sizeof_node_test.cpp | 25 +++ ets2panda/test/utils/ast_verifier_test.cpp | 3 + ets2panda/test/utils/ast_verifier_test.h | 1 + ets2panda/test/utils/scope_init_test.h | 9 +- ets2panda/util/enumbitops.h | 20 +- ets2panda/util/es2pandaMacros.h | 23 ++ ets2panda/util/helpers.cpp | 4 +- ets2panda/varbinder/ETSBinder.cpp | 2 +- 164 files changed, 2412 insertions(+), 1497 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index e889e393d75..18542c17671 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -267,7 +267,7 @@ void ETSAnalyzer::CheckMethodModifiers(ir::MethodDefinition *node) const auto const notValidInAbstract = ir::ModifierFlags::NATIVE | ir::ModifierFlags::PRIVATE | ir::ModifierFlags::OVERRIDE | ir::ModifierFlags::FINAL | ir::ModifierFlags::STATIC; - if (node->IsAbstract() && (node->flags_ & notValidInAbstract) != 0U) { + if (node->IsAbstract() && (node->Modifiers() & notValidInAbstract) != 0U) { checker->LogError(diagnostic::ABSTRACT_METHOD_INVALID_MODIFIER, {}, node->Start()); node->SetTsType(checker->GlobalTypeError()); return; @@ -288,14 +288,14 @@ void ETSAnalyzer::CheckMethodModifiers(ir::MethodDefinition *node) const auto const notValidInFinal = ir::ModifierFlags::ABSTRACT | ir::ModifierFlags::STATIC; - if (node->IsFinal() && (node->flags_ & notValidInFinal) != 0U) { + if (node->IsFinal() && (node->Modifiers() & notValidInFinal) != 0U) { checker->LogError(diagnostic::FINAL_METHOD_INVALID_MODIFIER, {}, node->Start()); node->SetTsType(checker->GlobalTypeError()); } auto const notValidInStatic = ir::ModifierFlags::ABSTRACT | ir::ModifierFlags::FINAL | ir::ModifierFlags::OVERRIDE; - if (node->IsStatic() && (node->flags_ & notValidInStatic) != 0U) { + if (node->IsStatic() && (node->Modifiers() & notValidInStatic) != 0U) { checker->LogError(diagnostic::STATIC_METHOD_INVALID_MODIFIER, {}, node->Start()); node->SetTsType(checker->GlobalTypeError()); } @@ -2385,10 +2385,10 @@ checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const stmt->Check(checker); // NOTE! Processing of trailing blocks was moved here so that smart casts could be applied correctly - if (auto const tb = st->trailingBlocks_.find(stmt); tb != st->trailingBlocks_.end()) { + if (auto const tb = st->TrailingBlocks().find(stmt); tb != st->TrailingBlocks().end()) { auto *const trailingBlock = tb->second; trailingBlock->Check(checker); - st->Statements().emplace(std::next(st->Statements().begin() + idx), trailingBlock); + st->StatementsMutable().emplace(std::next(st->StatementsMutable().begin() + idx), trailingBlock); ++idx; } } @@ -2724,7 +2724,8 @@ static bool CheckIsValidReturnTypeAnnotation(ir::ReturnStatement *st, ir::Script ir::TypeNode *returnTypeAnnotation, ETSChecker *checker) { // check valid `this` type as return type - if (containingFunc->GetPreferredReturnType() != nullptr || !returnTypeAnnotation->IsTSThisType()) { + if (containingFunc->GetPreferredReturnType() != nullptr || + !(returnTypeAnnotation != nullptr && returnTypeAnnotation->IsTSThisType())) { return true; } diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index f652f68e788..ce51c3016e4 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -420,7 +420,7 @@ checker::Signature *GetMostSpecificSigFromExtensionFuncAndClassMethod(checker::E methodCallSig->GetSignatureInfo()->minArgCount++; auto ¶msVar = methodCallSig->Params(); paramsVar.insert(paramsVar.begin(), dummyReceiverVar); - auto ¶ms = methodCallSig->Function()->Params(); + auto ¶ms = methodCallSig->Function()->ParamsMutable(); params.insert(params.begin(), dummyReceiver); if (typeParamsNeeded) { auto &typeParams = methodCallSig->TypeParams(); @@ -436,7 +436,7 @@ checker::Signature *GetMostSpecificSigFromExtensionFuncAndClassMethod(checker::E methodCallSig->GetSignatureInfo()->minArgCount--; auto ¶msVar = methodCallSig->Params(); paramsVar.erase(paramsVar.begin()); - auto ¶ms = methodCallSig->Function()->Params(); + auto ¶ms = methodCallSig->Function()->ParamsMutable(); params.erase(params.begin()); if (typeParamsNeeded) { auto &typeParams = methodCallSig->TypeParams(); diff --git a/ets2panda/checker/ets/dynamic.cpp b/ets2panda/checker/ets/dynamic.cpp index 90abef0f888..bb18641b6b1 100644 --- a/ets2panda/checker/ets/dynamic.cpp +++ b/ets2panda/checker/ets/dynamic.cpp @@ -365,7 +365,7 @@ ir::ClassDeclaration *ETSChecker::BuildClass(util::StringView name, const ClassB // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *classDecl = ProgramAllocNode(classDef, ProgramAllocator()); - VarBinder()->Program()->Ast()->Statements().push_back(classDecl); + VarBinder()->Program()->Ast()->StatementsMutable().push_back(classDecl); classDecl->SetParent(VarBinder()->Program()->Ast()); auto varBinder = VarBinder()->AsETSBinder(); @@ -597,7 +597,7 @@ void ETSChecker::EmitDynamicModuleClassInitCall() // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *const node = ProgramAllocNode(initCall); node->SetParent(cctorBody); - cctorBody->Statements().push_back(node); + cctorBody->StatementsMutable().push_back(node); ProcessScopesNode(this, node); ProcessCheckerNode(this, node); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 41e6c334e1b..70483ae2ed5 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -229,7 +229,7 @@ static void ResetInferredNode(ETSChecker *checker) auto resetFuncState = [](ir::ArrowFunctionExpression *expr) { auto *func = expr->Function(); func->SetSignature(nullptr); - func->ReturnStatements().clear(); + func->ReturnStatementsMutable().clear(); expr->SetTsType(nullptr); }; @@ -1099,7 +1099,7 @@ Signature *ETSChecker::ResolvePotentialTrailingLambdaWithReceiver(ir::CallExpres auto *candidateFunctionType = sig->Function()->Params().back()->AsETSParameterExpression()->TypeAnnotation()->AsETSFunctionType(); auto *currentReceiver = candidateFunctionType->Params()[0]; - trailingLambda->Function()->Params().emplace_back(currentReceiver); + trailingLambda->Function()->ParamsMutable().emplace_back(currentReceiver); sigContainLambdaWithReceiverAsParam.emplace_back(sig); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) signature = ValidateSignatures(sigContainLambdaWithReceiverAsParam, callExpr->TypeParams(), arguments, @@ -1109,7 +1109,7 @@ Signature *ETSChecker::ResolvePotentialTrailingLambdaWithReceiver(ir::CallExpres return signature; } sigContainLambdaWithReceiverAsParam.clear(); - trailingLambda->Function()->Params().clear(); + trailingLambda->Function()->ParamsMutable().clear(); } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return ValidateSignatures(normalSig, callExpr->TypeParams(), arguments, callExpr->Start(), "call", diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 95f7eed99f9..dec7e2f7797 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2823,7 +2823,7 @@ ir::ClassProperty *GetImplementationClassProp(ETSChecker *checker, ir::ClassProp auto *const classProp = checker->ClassPropToImplementationProp( interfaceProp->Clone(checker->ProgramAllocator(), originalProp->Parent()), scope); classType->AddProperty(classProp->Key()->Variable()->AsLocalVariable()); - classDef->Body().push_back(classProp); + classDef->BodyMutable().push_back(classProp); return classProp; } @@ -2890,7 +2890,7 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ir::MethodDefinition *getter = GenerateDefaultGetterSetter(interfaceProp, classProp, scope, false, this); - classDef->Body().push_back(getter); + classDef->BodyMutable().push_back(getter); const auto &name = getter->Key()->AsIdentifier()->Name(); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index c5724a9d7e1..b6afe5998aa 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -2414,7 +2414,7 @@ void ETSChecker::TransformProperties(ETSObjectType *classType) auto it = classDef->Body().begin(); while (it != classDef->Body().end()) { if ((*it)->IsClassProperty() && ((*it)->Modifiers() & ir::ModifierFlags::GETTER_SETTER) != 0U) { - it = classDef->Body().erase(it); + it = classDef->BodyMutable().erase(it); } else { ++it; } diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index b2d95bd91d7..8f974f73380 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -465,7 +465,7 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla auto *const newProp = CreateNullishProperty(prop->AsClassProperty(), newClassDefinition); // Put the new property into the class declaration - newClassDefinition->Body().emplace_back(newProp); + newClassDefinition->BodyMutable().emplace_back(newProp); } if (prop->IsMethodDefinition() && (prop->AsMethodDefinition()->Function()->IsGetter() || @@ -476,7 +476,10 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla continue; } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - newClassDefinition->Body().emplace_back(CreateNullishPropertyFromAccessor(method, newClassDefinition)); + auto *const newProp = CreateNullishPropertyFromAccessor(method, newClassDefinition); + + // Put the new property into the class declaration + newClassDefinition->BodyMutable().emplace_back(newProp); } } if (classDef->IsDeclare()) { @@ -599,7 +602,7 @@ ir::TSInterfaceDeclaration *ETSChecker::CreateInterfaceProto(util::StringView na // Put class declaration in global scope, and in program AST partialInterface->SetParent(interfaceDeclProgram->Ast()); - interfaceDeclProgram->Ast()->Statements().push_back(partialInterface); + interfaceDeclProgram->Ast()->StatementsMutable().push_back(partialInterface); interfaceDeclProgram->GlobalScope()->InsertBinding(name, var); partialInterface->AddModifier(flags); @@ -701,7 +704,7 @@ Type *ETSChecker::CreatePartialTypeInterfaceDecl(ir::TSInterfaceDeclaration *con // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) BuildSuperPartialTypeReference(superPartialType, superPartialRefTypeParams); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - partialInterface->Extends().push_back(ProgramAllocNode(superPartialRef)); + partialInterface->ExtendsMutable().push_back(ProgramAllocNode(superPartialRef)); partialInterface->Extends().back()->SetParent(partialInterface); } } @@ -739,7 +742,7 @@ void ETSChecker::CreateConstructorForPartialType(ir::ClassDefinition *const part ctor->Id()->SetVariable(ctorId->Variable()); // Put ctor in partial class body - partialClassDef->Body().emplace_back(ctor); + partialClassDef->BodyMutable().emplace_back(ctor); } ir::ClassDefinition *ETSChecker::CreateClassPrototype(util::StringView name, parser::Program *const classDeclProgram) @@ -772,7 +775,7 @@ ir::ClassDefinition *ETSChecker::CreateClassPrototype(util::StringView name, par decl->BindNode(classDef); // Put class declaration in global scope, and in program AST - classDeclProgram->Ast()->Statements().push_back(classDecl); + classDeclProgram->Ast()->StatementsMutable().push_back(classDecl); classDeclProgram->GlobalScope()->InsertBinding(name, var); return classDef; diff --git a/ets2panda/compiler/core/JSCompiler.cpp b/ets2panda/compiler/core/JSCompiler.cpp index b7cb2f00d37..c12fb83b907 100644 --- a/ets2panda/compiler/core/JSCompiler.cpp +++ b/ets2panda/compiler/core/JSCompiler.cpp @@ -395,7 +395,7 @@ void JSCompiler::Compile(const ir::ClassDefinition *node) const compiler::LocalRegScope lrs(pg, node->Scope()); compiler::VReg baseReg = CompileHeritageClause(pg, node); - util::StringView ctorId = node->Ctor()->Function()->Scope()->InternalName(); + util::StringView ctorId = node->CtorValue()->Function()->Scope()->InternalName(); util::BitSet compiled(node->Body().size()); auto [bufIdx, privateBuf] = CreateClassStaticProperties(pg, compiled, node->Body()); diff --git a/ets2panda/compiler/core/compilerImpl.cpp b/ets2panda/compiler/core/compilerImpl.cpp index af038f7485b..5b80fe45b4f 100644 --- a/ets2panda/compiler/core/compilerImpl.cpp +++ b/ets2panda/compiler/core/compilerImpl.cpp @@ -438,7 +438,8 @@ static pandasm::Program *Compile(const CompilationUnit &unit, CompilerImpl *comp auto checker = Checker(unit.diagnosticEngine, context->allocator); context->checker = &checker; auto analyzer = Analyzer(&checker); - auto phaseManager = compiler::PhaseManager(unit.ext, context->allocator); + auto phaseManager = compiler::PhaseManager(unit.ext, context->allocator, + unit.options.GetCompilationMode() == CompilationMode::PROJECT); checker.SetAnalyzer(&analyzer); context->analyzer = checker.GetAnalyzer(); context->parserProgram = &program; diff --git a/ets2panda/compiler/lowering/ets/ambientLowering.cpp b/ets2panda/compiler/lowering/ets/ambientLowering.cpp index b07f25dc9b6..3d47bb3c88b 100644 --- a/ets2panda/compiler/lowering/ets/ambientLowering.cpp +++ b/ets2panda/compiler/lowering/ets/ambientLowering.cpp @@ -93,7 +93,7 @@ ir::AstNode *AmbientLowering::CreateIndexerMethodIfNeeded(ir::AstNode *ast, publ } ArenaVector &classBody = - ast->IsClassDefinition() ? ast->AsClassDefinition()->Body() : ast->AsTSInterfaceBody()->Body(); + ast->IsClassDefinition() ? ast->AsClassDefinition()->BodyMutable() : ast->AsTSInterfaceBody()->Body(); auto it = classBody.begin(); // Only one DummyNode is allowed in classBody for now diff --git a/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp b/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp index d801b5526c2..9f17b441a5a 100644 --- a/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp +++ b/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp @@ -170,7 +170,7 @@ void ComposeAsyncImplMethod(checker::ETSChecker *checker, ir::MethodDefinition * implMethod->Function()->Id()->SetVariable(baseOverloadImplMethod->Function()->Id()->Variable()); baseOverloadImplMethod->AddOverload(implMethod); } else { - classDef->Body().push_back(implMethod); + classDef->BodyMutable().push_back(implMethod); } } diff --git a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp index 2f63e742225..f0874aed5c5 100644 --- a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp +++ b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp @@ -128,7 +128,7 @@ static void HandleFunctionParam(public_lib::Context *ctx, ir::ETSParameterExpres auto *func = param->Parent()->AsScriptFunction(); ES2PANDA_ASSERT(func->Body()->IsBlockStatement()); // guaranteed after expressionLambdaLowering auto *body = func->Body()->AsBlockStatement(); - auto &bodyStmts = body->Statements(); + auto &bodyStmts = body->StatementsMutable(); auto *scope = body->Scope(); auto *initId = allocator->New(id->Name(), allocator); diff --git a/ets2panda/compiler/lowering/ets/defaultParametersInConstructorLowering.cpp b/ets2panda/compiler/lowering/ets/defaultParametersInConstructorLowering.cpp index d9ede70dc70..1a0bb99138f 100644 --- a/ets2panda/compiler/lowering/ets/defaultParametersInConstructorLowering.cpp +++ b/ets2panda/compiler/lowering/ets/defaultParametersInConstructorLowering.cpp @@ -185,7 +185,7 @@ static void CreateFunctionOverload(ir::MethodDefinition *method, ArenaVectorSetRange(funcExpression->Range()); if (!method->IsDeclare() && method->Parent()->IsTSInterfaceBody()) { - overloadMethod->Function()->Body()->AsBlockStatement()->Statements().clear(); + overloadMethod->Function()->Body()->AsBlockStatement()->StatementsMutable().clear(); } method->AddOverload(overloadMethod); @@ -214,7 +214,7 @@ static void ClearOptionalParameters(public_lib::Context *ctx, ir::ScriptFunction { auto allocator = ctx->allocator; - for (auto *¶m : function->Params()) { + for (auto *¶m : function->ParamsMutable()) { auto oldParam = param->AsETSParameterExpression(); if (oldParam->IsOptional()) { param = util::NodeAllocator::ForceSetParent(allocator, oldParam->Ident(), false, diff --git a/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp b/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp index d87fc777fd5..1ca094dd002 100644 --- a/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp +++ b/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp @@ -69,12 +69,12 @@ static void TransformFunction(public_lib::Context *ctx, ir::ScriptFunction *func auto const allocator = ctx->allocator; auto const parser = ctx->parser->AsETSParser(); - body->Statements().insert(body->Statements().begin(), defaultParams.size(), nullptr); + body->StatementsMutable().insert(body->StatementsMutable().begin(), defaultParams.size(), nullptr); for (size_t dfltIdx = 0; dfltIdx < defaultParams.size(); ++dfltIdx) { auto const param = defaultParams.at(dfltIdx); auto stmt = TransformInitializer(allocator, parser, param); - body->Statements()[dfltIdx] = stmt; + body->StatementsMutable()[dfltIdx] = stmt; stmt->SetParent(body); } } diff --git a/ets2panda/compiler/lowering/ets/enumLowering.cpp b/ets2panda/compiler/lowering/ets/enumLowering.cpp index f16b4cd6019..4016c2748ec 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumLowering.cpp @@ -60,7 +60,7 @@ ir::MethodDefinition *MakeMethodDef(public_lib::Context *ctx, ir::ClassDefinitio auto *const methodDef = ctx->AllocNode( ir::MethodDefinitionKind::METHOD, identClone, functionExpr, function->Modifiers(), ctx->Allocator(), false); methodDef->SetParent(enumClass); - enumClass->Body().push_back(methodDef); + enumClass->BodyMutable().push_back(methodDef); return methodDef; } @@ -152,7 +152,7 @@ template arrayIdent, arrayExpr, typeAnnotation, ir::ModifierFlags::STATIC | ir::ModifierFlags::PRIVATE | ir::ModifierFlags::READONLY, Allocator(), false); arrayClassProp->SetParent(enumClass); - enumClass->Body().push_back(arrayClassProp); + enumClass->BodyMutable().push_back(arrayClassProp); return arrayIdent; } @@ -208,7 +208,7 @@ void EnumLoweringPhase::CreateEnumItemFields(const ir::TSEnumDeclaration *const return field; }; for (auto *const member : enumDecl->Members()) { - enumClass->Body().push_back(createEnumItemField(member->AsTSEnumMember())); + enumClass->BodyMutable().push_back(createEnumItemField(member->AsTSEnumMember())); } } @@ -316,7 +316,7 @@ void EnumLoweringPhase::CreateCCtorForEnumClass(ir::ClassDefinition *const enumC AllocNode(ir::MethodDefinitionKind::METHOD, identClone, funcExpr, ir::ModifierFlags::PRIVATE | ir::ModifierFlags::STATIC, Allocator(), false); methodDef->SetParent(enumClass); - enumClass->Body().push_back(methodDef); + enumClass->BodyMutable().push_back(methodDef); } ir::ClassProperty *EnumLoweringPhase::CreateOrdinalField(ir::ClassDefinition *const enumClass) @@ -327,7 +327,7 @@ ir::ClassProperty *EnumLoweringPhase::CreateOrdinalField(ir::ClassDefinition *co AllocNode(fieldIdent, nullptr, intTypeAnnotation, ir::ModifierFlags::PRIVATE | ir::ModifierFlags::READONLY, Allocator(), false); - enumClass->Body().push_back(field); + enumClass->BodyMutable().push_back(field); field->SetParent(enumClass); return field; } @@ -377,7 +377,7 @@ ir::ScriptFunction *EnumLoweringPhase::CreateFunctionForCtorOfEnumClass(ir::Clas auto *superConstructorCall = AllocNode(callee, std::move(callArguments), nullptr, false); auto *superCallStatement = AllocNode(superConstructorCall); superCallStatement->SetParent(body); - body->Statements().push_back(superCallStatement); + body->StatementsMutable().push_back(superCallStatement); auto *thisExpr = Allocator()->New(); auto *fieldIdentifier = Allocator()->New(ORDINAL_NAME, Allocator()); @@ -389,7 +389,7 @@ ir::ScriptFunction *EnumLoweringPhase::CreateFunctionForCtorOfEnumClass(ir::Clas AllocNode(leftHandSide, rightHandSide, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); auto initStatement = AllocNode(initializer); initStatement->SetParent(body); - body->Statements().push_back(initStatement); + body->StatementsMutable().push_back(initStatement); return func; } @@ -403,7 +403,7 @@ void EnumLoweringPhase::CreateCtorForEnumClass(ir::ClassDefinition *const enumCl auto *const methodDef = AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, identClone, funcExpr, ir::ModifierFlags::PUBLIC, Allocator(), false); methodDef->SetParent(enumClass); - enumClass->Body().push_back(methodDef); + enumClass->BodyMutable().push_back(methodDef); } void EnumLoweringPhase::ProcessEnumClassDeclaration(ir::TSEnumDeclaration *const enumDecl, diff --git a/ets2panda/compiler/lowering/ets/exportAnonymousConst.cpp b/ets2panda/compiler/lowering/ets/exportAnonymousConst.cpp index 3cb3fd1c242..3d251c6ddc3 100644 --- a/ets2panda/compiler/lowering/ets/exportAnonymousConst.cpp +++ b/ets2panda/compiler/lowering/ets/exportAnonymousConst.cpp @@ -64,7 +64,7 @@ static void HandleAnonymousConst(public_lib::Context *const ctx, parser::Program auto *anonymousVariableDecl = CreateAnonymousVariableDecl(ctx, (*iterator)->AsExportNamedDeclaration())->AsStatement(); - module->Statements().insert(iterator, anonymousVariableDecl); + module->StatementsMutable().insert(iterator, anonymousVariableDecl); } static void HandleExportDefaultInExportNamedDecl(public_lib::Context *const ctx, parser::Program *const program) @@ -110,7 +110,7 @@ static void HandleExportDefaultInExportNamedDecl(public_lib::Context *const ctx, newSpecifiers.push_back(specifier); } - module->Statements().insert(iterator, exportDefaulNamedDeclarations.front()); + module->StatementsMutable().insert(iterator, exportDefaulNamedDeclarations.front()); exportNamedDeclaration->ReplaceSpecifiers(newSpecifiers); exportNamedDeclaration->ClearModifier(ir::ModifierFlags::DEFAULT_EXPORT); } diff --git a/ets2panda/compiler/lowering/ets/insertOptionalParametersAnnotation.cpp b/ets2panda/compiler/lowering/ets/insertOptionalParametersAnnotation.cpp index d8bd398120e..db97546a76f 100644 --- a/ets2panda/compiler/lowering/ets/insertOptionalParametersAnnotation.cpp +++ b/ets2panda/compiler/lowering/ets/insertOptionalParametersAnnotation.cpp @@ -98,7 +98,7 @@ static void TryInsertDefaultAnnotation(public_lib::Context *ctx, ir::AstNode *no auto methodFunc = methodDef->Function(); auto defaultAnno = CreateDefaultAnnotationUsageForFunction(ctx, methodFunc); if (defaultAnno != nullptr) { - methodFunc->Annotations().emplace_back(defaultAnno->AsAnnotationUsage()); + methodFunc->AnnotationsMutable().emplace_back(defaultAnno->AsAnnotationUsage()); defaultAnno->SetParent(methodFunc); RefineSourceRanges(defaultAnno); } diff --git a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp index 7b00e071ae2..41b0baeaba1 100644 --- a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp @@ -204,7 +204,7 @@ static void AnnotateGeneratedAnonClass(checker::ETSChecker *checker, ir::ClassDe annoUsage->AddModifier(ir::ModifierFlags::ANNOTATION_USAGE); annoUsage->SetParent(classDef); annoId->SetParent(annoUsage); - classDef->Annotations().emplace_back(annoUsage); + classDef->AnnotationsMutable().emplace_back(annoUsage); RefineSourceRanges(annoUsage); CheckLoweredNode(checker->VarBinder()->AsETSBinder(), checker, annoUsage); } @@ -255,7 +255,7 @@ static void GenerateAnonClassTypeFromInterface(public_lib::Context *ctx, ir::TSI auto *classImplements = ctx->AllocNode( ctx->AllocNode(ifaceNode->TsType(), ctx->Allocator())); classImplements->SetParent(classDef); - classDef->Implements().emplace_back(classImplements); + classDef->ImplementsMutable().emplace_back(classImplements); classType->RemoveObjectFlag(checker::ETSObjectFlags::RESOLVED_INTERFACES); checker->GetInterfacesOfClass(classType); diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 15f279ea37e..02de187608b 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -278,7 +278,7 @@ static ir::MethodDefinition *SetUpCalleeMethod(public_lib::Context *ctx, LambdaI auto *funcExpr = util::NodeAllocator::ForceSetParent(allocator, func); auto *method = util::NodeAllocator::ForceSetParent( allocator, ir::MethodDefinitionKind::METHOD, calleeNameClone, funcExpr, modifierFlags, allocator, false); - calleeClass->Definition()->Body().push_back(method); + calleeClass->Definition()->BodyMutable().push_back(method); method->SetParent(calleeClass->Definition()); auto *var = @@ -491,7 +491,7 @@ static void CreateLambdaClassConstructor(public_lib::Context *ctx, ir::ClassDefi allocator, ir::MethodDefinitionKind::CONSTRUCTOR, constructorId->Clone(allocator, nullptr), funcExpr, ir::ModifierFlags::NONE, allocator, false); - classDefinition->Body().push_back(ctor); + classDefinition->BodyMutable().push_back(ctor); ctor->SetParent(classDefinition); } @@ -560,7 +560,7 @@ static ArenaVector CreateRestArgumentsArrayReall checker->MaybeBoxType(elementType), restParameterIndex, restParameterIndex); } - return ArenaVector(std::move(args->AsBlockStatement()->Statements())); + return ArenaVector(std::move(args->AsBlockStatement()->StatementsMutable())); } static void CreateInvokeMethodRestParameter(public_lib::Context *ctx, LambdaClassInvokeInfo *lciInfo, @@ -738,7 +738,7 @@ static void CreateLambdaClassInvokeMethod(public_lib::Context *ctx, LambdaInfo c false); ES2PANDA_ASSERT(!invokeMethod->IsStatic()); - lciInfo->classDefinition->Body().push_back(invokeMethod); + lciInfo->classDefinition->BodyMutable().push_back(invokeMethod); invokeMethod->SetParent(lciInfo->classDefinition); } @@ -822,7 +822,7 @@ static ir::ClassDeclaration *CreateEmptyLambdaClassDeclaration(public_lib::Conte auto *classDefinition = classDeclaration->Definition(); // Adjust the class definition compared to what the parser gives. - classDefinition->Body().clear(); // remove the default empty constructor + classDefinition->BodyMutable().clear(); // remove the default empty constructor classDefinition->AddModifier(ir::ModifierFlags::PUBLIC | ir::ModifierFlags::FUNCTIONAL); if (newTypeParams != nullptr) { classDefinition->SetTypeParams(newTypeParams); @@ -830,7 +830,7 @@ static ir::ClassDeclaration *CreateEmptyLambdaClassDeclaration(public_lib::Conte } auto *program = varBinder->GetRecordTable()->Program(); - program->Ast()->Statements().push_back(classDeclaration); + program->Ast()->StatementsMutable().push_back(classDeclaration); classDeclaration->SetParent(program->Ast()); return classDeclaration; diff --git a/ets2panda/compiler/lowering/ets/localClassLowering.cpp b/ets2panda/compiler/lowering/ets/localClassLowering.cpp index a9b4095219f..34b1921329e 100644 --- a/ets2panda/compiler/lowering/ets/localClassLowering.cpp +++ b/ets2panda/compiler/lowering/ets/localClassLowering.cpp @@ -126,7 +126,7 @@ void LocalClassConstructionPhase::ModifyConstructorParameters( for (auto *signature : classType->ConstructSignatures()) { LOG(DEBUG, ES2PANDA) << " - Modifying Constructor: " << signature->InternalName(); auto constructor = signature->Function(); - auto ¶meters = constructor->Params(); + auto ¶meters = constructor->ParamsMutable(); auto &sigParams = signature->Params(); signature->GetSignatureInfo()->minArgCount += capturedVars.size(); @@ -170,7 +170,7 @@ void LocalClassConstructionPhase::ModifyConstructorParameters( initStatements.push_back(initStatement); } if (body != nullptr && body->IsBlockStatement()) { - auto &statements = body->AsBlockStatement()->Statements(); + auto &statements = body->AsBlockStatement()->StatementsMutable(); statements.insert(statements.begin(), initStatements.begin(), initStatements.end()); } } diff --git a/ets2panda/compiler/lowering/ets/objectIterator.cpp b/ets2panda/compiler/lowering/ets/objectIterator.cpp index cf43ac31d1e..fda8b51fd41 100644 --- a/ets2panda/compiler/lowering/ets/objectIterator.cpp +++ b/ets2panda/compiler/lowering/ets/objectIterator.cpp @@ -54,7 +54,7 @@ void ObjectIteratorLowering::TransferForOfLoopBody(ir::Statement *const forBody, ir::BlockStatement *const whileBody) const noexcept { ES2PANDA_ASSERT(forBody != nullptr && whileBody != nullptr); - auto &whileStatements = whileBody->Statements(); + auto &whileStatements = whileBody->StatementsMutable(); // Currently while loop body consists of 2 statements: 'x = it.value!' and 'it = ci.next()' // We need to insert the body of original for-of-loop between them, change their parent and diff --git a/ets2panda/compiler/lowering/ets/packageImplicitImport.cpp b/ets2panda/compiler/lowering/ets/packageImplicitImport.cpp index fae3b44254e..4eb69bfb1db 100644 --- a/ets2panda/compiler/lowering/ets/packageImplicitImport.cpp +++ b/ets2panda/compiler/lowering/ets/packageImplicitImport.cpp @@ -32,7 +32,7 @@ static void MergeExternalFilesIntoCompiledProgram(parser::Program *const program // Because same package files must be in one folder, relative path references in an external // source's import declaration certainly will be the same (and can be resolved) from the global program too - program->Ast()->Statements().emplace_back(stmt); + program->Ast()->StatementsMutable().emplace_back(stmt); } } } diff --git a/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp b/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp index 12d58293e39..5a40d7c578c 100644 --- a/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp +++ b/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp @@ -27,7 +27,7 @@ static ir::AstNode *ConvertToResizableArrayType(ir::TSArrayType *node, public_li auto *parser = ctx->parser->AsETSParser(); ir::TypeNode *typeAnnotation = parser->CreateFormattedTypeAnnotation("Array<" + node->ElementType()->DumpEtsSrc() + ">"); - typeAnnotation->SetAnnotations(std::move(node->Annotations())); + typeAnnotation->SetAnnotations(std::move(node->AnnotationsMutable())); typeAnnotation->SetParent(node->Parent()); typeAnnotation->SetRange(node->Range()); RefineSourceRanges(node); diff --git a/ets2panda/compiler/lowering/ets/restTupleLowering.cpp b/ets2panda/compiler/lowering/ets/restTupleLowering.cpp index 7e9724a1bf1..aa9ead6ca22 100644 --- a/ets2panda/compiler/lowering/ets/restTupleLowering.cpp +++ b/ets2panda/compiler/lowering/ets/restTupleLowering.cpp @@ -368,7 +368,7 @@ void CreateNewMethod(public_lib::Context *ctx, ir::AstNode *node) // Build new methodDefinition auto *const methodDef = CreateNewMethodDefinition(ctx, definition->AsMethodDefinition(), function); - node->AsClassDefinition()->Body().push_back(methodDef); + node->AsClassDefinition()->BodyMutable().push_back(methodDef); } } } diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp index a914f8ad66a..ad3c8d72502 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp @@ -42,7 +42,7 @@ void GlobalClassHandler::AddStaticBlockToClass(ir::AstNode *node) if (node->IsClassDefinition() && !node->AsClassDefinition()->IsDeclare()) { auto classDef = node->AsClassDefinition(); if (auto staticBlock = CreateStaticBlock(classDef); staticBlock != nullptr) { - classDef->Body().emplace_back(staticBlock); // NOTE(vpukhov): inserted to end for some reason + classDef->BodyMutable().emplace_back(staticBlock); // NOTE(vpukhov): inserted to end for some reason staticBlock->SetParent(classDef); } } @@ -103,7 +103,7 @@ ir::ClassDeclaration *GlobalClassHandler::CreateTransformedClass(ir::ETSModule * static void InsertInGlobal(ir::ClassDefinition *globalClass, ir::AstNode *node) { - globalClass->Body().insert(globalClass->Body().begin(), node); + globalClass->BodyMutable().insert(globalClass->BodyMutable().begin(), node); node->SetParent(globalClass); } @@ -165,10 +165,10 @@ void GlobalClassHandler::MergeNamespace(ArenaVector &namespaces parser->LogError(diagnostic::NAMESPACE_ANNOTATION_CONFLICT, {ns->Ident()->Name().Mutf8()}, ns->Start()); } else if (!ns->Annotations().empty()) { ES2PANDA_ASSERT(res->second->Annotations().empty()); - res->second->SetAnnotations(std::move(ns->Annotations())); + res->second->SetAnnotations(std::move(ns->AnnotationsMutable())); } for (auto *statement : ns->Statements()) { - res->second->Statements().emplace_back(statement); + res->second->StatementsMutable().emplace_back(statement); } namespaces.erase(it); } else { @@ -197,7 +197,7 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns, ArenaVector immediateInitializers(allocator_->Adapter()); ArenaVector initializerBlock(allocator_->Adapter()); ArenaVector namespaces(allocator_->Adapter()); - auto &body = ns->Statements(); + auto &body = ns->StatementsMutable(); for (auto *statement : body) { statement->Iterate([this](ir::AstNode *node) { AddStaticBlockToClass(node); }); } @@ -224,14 +224,14 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns, body.erase(end, body.end()); auto globalClasses = TransformNamespaces(namespaces, program); for (auto *cls : globalClasses) { - globalClass->Body().emplace_back(cls); + globalClass->BodyMutable().emplace_back(cls); cls->SetParent(globalClass); CollectNamespaceExportedClasses(cls->Definition()); } // Add rest statement, such as type declaration for (auto *statement : body) { - globalClass->Body().emplace_back(statement); + globalClass->BodyMutable().emplace_back(statement); statement->SetParent(globalClass); } body.clear(); @@ -242,7 +242,7 @@ void GlobalClassHandler::CollectProgramGlobalClasses(parser::Program *program, A { auto classDecls = TransformNamespaces(namespaces, program); for (auto cls : classDecls) { - program->Ast()->Statements().push_back(cls); + program->Ast()->StatementsMutable().push_back(cls); cls->SetParent(program->Ast()); CollectNamespaceExportedClasses(cls->Definition()); } @@ -288,7 +288,7 @@ void GlobalClassHandler::SetupGlobalClass(const ArenaVector & for (auto program : programs) { program->Ast()->IterateRecursively([this](ir::AstNode *node) { AddStaticBlockToClass(node); }); - auto &body = program->Ast()->Statements(); + auto &body = program->Ast()->StatementsMutable(); auto stmts = CollectProgramGlobalStatements(body, globalClass, program->Ast()); auto end = std::remove_if(body.begin(), body.end(), [&namespaces](ir::AstNode *node) { if (node->IsETSModule() && node->AsETSModule()->IsNamespace()) { @@ -306,7 +306,7 @@ void GlobalClassHandler::SetupGlobalClass(const ArenaVector & program->SetGlobalClass(globalClass); } - globalProgram->Ast()->Statements().emplace_back(globalDecl); + globalProgram->Ast()->StatementsMutable().emplace_back(globalDecl); globalDecl->SetParent(globalProgram->Ast()); globalClass->SetGlobalInitialized(); CollectProgramGlobalClasses(globalProgram, namespaces); @@ -367,7 +367,7 @@ void GlobalClassHandler::AddInitializerBlockToStaticBlock(ir::ClassDefinition *g auto *blockBody = staticBlock->Function()->Body()->AsBlockStatement(); initializerStmts->SetParent(blockBody); - blockBody->Statements().emplace_back(initializerStmts); + blockBody->StatementsMutable().emplace_back(initializerStmts); } void GlobalClassHandler::AddInitCallToStaticBlock(ir::ClassDefinition *globalClass, ir::MethodDefinition *initMethod) @@ -388,7 +388,7 @@ void GlobalClassHandler::AddInitCallToStaticBlock(ir::ClassDefinition *globalCla auto *blockBody = staticBlock->Function()->Body()->AsBlockStatement(); auto exprStmt = NodeAllocator::Alloc(allocator_, callExpr); exprStmt->SetParent(blockBody); - blockBody->Statements().emplace_back(exprStmt); + blockBody->StatementsMutable().emplace_back(exprStmt); } ir::Identifier *GlobalClassHandler::RefIdent(const util::StringView &name) diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp index 8e3afe694c1..1ae10758b42 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp @@ -58,7 +58,7 @@ void GlobalDeclTransformer::VisitFunctionDeclaration(ir::FunctionDeclaration *fu allocator_, methodKind, funcDecl->Function()->Id()->Clone(allocator_, nullptr), funcExpr, funcDecl->Function()->Modifiers(), allocator_, false); method->SetRange(funcDecl->Range()); - method->Function()->SetAnnotations(std::move(funcDecl->Annotations())); + method->Function()->SetAnnotations(std::move(funcDecl->AnnotationsMutable())); if (funcDecl->Function()->IsExported() && funcDecl->Function()->HasExportAlias()) { method->AddAstNodeFlags(ir::AstNodeFlags::HAS_EXPORT_ALIAS); diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp index aa76dbdc450..35cb774ca05 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp @@ -318,7 +318,7 @@ void ImportExportDecls::PreMergeNamespaces(parser::Program *program) } ArenaVector namespaces(program->Allocator()->Adapter()); - auto &body = ast->AsETSModule()->Statements(); + auto &body = ast->AsETSModule()->StatementsMutable(); auto originalSize = body.size(); auto end = std::remove_if(body.begin(), body.end(), [&namespaces](ir::AstNode *node) { if (node->IsETSModule() && node->AsETSModule()->IsNamespace()) { diff --git a/ets2panda/compiler/lowering/ets/unionLowering.cpp b/ets2panda/compiler/lowering/ets/unionLowering.cpp index 2df65448a02..94b35945161 100644 --- a/ets2panda/compiler/lowering/ets/unionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unionLowering.cpp @@ -72,7 +72,7 @@ static ir::ClassDefinition *GetUnionAccessClass(public_lib::Context *ctx, varbin auto globalBlock = varbinder->Program()->Ast(); classDecl->SetParent(globalBlock); - globalBlock->Statements().push_back(classDecl); + globalBlock->StatementsMutable().push_back(classDecl); classDecl->Check(checker); return classDef; } diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 41cf70c6afe..7ea38822be9 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -242,6 +242,16 @@ void SetPhaseManager(PhaseManager *phaseManager) g_phaseManager = phaseManager; } +void PhaseManager::Restart() +{ + prev_ = INVALID_PHASE_ID; + curr_ = PARSER_PHASE_ID; + next_ = PARSER_PHASE_ID + 1; + ES2PANDA_ASSERT(next_ == 0); + + SetPhaseManager(this); +} + bool Phase::Apply(public_lib::Context *ctx, parser::Program *program) { SetPhaseManager(ctx->phaseManager); diff --git a/ets2panda/compiler/lowering/phase.h b/ets2panda/compiler/lowering/phase.h index e1ff9c3885e..83baa6fd81e 100644 --- a/ets2panda/compiler/lowering/phase.h +++ b/ets2panda/compiler/lowering/phase.h @@ -92,7 +92,8 @@ class PhaseForBodies : public Phase { class PhaseManager { public: - PhaseManager(ScriptExtension ext, ArenaAllocator *allocator) : allocator_ {allocator}, ext_ {ext} + PhaseManager(ScriptExtension ext, ArenaAllocator *allocator, bool historyEnabled = false) + : allocator_ {allocator}, ext_ {ext}, historyEnabled_ {historyEnabled} { InitializePhases(); Restart(); @@ -119,19 +120,18 @@ public: return allocator_; } - bool IsInitialized() const + bool HistoryEnabled() const { - return allocator_ != nullptr && ext_ != ScriptExtension::INVALID; + return historyEnabled_; } - void Restart() + bool IsInitialized() const { - prev_ = INVALID_PHASE_ID; - curr_ = PARSER_PHASE_ID; - next_ = PARSER_PHASE_ID + 1; - ES2PANDA_ASSERT(next_ == 0); + return allocator_ != nullptr && ext_ != ScriptExtension::INVALID; } + void Restart(); + Phase *NextPhase() { if (next_ < static_cast(phases_.size())) { @@ -152,6 +152,7 @@ private: ArenaAllocator *allocator_ {nullptr}; ScriptExtension ext_ {ScriptExtension::INVALID}; + bool historyEnabled_ {false}; std::vector phases_; }; diff --git a/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp b/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp index 56aa8c83183..e03465cb1ed 100644 --- a/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp +++ b/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -68,8 +68,9 @@ void ExportDeclarationContext::BindExportDecl(ir::AstNode *exportDecl) util::StringView exportName(exportDecl->IsExportDefaultDeclaration() ? "default" : name); variable->AddFlag(varbinder::VariableFlags::LOCAL_EXPORT); - auto *decl = - VarBinder()->AddDecl(variable->Declaration()->Node()->Start(), exportName, name); + auto node = variable->Declaration()->Node(); + auto pos = node != nullptr ? node->Start() : lexer::SourcePosition {}; + auto *decl = VarBinder()->AddDecl(pos, exportName, name); declList.push_back(decl); } diff --git a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp index 49bec80f6e3..97325b97602 100644 --- a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp +++ b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp @@ -1251,7 +1251,7 @@ void InitScopesPhaseETS::VisitClassDefinition(ir::ClassDefinition *classDef) auto classCtx = LexicalScopeCreateOrEnter(VarBinder(), classDef); IterateNoTParams(classDef); - FilterOverloads(classDef->Body()); + FilterOverloads(classDef->BodyMutable()); auto *classScope = classCtx.GetScope(); BindScopeNode(classScope, classDef); } @@ -1378,7 +1378,7 @@ void InitScopesPhaseETS::ParseGlobalClass(ir::ClassDefinition *global) CallNode(decl); } CallNode(global->Annotations()); - FilterOverloads(global->Body()); + FilterOverloads(global->BodyMutable()); } void InitScopesPhaseETS::AddGlobalDeclaration(ir::AstNode *node) diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index 09fe048e257..8c5c31092ce 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -167,7 +167,7 @@ static void ClearHelper(parser::Program *prog) { ResetGlobalClass(prog); // #24256 Should be removed when code refactoring on checker is done and no ast node allocated in checker. - auto &stmts = prog->Ast()->Statements(); + auto &stmts = prog->Ast()->StatementsMutable(); // clang-format off stmts.erase(std::remove_if(stmts.begin(), stmts.end(), [](ir::AstNode *ast) -> bool { diff --git a/ets2panda/evaluate/debugInfoDeserialization/classBuilder.cpp b/ets2panda/evaluate/debugInfoDeserialization/classBuilder.cpp index e78fd348d34..b6f04e44ca2 100644 --- a/ets2panda/evaluate/debugInfoDeserialization/classBuilder.cpp +++ b/ets2panda/evaluate/debugInfoDeserialization/classBuilder.cpp @@ -68,7 +68,7 @@ ir::ClassDeclaration *ClassBuilder::Build(parser::Program *program) && classDecl->SetParent(programAst); // Here we assume that global statements of the passed `program` are not currently checked, so that // insertion is safe. - programAst->Statements().push_back(classDecl); + programAst->StatementsMutable().push_back(classDecl); return classDecl; } diff --git a/ets2panda/evaluate/scopedDebugInfoPlugin.cpp b/ets2panda/evaluate/scopedDebugInfoPlugin.cpp index fc8666dc9eb..eb95e2c2ee9 100644 --- a/ets2panda/evaluate/scopedDebugInfoPlugin.cpp +++ b/ets2panda/evaluate/scopedDebugInfoPlugin.cpp @@ -149,7 +149,7 @@ bool ScopedDebugInfoPlugin::InsertReturnStatement() // which will also modify method signature's return type. auto *evalMethodStatements = context_.methodStatements; - auto &statementsList = evalMethodStatements->Statements(); + auto &statementsList = evalMethodStatements->StatementsMutable(); // Omit the emplaced `DebuggerAPI.setLocal<>` calls and find the original last statement. auto lastStatementIter = std::find(statementsList.rbegin(), statementsList.rend(), lastStatement); ES2PANDA_ASSERT(lastStatementIter != statementsList.rend()); @@ -195,7 +195,7 @@ void ScopedDebugInfoPlugin::AddPrologueEpilogue(ir::BlockStatement *block) } // Prepend prologue. - auto &statements = block->Statements(); + auto &statements = block->StatementsMutable(); for (auto *stmt : iter->second.first) { statements.insert(statements.begin(), stmt); } diff --git a/ets2panda/ir/annotationAllowed.h b/ets2panda/ir/annotationAllowed.h index 0053c073dc9..d33fa90dfd5 100644 --- a/ets2panda/ir/annotationAllowed.h +++ b/ets2panda/ir/annotationAllowed.h @@ -31,21 +31,33 @@ public: NO_COPY_OPERATOR(AnnotationAllowed); NO_MOVE_SEMANTIC(AnnotationAllowed); - [[nodiscard]] ArenaVector &Annotations() noexcept + void TransformAnnotations(const NodeTransformer &cb, std::string_view const transformationName) { - return annotations_; + auto &annotations = Annotations(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < annotations.size(); ix++) { + if (auto *transformedNode = cb(annotations[ix]); annotations[ix] != transformedNode) { + annotations[ix]->SetTransformedNode(transformationName, transformedNode); + AnnotationsMutable()[ix] = transformedNode->AsAnnotationUsage(); + } + } + } + + [[nodiscard]] ArenaVector &AnnotationsMutable() noexcept + { + return HISTORY_GET_OR_CREATE(annotations_); } [[nodiscard]] const ArenaVector &Annotations() const noexcept { - return annotations_; + return HISTORY_GET(annotations_); } void SetAnnotations(ArenaVector &&annotations) { - annotations_ = std::move(annotations); - for (ir::AnnotationUsage *anno : annotations_) { - anno->SetParent(this); + HISTORY_GET_OR_CREATE(annotations_) = std::move(annotations); + for (auto annotation : Annotations()) { + annotation->SetParent(this); } } @@ -84,7 +96,7 @@ protected: void AddAnnotations(AnnotationUsage *const annotations) { - annotations_.emplace_back(annotations); + HISTORY_GET_OR_CREATE(annotations_).emplace_back(annotations); } AnnotationAllowed(AnnotationAllowed const &other) diff --git a/ets2panda/ir/as/namedType.cpp b/ets2panda/ir/as/namedType.cpp index 7bf5f66ecbc..48880e15899 100644 --- a/ets2panda/ir/as/namedType.cpp +++ b/ets2panda/ir/as/namedType.cpp @@ -45,12 +45,7 @@ void NamedType::TransformChildren(const NodeTransformer &cb, std::string_view co } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void NamedType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/astNode.cpp b/ets2panda/ir/astNode.cpp index 9d920eeac2e..b15eb4f8244 100644 --- a/ets2panda/ir/astNode.cpp +++ b/ets2panda/ir/astNode.cpp @@ -15,57 +15,60 @@ #include "astNode.h" #include "ir/astDump.h" +#include "ir/astNodeHistory.h" #include "ir/srcDump.h" #include "ir/typed.h" +#include "compiler/lowering/phase.h" namespace ark::es2panda::ir { AstNode::AstNode(AstNode const &other) { - range_ = other.range_; - type_ = other.type_; - if (other.variable_ != nullptr) { - variable_ = other.variable_; + auto otherHistoryNode = other.GetHistoryNode(); + range_ = otherHistoryNode->range_; + type_ = otherHistoryNode->type_; + if (otherHistoryNode->variable_ != nullptr) { + variable_ = otherHistoryNode->variable_; } - flags_ = other.flags_; - astNodeFlags_ = other.astNodeFlags_; + flags_ = otherHistoryNode->flags_; + astNodeFlags_ = otherHistoryNode->astNodeFlags_; // boxing_unboxing_flags_ {}; leave default value! } [[nodiscard]] bool AstNode::IsExported() const noexcept { if (UNLIKELY(IsClassDefinition())) { - return parent_->IsExported(); + return Parent()->IsExported(); } - return (flags_ & ModifierFlags::EXPORT) != 0; + return (Modifiers() & ModifierFlags::EXPORT) != 0; } [[nodiscard]] bool AstNode::IsDefaultExported() const noexcept { if (UNLIKELY(IsClassDefinition())) { - return parent_->IsDefaultExported(); + return Parent()->IsDefaultExported(); } - return (flags_ & ModifierFlags::DEFAULT_EXPORT) != 0; + return (Modifiers() & ModifierFlags::DEFAULT_EXPORT) != 0; } [[nodiscard]] bool AstNode::IsExportedType() const noexcept { if (UNLIKELY(IsClassDefinition())) { - return this->parent_->IsExportedType(); + return Parent()->IsExportedType(); } - return (flags_ & ModifierFlags::EXPORT_TYPE) != 0; + return (Modifiers() & ModifierFlags::EXPORT_TYPE) != 0; } [[nodiscard]] bool AstNode::HasExportAlias() const noexcept { if (UNLIKELY(IsClassDefinition())) { - return parent_->HasExportAlias(); + return Parent()->HasExportAlias(); } - return (astNodeFlags_ & AstNodeFlags::HAS_EXPORT_ALIAS) != 0; + return (HISTORY_GET(astNodeFlags_) & AstNodeFlags::HAS_EXPORT_ALIAS) != 0; } bool AstNode::IsScopeBearer() const noexcept @@ -247,18 +250,24 @@ std::string AstNode::IsolatedDumpDecl() const void AstNode::SetOriginalNode(AstNode *originalNode) noexcept { - originalNode_ = originalNode; + HISTORY_SET(originalNode_, originalNode); } AstNode *AstNode::OriginalNode() const noexcept { - return originalNode_; + return HISTORY_GET(originalNode_); +} + +const std::optional> &AstNode::TransformedNode() const noexcept +{ + return HISTORY_GET(transformedNode_); } void AstNode::SetTransformedNode(std::string_view const transformationName, AstNode *transformedNode) { transformedNode->SetOriginalNode(this); - transformedNode_ = std::make_optional(std::make_pair(transformationName, transformedNode)); + + HISTORY_GET_OR_CREATE(transformedNode_) = std::make_optional(std::make_pair(transformationName, transformedNode)); } void AstNode::CleanUp() @@ -274,33 +283,33 @@ void AstNode::CleanUp() bool AstNode::IsReadonly() const noexcept { - return (flags_ & ModifierFlags::READONLY) != 0; + return (Modifiers() & ModifierFlags::READONLY) != 0; } // NOTE: For readonly parameter type bool AstNode::IsReadonlyType() const noexcept { - return (flags_ & ModifierFlags::READONLY_PARAMETER) != 0; + return (Modifiers() & ModifierFlags::READONLY_PARAMETER) != 0; } bool AstNode::IsOptionalDeclaration() const noexcept { - return (flags_ & ModifierFlags::OPTIONAL) != 0; + return (Modifiers() & ModifierFlags::OPTIONAL) != 0; } bool AstNode::IsDefinite() const noexcept { - return (flags_ & ModifierFlags::DEFINITE) != 0; + return (Modifiers() & ModifierFlags::DEFINITE) != 0; } bool AstNode::IsConstructor() const noexcept { - return (flags_ & ModifierFlags::CONSTRUCTOR) != 0; + return (Modifiers() & ModifierFlags::CONSTRUCTOR) != 0; } bool AstNode::IsOverride() const noexcept { - return (flags_ & ModifierFlags::OVERRIDE) != 0; + return (Modifiers() & ModifierFlags::OVERRIDE) != 0; } AstNode *AstNode::ShallowClone(ArenaAllocator *allocator) @@ -319,6 +328,7 @@ void AstNode::CopyTo(AstNode *other) const other->flags_ = flags_; other->astNodeFlags_ = astNodeFlags_; other->boxingUnboxingFlags_ = boxingUnboxingFlags_; + other->history_ = history_; other->variable_ = variable_; other->originalNode_ = originalNode_; other->transformedNode_ = transformedNode_; @@ -328,4 +338,57 @@ AstNode *AstNode::Construct([[maybe_unused]] ArenaAllocator *allocator) { ES2PANDA_UNREACHABLE(); } + +AstNode *AstNode::GetHistoryNode() const +{ + AstNode *node = nullptr; + + if (HistoryEnabled()) { + node = history_->Get(compiler::GetPhaseManager()->CurrentPhaseId()); + } else { + node = const_cast(this); + } + + ES2PANDA_ASSERT(node != nullptr); + return node; +} + +AstNode *AstNode::GetOrCreateHistoryNode() const +{ + AstNode *node = nullptr; + + if (HistoryEnabled()) { + node = history_->At(compiler::GetPhaseManager()->CurrentPhaseId()); + if (node == nullptr) { + node = history_->Get(compiler::GetPhaseManager()->PreviousPhaseId()); + ES2PANDA_ASSERT(node != nullptr); + node = node->ShallowClone(compiler::GetPhaseManager()->Allocator()); + history_->Set(node, compiler::GetPhaseManager()->CurrentPhaseId()); + } + } else { + node = const_cast(this); + } + + return node; +} + +void AstNode::EnableHistory() +{ + if (!compiler::GetPhaseManager()->HistoryEnabled()) { + return; + } + + if (HistoryEnabled()) { + return; + } + + history_ = compiler::GetPhaseManager()->Allocator()->New( + this, compiler::GetPhaseManager()->CurrentPhaseId(), compiler::GetPhaseManager()->Allocator()); +} + +bool AstNode::HistoryEnabled() const +{ + return history_ != nullptr; +} + } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index c8f07a0c751..9f312934da1 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -96,6 +96,7 @@ inline std::string_view ToString(AstNodeType nodeType) #undef STRING_FROM_NODE_TYPE // Forward declarations +class AstNodeHistory; class AstDumper; class Expression; class SrcDumper; @@ -127,7 +128,7 @@ public: bool IsProgram() const { - return parent_ == nullptr; + return Parent() == nullptr; } // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -136,7 +137,7 @@ public: { \ /* CC-OFFNXT(G.PRE.02) name part*/ \ /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed */ \ - return type_ == AstNodeType::nodeType; /* CC-OFF(G.PRE.02) name part*/ \ + return Type() == AstNodeType::nodeType; /* CC-OFF(G.PRE.02) name part*/ \ } AST_NODE_MAPPING(DECLARE_IS_CHECKS) #undef DECLARE_IS_CHECKS @@ -146,12 +147,12 @@ public: bool Is##baseClass() const \ { \ /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed */ \ - return type_ == AstNodeType::nodeType1; /* CC-OFF(G.PRE.02) name part*/ \ + return Type() == AstNodeType::nodeType1; /* CC-OFF(G.PRE.02) name part*/ \ } \ bool Is##reinterpretClass() const \ { \ /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed */ \ - return type_ == AstNodeType::nodeType2; /* CC-OFF(G.PRE.02) name part*/ \ + return Type() == AstNodeType::nodeType2; /* CC-OFF(G.PRE.02) name part*/ \ } AST_NODE_REINTERPRET_MAPPING(DECLARE_IS_CHECKS) #undef DECLARE_IS_CHECKS @@ -265,62 +266,66 @@ public: void SetRange(const lexer::SourceRange &loc) noexcept { - range_ = loc; + HISTORY_SET(range_, loc); } void SetStart(const lexer::SourcePosition &start) noexcept { - range_.start = start; + if (Start() != start) { + HISTORY_GET_OR_CREATE(range_).start = start; + } } void SetEnd(const lexer::SourcePosition &end) noexcept { - range_.end = end; + if (End() != end) { + HISTORY_GET_OR_CREATE(range_).end = end; + } } [[nodiscard]] const lexer::SourcePosition &Start() const noexcept { - return range_.start; + return HISTORY_GET(range_).start; } [[nodiscard]] const lexer::SourcePosition &End() const noexcept { - return range_.end; + return HISTORY_GET(range_).end; } [[nodiscard]] const lexer::SourceRange &Range() const noexcept { - return range_; + return HISTORY_GET(range_); } [[nodiscard]] AstNodeType Type() const noexcept { - return type_; + return HISTORY_GET(type_); } [[nodiscard]] AstNode *Parent() noexcept { - return parent_; + return HISTORY_GET(parent_); } [[nodiscard]] const AstNode *Parent() const noexcept { - return parent_; + return HISTORY_GET(parent_); } void SetParent(AstNode *const parent) noexcept { - parent_ = parent; + HISTORY_SET(parent_, parent); } [[nodiscard]] varbinder::Variable *Variable() const noexcept { - return variable_; + return HISTORY_GET(variable_); } void SetVariable(varbinder::Variable *variable) noexcept { - variable_ = variable; + HISTORY_SET(variable_, variable); } // When no decorators are allowed, we cannot return a reference to an empty vector. @@ -354,62 +359,62 @@ public: void SetOverride() noexcept { - flags_ |= ModifierFlags::OVERRIDE; + AddModifier(ModifierFlags::OVERRIDE); } [[nodiscard]] bool IsAsync() const noexcept { - return (flags_ & ModifierFlags::ASYNC) != 0; + return (Modifiers() & ModifierFlags::ASYNC) != 0; } [[nodiscard]] bool IsSynchronized() const noexcept { - return (flags_ & ModifierFlags::SYNCHRONIZED) != 0; + return (Modifiers() & ModifierFlags::SYNCHRONIZED) != 0; } [[nodiscard]] bool IsNative() const noexcept { - return (flags_ & ModifierFlags::NATIVE) != 0; + return (Modifiers() & ModifierFlags::NATIVE) != 0; } [[nodiscard]] bool IsConst() const noexcept { - return (flags_ & ModifierFlags::CONST) != 0; + return (Modifiers() & ModifierFlags::CONST) != 0; } [[nodiscard]] bool IsStatic() const noexcept { - return (flags_ & ModifierFlags::STATIC) != 0; + return (Modifiers() & ModifierFlags::STATIC) != 0; } [[nodiscard]] bool IsFinal() const noexcept { - return (flags_ & ModifierFlags::FINAL) != 0U; + return (Modifiers() & ModifierFlags::FINAL) != 0U; } [[nodiscard]] bool IsAbstract() const noexcept { - return (flags_ & ModifierFlags::ABSTRACT) != 0; + return (Modifiers() & ModifierFlags::ABSTRACT) != 0; } [[nodiscard]] bool IsPublic() const noexcept { - return (flags_ & ModifierFlags::PUBLIC) != 0; + return (Modifiers() & ModifierFlags::PUBLIC) != 0; } [[nodiscard]] bool IsProtected() const noexcept { - return (flags_ & ModifierFlags::PROTECTED) != 0; + return (Modifiers() & ModifierFlags::PROTECTED) != 0; } [[nodiscard]] bool IsPrivate() const noexcept { - return (flags_ & ModifierFlags::PRIVATE) != 0; + return (Modifiers() & ModifierFlags::PRIVATE) != 0; } [[nodiscard]] bool IsInternal() const noexcept { - return (flags_ & ModifierFlags::INTERNAL) != 0; + return (Modifiers() & ModifierFlags::INTERNAL) != 0; } [[nodiscard]] bool IsExported() const noexcept; @@ -420,42 +425,46 @@ public: [[nodiscard]] bool IsDeclare() const noexcept { - return (flags_ & ModifierFlags::DECLARE) != 0; + return (Modifiers() & ModifierFlags::DECLARE) != 0; } [[nodiscard]] bool IsIn() const noexcept { - return (flags_ & ModifierFlags::IN) != 0; + return (Modifiers() & ModifierFlags::IN) != 0; } [[nodiscard]] bool IsOut() const noexcept { - return (flags_ & ModifierFlags::OUT) != 0; + return (Modifiers() & ModifierFlags::OUT) != 0; } [[nodiscard]] bool IsSetter() const noexcept { - return (flags_ & ModifierFlags::SETTER) != 0; + return (Modifiers() & ModifierFlags::SETTER) != 0; } void AddModifier(ModifierFlags const flags) noexcept { - flags_ |= flags; + if (!All(Modifiers(), flags)) { + HISTORY_GET_OR_CREATE(flags_) |= flags; + } } void ClearModifier(ModifierFlags const flags) noexcept { - flags_ &= ~flags; + if (Any(Modifiers(), flags)) { + HISTORY_GET_OR_CREATE(flags_) &= ~flags; + } } [[nodiscard]] ModifierFlags Modifiers() noexcept { - return flags_; + return HISTORY_GET(flags_); } [[nodiscard]] ModifierFlags Modifiers() const noexcept { - return flags_; + return HISTORY_GET(flags_); } [[nodiscard]] bool HasExportAlias() const noexcept; @@ -464,28 +473,32 @@ public: #define DECLARE_FLAG_OPERATIONS(flag_type, member_name) \ void Set##flag_type(flag_type flags) const noexcept \ { \ - (member_name) = flags; \ + HISTORY_SET(member_name, flags); \ } \ \ void Add##flag_type(flag_type flag) const noexcept \ { \ - (member_name) |= flag; \ + if (!All(HISTORY_GET(member_name), flag)) { \ + HISTORY_GET_OR_CREATE(member_name) |= flag; \ + } \ } \ \ [[nodiscard]] flag_type Get##flag_type() const noexcept \ { \ /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \ - return (member_name); \ + return HISTORY_GET(member_name); \ } \ \ bool Has##flag_type(flag_type flag) const noexcept \ { \ /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \ - return ((member_name)&flag) != 0U; \ + return (HISTORY_GET(member_name) & flag) != 0U; \ } \ void Remove##flag_type(flag_type flag) const noexcept \ { \ - (member_name) &= ~flag; \ + if (Any(HISTORY_GET(member_name), flag)) { \ + HISTORY_GET_OR_CREATE(member_name) &= ~flag; \ + } \ } DECLARE_FLAG_OPERATIONS(BoxingUnboxingFlags, boxingUnboxingFlags_); @@ -561,7 +574,30 @@ protected: void SetType(AstNodeType const type) noexcept { - type_ = type; + HISTORY_SET(type_, type); + } + + void SetModifiers(ModifierFlags flags) + { + HISTORY_SET(flags_, flags); + } + + void EnableHistory(); + bool HistoryEnabled() const; + + AstNode *GetHistoryNode() const; + AstNode *GetOrCreateHistoryNode() const; + + template + T *GetHistoryNodeAs() const + { + return static_cast(GetHistoryNode()); + } + + template + T *GetOrCreateHistoryNodeAs() const + { + return static_cast(GetOrCreateHistoryNode()); } friend class SizeOfNodeTest; @@ -572,11 +608,14 @@ protected: ModifierFlags flags_ {}; mutable AstNodeFlags astNodeFlags_ {}; mutable BoxingUnboxingFlags boxingUnboxingFlags_ {}; + AstNodeHistory *history_ {nullptr}; // NOLINTEND(misc-non-private-member-variables-in-classes) private: AstNode &operator=(const AstNode &) = default; + const std::optional> &TransformedNode() const noexcept; + varbinder::Variable *variable_ {}; AstNode *originalNode_ = nullptr; // {lowering_phase_name, new_generated_node} @@ -594,12 +633,12 @@ public: [[nodiscard]] TypeNode *TypeAnnotation() const noexcept { - return typeAnnotation_; + return HISTORY_GET(typeAnnotation_); } void SetTsTypeAnnotation(TypeNode *const typeAnnotation) noexcept { - typeAnnotation_ = typeAnnotation; + HISTORY_SET(typeAnnotation_, typeAnnotation); } void CopyTo(AstNode *other) const override diff --git a/ets2panda/ir/astNodeHistory.cpp b/ets2panda/ir/astNodeHistory.cpp index c27d68e8d20..0eff803785a 100644 --- a/ets2panda/ir/astNodeHistory.cpp +++ b/ets2panda/ir/astNodeHistory.cpp @@ -78,6 +78,12 @@ AstNode *AstNodeHistory::Get(int32_t phaseId) return item_->data.node; } + // Return head node (original), in case node was created later than a given phase ID + ES2PANDA_ASSERT(!list_.Empty()); + if (list_.Head()->data.phaseId > phaseId) { + return list_.Head()->data.node; + } + return nullptr; } @@ -131,6 +137,9 @@ AstNodeHistory::HistoryList::Item *AstNodeHistory::FindLessOrEquals(int32_t phas item = item->prev; return item; } + if (item->next->data.phaseId > phaseId) { + return item; + } item = item->next; } if (item->data.phaseId <= phaseId) { diff --git a/ets2panda/ir/base/classDefinition.cpp b/ets2panda/ir/base/classDefinition.cpp index 2c88bf449ea..b53bbcf6ba2 100644 --- a/ets2panda/ir/base/classDefinition.cpp +++ b/ets2panda/ir/base/classDefinition.cpp @@ -28,28 +28,32 @@ #include "ir/ts/tsClassImplements.h" namespace ark::es2panda::ir { -const FunctionExpression *ClassDefinition::Ctor() const +const FunctionExpression *ClassDefinition::CtorValue() const { - return ctor_ != nullptr ? ctor_->Value()->AsFunctionExpression() : nullptr; + auto ctor = HISTORY_GET(ctor_); + return ctor != nullptr ? ctor->Value()->AsFunctionExpression() : nullptr; } bool ClassDefinition::HasPrivateMethod() const { - return std::any_of(body_.cbegin(), body_.cend(), [](auto *element) { + auto &body = Body(); + return std::any_of(body.cbegin(), body.cend(), [](auto const *element) { return element->IsMethodDefinition() && element->AsClassElement()->IsPrivateElement(); }); } bool ClassDefinition::HasNativeMethod() const { - return std::any_of(body_.cbegin(), body_.cend(), [](auto *element) { + auto &body = Body(); + return std::any_of(body.cbegin(), body.cend(), [](auto const *element) { return element->IsMethodDefinition() && element->AsMethodDefinition()->IsNative(); }); } bool ClassDefinition::HasComputedInstanceField() const { - return std::any_of(body_.cbegin(), body_.cend(), [](auto *element) { + auto &body = Body(); + return std::any_of(body.cbegin(), body.cend(), [](auto *element) { return element->IsClassProperty() && element->AsClassElement()->IsComputed() && !(element->AsClassElement()->Modifiers() & ir::ModifierFlags::STATIC); }); @@ -57,115 +61,128 @@ bool ClassDefinition::HasComputedInstanceField() const bool ClassDefinition::HasMatchingPrivateKey(const util::StringView &name) const { - return std::any_of(body_.cbegin(), body_.cend(), [&name](auto *element) { + auto &body = Body(); + return std::any_of(body.cbegin(), body.cend(), [&name](auto *element) { return element->AsClassElement()->IsPrivateElement() && element->AsClassElement()->Id()->Name() == name; }); } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic +// NOLINTNEXTLINE(readability-function-size) void ClassDefinition::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - if (ident_ != nullptr) { - if (auto *transformedNode = cb(ident_); ident_ != transformedNode) { - ident_->SetTransformedNode(transformationName, transformedNode); - ident_ = transformedNode->AsIdentifier(); + auto ident = Ident(); + if (ident != nullptr) { + if (auto *transformedNode = cb(ident); ident != transformedNode) { + ident->SetTransformedNode(transformationName, transformedNode); + SetIdent(transformedNode->AsIdentifier()); } } - if (typeParams_ != nullptr) { - if (auto *transformedNode = cb(typeParams_); typeParams_ != transformedNode) { - typeParams_->SetTransformedNode(transformationName, transformedNode); - typeParams_ = transformedNode->AsTSTypeParameterDeclaration(); + auto typeParam = TypeParams(); + if (typeParam != nullptr) { + if (auto *transformedNode = cb(typeParam); typeParam != transformedNode) { + typeParam->SetTransformedNode(transformationName, transformedNode); + SetTypeParams(transformedNode->AsTSTypeParameterDeclaration()); } } - if (superClass_ != nullptr) { - if (auto *transformedNode = cb(superClass_); superClass_ != transformedNode) { - superClass_->SetTransformedNode(transformationName, transformedNode); - superClass_ = transformedNode->AsExpression(); + auto superClass = SuperClass(); + if (superClass != nullptr) { + if (auto *transformedNode = cb(superClass); superClass != transformedNode) { + superClass->SetTransformedNode(transformationName, transformedNode); + SetSuperClass(transformedNode->AsExpression()); } } - if (superTypeParams_ != nullptr) { - if (auto *transformedNode = cb(superTypeParams_); superTypeParams_ != transformedNode) { - superTypeParams_->SetTransformedNode(transformationName, transformedNode); - superTypeParams_ = transformedNode->AsTSTypeParameterInstantiation(); + auto superTypeParam = SuperTypeParams(); + if (superTypeParam != nullptr) { + if (auto *transformedNode = cb(superTypeParam); superTypeParam != transformedNode) { + superTypeParam->SetTransformedNode(transformationName, transformedNode); + SetSuperTypeParams(transformedNode->AsTSTypeParameterInstantiation()); } } - for (auto *&it : VectorIterationGuard(implements_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsTSClassImplements(); + auto &implements = Implements(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < implements.size(); ix++) { + if (auto *transformedNode = cb(implements[ix]); implements[ix] != transformedNode) { + implements[ix]->SetTransformedNode(transformationName, transformedNode); + ImplementsMutable()[ix] = transformedNode->AsTSClassImplements(); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); - if (ctor_ != nullptr) { - if (auto *transformedNode = cb(ctor_); ctor_ != transformedNode) { - ctor_->SetTransformedNode(transformationName, transformedNode); - ctor_ = transformedNode->AsMethodDefinition(); + auto ctor = Ctor(); + if (ctor != nullptr) { + if (auto *transformedNode = cb(ctor); ctor != transformedNode) { + ctor->SetTransformedNode(transformationName, transformedNode); + SetCtor(transformedNode->AsMethodDefinition()); } } // Survives adding new elements to the end + auto &body = Body(); // NOLINTNEXTLINE(modernize-loop-convert) - for (size_t ix = 0; ix < body_.size(); ix++) { - if (auto *transformedNode = cb(body_[ix]); body_[ix] != transformedNode) { - body_[ix]->SetTransformedNode(transformationName, transformedNode); - body_[ix] = transformedNode; + for (size_t ix = 0; ix < body.size(); ix++) { + if (auto *transformedNode = cb(body[ix]); body[ix] != transformedNode) { + body[ix]->SetTransformedNode(transformationName, transformedNode); + BodyMutable()[ix] = transformedNode; } } } void ClassDefinition::Iterate(const NodeTraverser &cb) const { - if (ident_ != nullptr) { - cb(ident_); + auto ident = HISTORY_GET(ident_); + if (ident != nullptr) { + cb(ident); } - if (typeParams_ != nullptr) { - cb(typeParams_); + auto typeParams = HISTORY_GET(typeParams_); + if (typeParams != nullptr) { + cb(typeParams); } - if (superClass_ != nullptr) { - cb(superClass_); + auto superClass = HISTORY_GET(superClass_); + if (superClass != nullptr) { + cb(superClass); } - if (superTypeParams_ != nullptr) { - cb(superTypeParams_); + auto superTypeParams = HISTORY_GET(superTypeParams_); + if (superTypeParams != nullptr) { + cb(superTypeParams); } // Survives adding new elements to the end + auto &implements = HISTORY_GET(implements_); // NOLINTNEXTLINE(modernize-loop-convert) - for (size_t ix = 0; ix < implements_.size(); ix++) { - cb(implements_[ix]); + for (size_t ix = 0; ix < implements.size(); ix++) { + cb(implements[ix]); } for (auto *it : VectorIterationGuard(Annotations())) { cb(it); } - if (ctor_ != nullptr) { - cb(ctor_); + auto ctor = HISTORY_GET(ctor_); + if (ctor != nullptr) { + cb(ctor); } + auto &body = HISTORY_GET(body_); // NOLINTNEXTLINE(modernize-loop-convert) - for (size_t ix = 0; ix < body_.size(); ix++) { - cb(body_[ix]); + for (size_t ix = 0; ix < body.size(); ix++) { + cb(body[ix]); } } void ClassDefinition::SetIdent(ir::Identifier *ident) noexcept { - ident_ = ident; - if (ident_ != nullptr) { - ident_->SetParent(this); + HISTORY_SET(ident_, ident); + if (ident != nullptr) { + ident->SetParent(this); } } @@ -174,26 +191,27 @@ void ClassDefinition::Dump(ir::AstDumper *dumper) const auto propFilter = [](AstNode *prop) -> bool { return !prop->IsClassStaticBlock() || !prop->AsClassStaticBlock()->Function()->IsHidden(); }; - dumper->Add({{"id", AstDumper::Nullish(ident_)}, - {"typeParameters", AstDumper::Optional(typeParams_)}, - {"superClass", AstDumper::Nullish(superClass_)}, - {"superTypeParameters", AstDumper::Optional(superTypeParams_)}, - {"implements", implements_}, + dumper->Add({{"id", AstDumper::Nullish(Ident())}, + {"typeParameters", AstDumper::Optional(TypeParams())}, + {"superClass", AstDumper::Nullish(SuperClass())}, + {"superTypeParameters", AstDumper::Optional(SuperTypeParams())}, + {"implements", Implements()}, {"annotations", AstDumper::Optional(Annotations())}, - {"constructor", AstDumper::Optional(ctor_)}, - {"body", body_, propFilter}}); + {"constructor", AstDumper::Optional(Ctor())}, + {"body", Body(), propFilter}}); } void ClassDefinition::DumpGlobalClass(ir::SrcDumper *dumper) const { ES2PANDA_ASSERT(IsGlobal()); - for (auto elem : body_) { + auto &body = Body(); + for (auto elem : body) { if (elem->IsClassProperty()) { elem->Dump(dumper); dumper->Endl(); } } - for (auto elem : body_) { + for (auto elem : body) { if (elem->IsMethodDefinition()) { elem->Dump(dumper); dumper->Endl(); @@ -204,13 +222,14 @@ void ClassDefinition::DumpGlobalClass(ir::SrcDumper *dumper) const // This method is needed by OHOS CI code checker void ClassDefinition::DumpBody(ir::SrcDumper *dumper) const { + auto &body = Body(); dumper->Add(" {"); - if (!body_.empty()) { + if (!body.empty()) { dumper->IncrIndent(); dumper->Endl(); - for (auto elem : body_) { + for (auto elem : body) { elem->Dump(dumper); - if (elem == body_.back()) { + if (elem == body.back()) { dumper->DecrIndent(); } dumper->Endl(); @@ -270,7 +289,8 @@ bool ClassDefinition::RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const void ClassDefinition::Dump(ir::SrcDumper *dumper) const { // NOTE: plugin API fails - if ((ident_->Name().StartsWith("$dynmodule")) || (ident_->Name().StartsWith("$jscall"))) { + auto const ident = Ident(); + if ((ident->Name().StartsWith("$dynmodule")) || (ident->Name().StartsWith("$jscall"))) { return; } @@ -279,7 +299,7 @@ void ClassDefinition::Dump(ir::SrcDumper *dumper) const return; } - ES2PANDA_ASSERT(ident_ != nullptr); + ES2PANDA_ASSERT(ident != nullptr); if (RegisterUnexportedForDeclGen(dumper)) { return; @@ -290,21 +310,21 @@ void ClassDefinition::Dump(ir::SrcDumper *dumper) const } DumpPrefix(dumper); - ident_->Dump(dumper); + ident->Dump(dumper); - if (typeParams_ != nullptr) { + if (TypeParams() != nullptr) { dumper->Add("<"); - typeParams_->Dump(dumper); + TypeParams()->Dump(dumper); dumper->Add("> "); } - if (superClass_ != nullptr) { + if (SuperClass() != nullptr) { dumper->Add(" extends "); - superClass_->Dump(dumper); + SuperClass()->Dump(dumper); } - DumpItems(dumper, " implements ", implements_); - if (!IsDeclare() || !body_.empty()) { + DumpItems(dumper, " implements ", Implements()); + if (!IsDeclare() || !Body().empty()) { DumpBody(dumper); } if (IsLocal()) { @@ -337,7 +357,7 @@ ClassDefinition *ClassDefinition::Construct(ArenaAllocator *allocator) { ArenaVector body {allocator->Adapter()}; return allocator->New(allocator, nullptr, std::move(body), ClassDefinitionModifiers::NONE, - ModifierFlags::NONE, Language::Id::COUNT); + ModifierFlags::NONE, Language::Id::COUNT, history_); } void ClassDefinition::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/base/classDefinition.h b/ets2panda/ir/base/classDefinition.h index 2eb349f8cc3..07020ac4e49 100644 --- a/ets2panda/ir/base/classDefinition.h +++ b/ets2panda/ir/base/classDefinition.h @@ -21,6 +21,7 @@ #include "ir/srcDump.h" #include "ir/annotationAllowed.h" #include "ir/astNode.h" +#include "ir/astNodeHistory.h" #include "ir/expressions/identifier.h" #include "ir/jsDocAllowed.h" #include "ir/statements/annotationUsage.h" @@ -101,6 +102,7 @@ public: localPrefix_("$" + std::to_string(localIndex_)), exportedClasses_(body_.get_allocator()) { + EnableHistory(); } // CC-OFFNXT(G.FUN.01-CPP) solid logic explicit ClassDefinition(ArenaAllocator *allocator, Identifier *ident, ArenaVector &&body, @@ -117,6 +119,7 @@ public: localPrefix_("$" + std::to_string(localIndex_)), exportedClasses_(body_.get_allocator()) { + EnableHistory(); } explicit ClassDefinition(ArenaAllocator *allocator, Identifier *ident, ClassDefinitionModifiers modifiers, @@ -133,6 +136,30 @@ public: localPrefix_("$" + std::to_string(localIndex_)), exportedClasses_(body_.get_allocator()) { + EnableHistory(); + } + + // CC-OFFNXT(G.FUN.01-CPP) solid logic + explicit ClassDefinition(ArenaAllocator *allocator, Identifier *ident, ArenaVector &&body, + ClassDefinitionModifiers modifiers, ModifierFlags flags, Language lang, + AstNodeHistory *history) + : JsDocAllowed>(AstNodeType::CLASS_DEFINITION, flags, allocator), + ident_(ident), + implements_(allocator->Adapter()), + body_(std::move(body)), + modifiers_(modifiers), + lang_(lang), + capturedVars_(allocator->Adapter()), + localVariableIsNeeded_(allocator->Adapter()), + localIndex_(classCounter_++), + localPrefix_("$" + std::to_string(localIndex_)), + exportedClasses_(body_.get_allocator()) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } [[nodiscard]] bool IsScopeBearer() const noexcept override @@ -142,107 +169,107 @@ public: [[nodiscard]] varbinder::LocalScope *Scope() const noexcept override { - return scope_; + return HISTORY_GET(scope_); } void SetScope(varbinder::LocalScope *scope) { - ES2PANDA_ASSERT(scope_ == nullptr); - scope_ = scope; + ES2PANDA_ASSERT(Scope() == nullptr); + HISTORY_SET(scope_, scope); } void ClearScope() noexcept override { - scope_ = nullptr; + HISTORY_SET(scope_, nullptr); } [[nodiscard]] const Identifier *Ident() const noexcept { - return ident_; + return HISTORY_GET(ident_); } [[nodiscard]] Identifier *Ident() noexcept { - return ident_; + return HISTORY_GET(ident_); } void SetIdent(ir::Identifier *ident) noexcept; [[nodiscard]] const util::StringView &InternalName() const noexcept { - return internalName_; + return HISTORY_GET(internalName_); } void SetInternalName(util::StringView internalName) noexcept { - internalName_ = internalName; + HISTORY_SET(internalName_, internalName); } [[nodiscard]] Expression *Super() noexcept { - return superClass_; + return HISTORY_GET(superClass_); } [[nodiscard]] const Expression *Super() const noexcept { - return superClass_; + return HISTORY_GET(superClass_); } void SetSuper(Expression *superClass) { - superClass_ = superClass; - if (superClass_ != nullptr) { - superClass_->SetParent(this); + HISTORY_SET(superClass_, superClass); + if (superClass != nullptr) { + superClass->SetParent(this); } } [[nodiscard]] bool IsGlobal() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::GLOBAL) != 0; + return (Modifiers() & ClassDefinitionModifiers::GLOBAL) != 0; } [[nodiscard]] bool IsLocal() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::LOCAL) != 0; + return (Modifiers() & ClassDefinitionModifiers::LOCAL) != 0; } [[nodiscard]] bool IsExtern() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::EXTERN) != 0; + return (Modifiers() & ClassDefinitionModifiers::EXTERN) != 0; } [[nodiscard]] bool IsFromExternal() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::FROM_EXTERNAL) != 0; + return (Modifiers() & ClassDefinitionModifiers::FROM_EXTERNAL) != 0; } [[nodiscard]] bool IsInner() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::INNER) != 0; + return (Modifiers() & ClassDefinitionModifiers::INNER) != 0; } [[nodiscard]] bool IsGlobalInitialized() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::GLOBAL_INITIALIZED) != 0; + return (Modifiers() & ClassDefinitionModifiers::GLOBAL_INITIALIZED) != 0; } [[nodiscard]] bool IsClassDefinitionChecked() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::CLASSDEFINITION_CHECKED) != 0; + return (Modifiers() & ClassDefinitionModifiers::CLASSDEFINITION_CHECKED) != 0; } [[nodiscard]] bool IsAnonymous() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::ANONYMOUS) != 0; + return (Modifiers() & ClassDefinitionModifiers::ANONYMOUS) != 0; } [[nodiscard]] bool IsIntEnumTransformed() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::INT_ENUM_TRANSFORMED) != 0; + return (Modifiers() & ClassDefinitionModifiers::INT_ENUM_TRANSFORMED) != 0; } [[nodiscard]] bool IsStringEnumTransformed() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::STRING_ENUM_TRANSFORMED) != 0; + return (Modifiers() & ClassDefinitionModifiers::STRING_ENUM_TRANSFORMED) != 0; } [[nodiscard]] bool IsEnumTransformed() const noexcept @@ -252,12 +279,12 @@ public: [[nodiscard]] bool IsNamespaceTransformed() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::NAMESPACE_TRANSFORMED) != 0; + return (Modifiers() & ClassDefinitionModifiers::NAMESPACE_TRANSFORMED) != 0; } [[nodiscard]] bool IsFromStruct() const noexcept { - return (modifiers_ & ClassDefinitionModifiers::FROM_STRUCT) != 0; + return (Modifiers() & ClassDefinitionModifiers::FROM_STRUCT) != 0; } [[nodiscard]] bool IsModule() const noexcept @@ -267,111 +294,117 @@ public: [[nodiscard]] es2panda::Language Language() const noexcept { - return lang_; + return HISTORY_GET(lang_); } void SetGlobalInitialized() noexcept { - modifiers_ |= ClassDefinitionModifiers::GLOBAL_INITIALIZED; + AddClassModifiers(ClassDefinitionModifiers::GLOBAL_INITIALIZED); } void SetInnerModifier() noexcept { - modifiers_ |= ClassDefinitionModifiers::INNER; + AddClassModifiers(ClassDefinitionModifiers::INNER); } void SetClassDefinitionChecked() noexcept { - modifiers_ |= ClassDefinitionModifiers::CLASSDEFINITION_CHECKED; + AddClassModifiers(ClassDefinitionModifiers::CLASSDEFINITION_CHECKED); } void SetAnonymousModifier() noexcept { - modifiers_ |= ClassDefinitionModifiers::ANONYMOUS; + AddClassModifiers(ClassDefinitionModifiers::ANONYMOUS); } void SetNamespaceTransformed() noexcept { - modifiers_ |= ClassDefinitionModifiers::NAMESPACE_TRANSFORMED; + AddClassModifiers(ClassDefinitionModifiers::NAMESPACE_TRANSFORMED); } void SetFromStructModifier() noexcept { - modifiers_ |= ClassDefinitionModifiers::FROM_STRUCT; + AddClassModifiers(ClassDefinitionModifiers::FROM_STRUCT); } [[nodiscard]] ClassDefinitionModifiers Modifiers() const noexcept { - return modifiers_; + return HISTORY_GET(modifiers_); } void SetModifiers(ClassDefinitionModifiers modifiers) noexcept { - modifiers_ = modifiers; + HISTORY_SET(modifiers_, modifiers); } - void AddProperties(ArenaVector &&body) + void AddProperties(ArenaVector &&properties) { - for (auto *prop : body) { - prop->SetParent(this); + for (auto property : properties) { + property->SetParent(this); } - body_.insert(body_.end(), body.begin(), body.end()); + auto &body = HISTORY_GET_OR_CREATE(body_); + body.insert(body.end(), properties.begin(), properties.end()); } - [[nodiscard]] ArenaVector &Body() noexcept + [[nodiscard]] ArenaVector &BodyMutable() noexcept { - return body_; + return HISTORY_GET_OR_CREATE(body_); } [[nodiscard]] const ArenaVector &Body() const noexcept { - return body_; + return HISTORY_GET(body_); } [[nodiscard]] MethodDefinition *Ctor() noexcept { - return ctor_; + return HISTORY_GET(ctor_); + } + + [[nodiscard]] const MethodDefinition *Ctor() const noexcept + { + return HISTORY_GET(ctor_); } void SetCtor(MethodDefinition *ctor) { - ctor_ = ctor; + HISTORY_SET(ctor_, ctor); } - [[nodiscard]] ArenaVector &Implements() noexcept + [[nodiscard]] ArenaVector &ImplementsMutable() noexcept { - return implements_; + return HISTORY_GET_OR_CREATE(implements_); } [[nodiscard]] const ArenaVector &Implements() const noexcept { - return implements_; + return HISTORY_GET(implements_); } [[nodiscard]] const ir::TSTypeParameterDeclaration *TypeParams() const noexcept { - return typeParams_; + return HISTORY_GET(typeParams_); } [[nodiscard]] ir::TSTypeParameterDeclaration *TypeParams() noexcept { - return typeParams_; + return HISTORY_GET(typeParams_); } void SetTypeParams(ir::TSTypeParameterDeclaration *typeParams) { - typeParams_ = typeParams; + HISTORY_SET(typeParams_, typeParams); } const TSTypeParameterInstantiation *SuperTypeParams() const { - return superTypeParams_; + return HISTORY_GET(superTypeParams_); } TSTypeParameterInstantiation *SuperTypeParams() { - return superTypeParams_; + return HISTORY_GET(superTypeParams_); } [[nodiscard]] static int LocalTypeCounter() noexcept @@ -381,7 +414,7 @@ public: [[nodiscard]] int LocalIndex() const noexcept { - return localIndex_; + return HISTORY_GET(localIndex_); } [[nodiscard]] util::StringView FunctionalReferenceReferencedMethod() const noexcept @@ -396,55 +429,55 @@ public: [[nodiscard]] const std::string &LocalPrefix() const noexcept { - return localPrefix_; + return HISTORY_GET(localPrefix_); } bool CaptureVariable(varbinder::Variable *var) { - return capturedVars_.insert(var).second; + return HISTORY_GET_OR_CREATE(capturedVars_).insert(var).second; } bool AddToLocalVariableIsNeeded(varbinder::Variable *var) { - return localVariableIsNeeded_.insert(var).second; + return HISTORY_GET_OR_CREATE(localVariableIsNeeded_).insert(var).second; } bool IsLocalVariableNeeded(varbinder::Variable *var) const { - return localVariableIsNeeded_.find(var) != localVariableIsNeeded_.end(); + return HISTORY_GET(localVariableIsNeeded_).count(var) > 0; } [[nodiscard]] const ArenaSet &CapturedVariables() const noexcept { - return capturedVars_; + return HISTORY_GET(capturedVars_); } bool EraseCapturedVariable(varbinder::Variable *var) { - return capturedVars_.erase(var) != 0; + return HISTORY_GET_OR_CREATE(capturedVars_).erase(var) != 0; } void SetOrigEnumDecl(ir::TSEnumDeclaration *enumDecl) { - origEnumDecl_ = enumDecl; + HISTORY_SET(origEnumDecl_, enumDecl); } ir::TSEnumDeclaration *OrigEnumDecl() const { - return origEnumDecl_; + return HISTORY_GET(origEnumDecl_); } ClassDeclaration *GetAnonClass() noexcept { - return anonClass_; + return HISTORY_GET(anonClass_); } void SetAnonClass(ClassDeclaration *anonClass) noexcept { - anonClass_ = anonClass; + HISTORY_SET(anonClass_, anonClass); } - const FunctionExpression *Ctor() const; + const FunctionExpression *CtorValue() const; bool HasPrivateMethod() const; bool HasNativeMethod() const; bool HasComputedInstanceField() const; @@ -483,26 +516,60 @@ public: void CleanUp() override { AstNode::CleanUp(); - modifiers_ &= ~(ClassDefinitionModifiers::CLASSDEFINITION_CHECKED); + ClearClassModifiers(ClassDefinitionModifiers::CLASSDEFINITION_CHECKED); } void AddToExportedClasses(const ir::ClassDeclaration *cls) { ES2PANDA_ASSERT(cls->IsExported()); - exportedClasses_.push_back(cls); + HISTORY_GET_OR_CREATE(exportedClasses_).push_back(cls); } [[nodiscard]] const ArenaVector &ExportedClasses() const noexcept { - return exportedClasses_; + return HISTORY_GET(exportedClasses_); } protected: + void AddClassModifiers(ClassDefinitionModifiers const flags) noexcept + { + if (!All(Modifiers(), flags)) { + HISTORY_GET_OR_CREATE(modifiers_) |= flags; + } + } + + void ClearClassModifiers(ClassDefinitionModifiers const flags) noexcept + { + if (Any(Modifiers(), flags)) { + HISTORY_GET_OR_CREATE(modifiers_) &= ~flags; + } + } + ClassDefinition *Construct(ArenaAllocator *allocator) override; void CopyTo(AstNode *other) const override; private: + void SetSuperClass(Expression *superClass) + { + HISTORY_SET(superClass_, superClass); + } + + void SetSuperTypeParams(TSTypeParameterInstantiation *superTypeParams) + { + HISTORY_SET(superTypeParams_, superTypeParams); + } + + [[nodiscard]] Expression *SuperClass() + { + return HISTORY_GET(superClass_); + } + + [[nodiscard]] const Expression *SuperClass() const + { + return HISTORY_GET(superClass_); + } + void CompileStaticFieldInitializers(compiler::PandaGen *pg, compiler::VReg classReg, const std::vector &staticComputedFieldKeys) const; diff --git a/ets2panda/ir/base/classElement.cpp b/ets2panda/ir/base/classElement.cpp index 9c54368dd8b..ae8fb7a6417 100644 --- a/ets2panda/ir/base/classElement.cpp +++ b/ets2panda/ir/base/classElement.cpp @@ -25,17 +25,19 @@ void ClassElement::SetValue(Expression *value) noexcept if (value != nullptr) { value->SetParent(this); } - value_ = value; + HISTORY_SET(value_, value); } Identifier *ClassElement::Id() noexcept { - return key_ != nullptr && key_->IsIdentifier() ? key_->AsIdentifier() : nullptr; + auto const key = Key(); + return key != nullptr && key->IsIdentifier() ? key->AsIdentifier() : nullptr; } const Identifier *ClassElement::Id() const noexcept { - return key_ != nullptr && key_->IsIdentifier() ? key_->AsIdentifier() : nullptr; + auto const key = Key(); + return key != nullptr && key->IsIdentifier() ? key->AsIdentifier() : nullptr; } bool ClassElement::IsPrivateElement() const noexcept @@ -44,7 +46,8 @@ bool ClassElement::IsPrivateElement() const noexcept return false; } - return key_->IsIdentifier() && key_->AsIdentifier()->IsPrivateIdent(); + auto const key = Key(); + return key->IsIdentifier() && key->AsIdentifier()->IsPrivateIdent(); } void ClassElement::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/base/classElement.h b/ets2panda/ir/base/classElement.h index fc372f8dc27..a1864defc80 100644 --- a/ets2panda/ir/base/classElement.h +++ b/ets2panda/ir/base/classElement.h @@ -46,41 +46,41 @@ public: [[nodiscard]] Expression *Key() noexcept { - return key_; + return HISTORY_GET(key_); } [[nodiscard]] const Expression *Key() const noexcept { - return key_; + return HISTORY_GET(key_); } [[nodiscard]] Expression *Value() noexcept { - return value_; + return HISTORY_GET(value_); } void SetValue(Expression *value) noexcept; [[nodiscard]] const Expression *Value() const noexcept { - return value_; + return HISTORY_GET(value_); } [[nodiscard]] const TSEnumMember *OriginEnumMember() const noexcept { - return enumMember_; + return HISTORY_GET(enumMember_); } void SetOrigEnumMember(ir::TSEnumMember *enumMember) { - enumMember_ = enumMember; + HISTORY_SET(enumMember_, enumMember); } [[nodiscard]] bool IsPrivateElement() const noexcept; [[nodiscard]] const ArenaVector &Decorators() const noexcept { - return decorators_; + return HISTORY_GET(decorators_); } const ArenaVector *DecoratorsPtr() const override @@ -90,18 +90,18 @@ public: [[nodiscard]] bool IsComputed() const noexcept { - return isComputed_; + return HISTORY_GET(isComputed_); } void AddDecorators([[maybe_unused]] ArenaVector &&decorators) override { - decorators_ = std::move(decorators); + HISTORY_GET_OR_CREATE(decorators_) = std::move(decorators); } void AddDecorator(ir::Decorator *const decorator) { if (decorator != nullptr) { - decorators_.emplace_back(decorator); + HISTORY_GET_OR_CREATE(decorators_).emplace_back(decorator); } } @@ -116,6 +116,16 @@ public: protected: friend class SizeOfNodeTest; + void SetKey(Expression *key) + { + HISTORY_SET(key_, key); + } + + ArenaVector &DecoratorsMutable() + { + return HISTORY_GET_OR_CREATE(decorators_); + } + // NOLINTBEGIN(misc-non-private-member-variables-in-classes) Expression *key_; Expression *value_; diff --git a/ets2panda/ir/base/classProperty.cpp b/ets2panda/ir/base/classProperty.cpp index 0ec31492bcf..bc446b71d84 100644 --- a/ets2panda/ir/base/classProperty.cpp +++ b/ets2panda/ir/base/classProperty.cpp @@ -25,53 +25,58 @@ namespace ark::es2panda::ir { void ClassProperty::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { - if (auto *transformedNode = cb(key_); key_ != transformedNode) { - key_->SetTransformedNode(transformationName, transformedNode); - key_ = transformedNode->AsExpression(); - } - - if (value_ != nullptr) { - if (auto *transformedNode = cb(value_); value_ != transformedNode) { - value_->SetTransformedNode(transformationName, transformedNode); - value_ = transformedNode->AsExpression(); + auto key = Key(); + if (key != nullptr) { + if (auto *transformedNode = cb(key); key != transformedNode) { + key->SetTransformedNode(transformationName, transformedNode); + SetKey(transformedNode->AsExpression()); } } - if (typeAnnotation_ != nullptr) { - if (auto *transformedNode = cb(typeAnnotation_); typeAnnotation_ != transformedNode) { - typeAnnotation_->SetTransformedNode(transformationName, transformedNode); - typeAnnotation_ = static_cast(transformedNode); + auto value = Value(); + if (value != nullptr) { + if (auto *transformedNode = cb(value); value != transformedNode) { + value->SetTransformedNode(transformationName, transformedNode); + SetValue(transformedNode->AsExpression()); } } - for (auto *&it : VectorIterationGuard(decorators_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsDecorator(); + auto typeAnnotation = TypeAnnotation(); + if (typeAnnotation != nullptr) { + if (auto *transformedNode = cb(typeAnnotation); typeAnnotation != transformedNode) { + typeAnnotation->SetTransformedNode(transformationName, transformedNode); + SetTypeAnnotation(static_cast(transformedNode)); } } - for (auto *&it : Annotations()) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); + auto &decorators = Decorators(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < decorators.size(); ix++) { + if (auto *transformedNode = cb(decorators[ix]); decorators[ix] != transformedNode) { + decorators[ix]->SetTransformedNode(transformationName, transformedNode); + DecoratorsMutable()[ix] = transformedNode->AsDecorator(); } } + + TransformAnnotations(cb, transformationName); } void ClassProperty::Iterate(const NodeTraverser &cb) const { - cb(key_); + auto key = HISTORY_GET(key_); + cb(key); - if (value_ != nullptr) { - cb(value_); + auto value = HISTORY_GET(value_); + if (value != nullptr) { + cb(value); } - if (typeAnnotation_ != nullptr) { - cb(typeAnnotation_); + auto typeAnnotation = TypeAnnotation(); + if (typeAnnotation != nullptr) { + cb(typeAnnotation); } - for (auto *it : VectorIterationGuard(decorators_)) { + for (auto *it : VectorIterationGuard(Decorators())) { cb(it); } @@ -82,18 +87,19 @@ void ClassProperty::Iterate(const NodeTraverser &cb) const void ClassProperty::Dump(ir::AstDumper *dumper) const { + // CC-OFFNXT(WordsTool.5) sensitive word copnflict dumper->Add({{"type", "ClassProperty"}, - {"key", key_}, - {"value", AstDumper::Optional(value_)}, - {"accessibility", AstDumper::Optional(AstDumper::ModifierToString(flags_))}, + {"key", Key()}, + {"value", AstDumper::Optional(Value())}, + {"accessibility", AstDumper::Optional(AstDumper::ModifierToString(Modifiers()))}, {"static", IsStatic()}, {"readonly", IsReadonly()}, {"declare", IsDeclare()}, {"optional", IsOptionalDeclaration()}, - {"computed", isComputed_}, - {"typeAnnotation", AstDumper::Optional(typeAnnotation_)}, + {"computed", IsComputed()}, + {"typeAnnotation", AstDumper::Optional(TypeAnnotation())}, {"definite", IsDefinite()}, - {"decorators", decorators_}, + {"decorators", Decorators()}, {"annotations", AstDumper::Optional(Annotations())}}); } @@ -179,8 +185,9 @@ void ClassProperty::DumpCheckerTypeForDeclGen(ir::SrcDumper *dumper) const } auto typeStr = TsType()->ToString(); - if (TsType()->IsTypeError() && dumper->IsIsolatedDeclgen() && typeAnnotation_ != nullptr) { - typeStr = typeAnnotation_->AsETSTypeReference()->Part()->Name()->AsIdentifier()->Name().Mutf8(); + auto typeAnnotation = TypeAnnotation(); + if (TsType()->IsTypeError() && dumper->IsIsolatedDeclgen() && typeAnnotation != nullptr) { + typeStr = typeAnnotation->AsETSTypeReference()->Part()->Name()->AsIdentifier()->Name().Mutf8(); } dumper->Add(": "); @@ -191,12 +198,13 @@ void ClassProperty::DumpCheckerTypeForDeclGen(ir::SrcDumper *dumper) const bool ClassProperty::RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const { - ES2PANDA_ASSERT(key_); + ES2PANDA_ASSERT(Key() != nullptr); + auto key = Key(); if (!dumper->IsDeclgen()) { return false; } - auto name = key_->AsIdentifier()->Name().Mutf8(); + auto name = key->AsIdentifier()->Name().Mutf8(); if (name.rfind('#', 0) == 0) { return true; } @@ -209,7 +217,7 @@ bool ClassProperty::RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const return false; } - if (key_->Parent()->IsExported() || key_->Parent()->IsDefaultExported()) { + if (key->Parent()->IsExported() || key->Parent()->IsDefaultExported()) { return false; } @@ -224,8 +232,9 @@ void ClassProperty::Dump(ir::SrcDumper *dumper) const } DumpPrefix(dumper); - if (key_ != nullptr) { - key_->Dump(dumper); + auto key = Key(); + if (key != nullptr) { + key->Dump(dumper); } if (IsOptionalDeclaration()) { @@ -236,16 +245,18 @@ void ClassProperty::Dump(ir::SrcDumper *dumper) const dumper->Add("!"); } - if (typeAnnotation_ != nullptr && !dumper->IsDeclgen()) { + auto typeAnnotation = TypeAnnotation(); + if (typeAnnotation != nullptr && !dumper->IsDeclgen()) { dumper->Add(": "); - typeAnnotation_->Dump(dumper); + typeAnnotation->Dump(dumper); } DumpCheckerTypeForDeclGen(dumper); - if (value_ != nullptr && !dumper->IsDeclgen()) { + auto value = Value(); + if (value != nullptr && !dumper->IsDeclgen()) { dumper->Add(" = "); - value_->Dump(dumper); + value->Dump(dumper); } dumper->Add(";"); @@ -274,11 +285,11 @@ checker::VerifiedType ClassProperty::Check(checker::ETSChecker *checker) ClassProperty *ClassProperty::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const key = key_->Clone(allocator, nullptr)->AsExpression(); - auto *const value = value_ != nullptr ? value_->Clone(allocator, nullptr)->AsExpression() : nullptr; - auto *const typeAnnotation = typeAnnotation_ != nullptr ? typeAnnotation_->Clone(allocator, nullptr) : nullptr; + auto *const key = Key()->Clone(allocator, nullptr)->AsExpression(); + auto *const value = Value() != nullptr ? Value()->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const typeAnnotation = TypeAnnotation() != nullptr ? TypeAnnotation()->Clone(allocator, nullptr) : nullptr; - auto *const clone = allocator->New(key, value, typeAnnotation, flags_, allocator, isComputed_); + auto *const clone = allocator->New(key, value, typeAnnotation, Modifiers(), allocator, IsComputed()); if (parent != nullptr) { clone->SetParent(parent); @@ -286,7 +297,7 @@ ClassProperty *ClassProperty::Clone(ArenaAllocator *const allocator, AstNode *co key->SetParent(clone); if (value != nullptr) { - value->SetTsType(value_->TsType()); + value->SetTsType(Value()->TsType()); value->SetParent(clone); } if (typeAnnotation != nullptr) { @@ -294,7 +305,7 @@ ClassProperty *ClassProperty::Clone(ArenaAllocator *const allocator, AstNode *co typeAnnotation->SetParent(clone); } - for (auto *const decorator : decorators_) { + for (auto *const decorator : Decorators()) { clone->AddDecorator(decorator->Clone(allocator, clone)); } @@ -306,14 +317,14 @@ ClassProperty *ClassProperty::Clone(ArenaAllocator *const allocator, AstNode *co clone->SetAnnotations(std::move(annotationUsages)); } - clone->SetRange(range_); + clone->SetRange(Range()); return clone; } ClassProperty *ClassProperty::Construct(ArenaAllocator *allocator) { - return allocator->New(nullptr, nullptr, nullptr, ModifierFlags::NONE, allocator, false); + return allocator->New(nullptr, nullptr, nullptr, ModifierFlags::NONE, allocator, false, history_); } void ClassProperty::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/base/classProperty.h b/ets2panda/ir/base/classProperty.h index 9725118c576..a6c229eced0 100644 --- a/ets2panda/ir/base/classProperty.h +++ b/ets2panda/ir/base/classProperty.h @@ -43,26 +43,42 @@ public: isComputed), typeAnnotation_(typeAnnotation) { + EnableHistory(); + } + + // CC-OFFNXT(G.FUN.01-CPP) solid logic + explicit ClassProperty(Expression *const key, Expression *const value, TypeNode *const typeAnnotation, + ModifierFlags const modifiers, ArenaAllocator *const allocator, bool const isComputed, + AstNodeHistory *history) + : JsDocAllowed>(AstNodeType::CLASS_PROPERTY, key, value, modifiers, allocator, + isComputed), + typeAnnotation_(typeAnnotation) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } [[nodiscard]] bool IsDefaultAccessModifier() const noexcept { - return isDefault_; + return HISTORY_GET(isDefault_); } void SetDefaultAccessModifier(bool isDefault) { - isDefault_ = isDefault; + HISTORY_SET(isDefault_, isDefault); } [[nodiscard]] TypeNode *TypeAnnotation() const noexcept { - return typeAnnotation_; + return HISTORY_GET(typeAnnotation_); } void SetTypeAnnotation(TypeNode *typeAnnotation) noexcept { - typeAnnotation_ = typeAnnotation; + HISTORY_SET(typeAnnotation_, typeAnnotation); } [[nodiscard]] PrivateFieldKind ToPrivateFieldKind(bool const isStatic) const override @@ -89,12 +105,12 @@ public: [[nodiscard]] bool NeedInitInStaticBlock() const { - return needInitInStaticBlock_; + return HISTORY_GET(needInitInStaticBlock_); } void SetInitInStaticBlock(bool needInitInStaticBlock) { - needInitInStaticBlock_ = needInitInStaticBlock; + HISTORY_SET(needInitInStaticBlock_, needInitInStaticBlock); } protected: diff --git a/ets2panda/ir/base/classStaticBlock.cpp b/ets2panda/ir/base/classStaticBlock.cpp index d912d1532bf..04f6525ac52 100644 --- a/ets2panda/ir/base/classStaticBlock.cpp +++ b/ets2panda/ir/base/classStaticBlock.cpp @@ -30,20 +30,22 @@ namespace ark::es2panda::ir { void ClassStaticBlock::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - if (auto *transformedNode = cb(value_); value_ != transformedNode) { - value_->SetTransformedNode(transformationName, transformedNode); - value_ = transformedNode->AsExpression(); + auto value = Value(); + if (auto *transformedNode = cb(value); value != transformedNode) { + value->SetTransformedNode(transformationName, transformedNode); + SetValue(transformedNode->AsExpression()); } } void ClassStaticBlock::Iterate(const NodeTraverser &cb) const { - cb(value_); + auto value = HISTORY_GET(value_); + cb(value); } void ClassStaticBlock::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", "ClassStaticBlock"}, {"value", value_}}); + dumper->Add({{"type", "ClassStaticBlock"}, {"value", Value()}}); } void ClassStaticBlock::Dump([[maybe_unused]] ir::SrcDumper *dumper) const @@ -84,12 +86,12 @@ checker::VerifiedType ClassStaticBlock::Check(checker::ETSChecker *checker) ir::ScriptFunction *ClassStaticBlock::Function() { - return value_->AsFunctionExpression()->Function(); + return Value()->AsFunctionExpression()->Function(); } const ir::ScriptFunction *ClassStaticBlock::Function() const { - return value_->AsFunctionExpression()->Function(); + return Value()->AsFunctionExpression()->Function(); } const util::StringView &ClassStaticBlock::Name() const diff --git a/ets2panda/ir/base/classStaticBlock.h b/ets2panda/ir/base/classStaticBlock.h index a1a1030b757..32e7de0e6e3 100644 --- a/ets2panda/ir/base/classStaticBlock.h +++ b/ets2panda/ir/base/classStaticBlock.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -26,6 +26,17 @@ public: explicit ClassStaticBlock(Expression *value, ArenaAllocator *allocator) : ClassElement(AstNodeType::CLASS_STATIC_BLOCK, nullptr, value, ModifierFlags::NONE, allocator, false) { + EnableHistory(); + } + + explicit ClassStaticBlock(Expression *value, ArenaAllocator *allocator, AstNodeHistory *history) + : ClassElement(AstNodeType::CLASS_STATIC_BLOCK, nullptr, value, ModifierFlags::NONE, allocator, false) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } PrivateFieldKind ToPrivateFieldKind([[maybe_unused]] bool isStatic) const override @@ -51,6 +62,17 @@ public: v->Accept(this); } +protected: + ClassStaticBlock *Construct(ArenaAllocator *allocator) override + { + return allocator->New(nullptr, allocator, history_); + } + + void CopyTo(AstNode *other) const override + { + ClassElement::CopyTo(other); + }; + private: }; } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/base/methodDefinition.cpp b/ets2panda/ir/base/methodDefinition.cpp index cf497838fb2..2021f98f723 100644 --- a/ets2panda/ir/base/methodDefinition.cpp +++ b/ets2panda/ir/base/methodDefinition.cpp @@ -26,17 +26,19 @@ namespace ark::es2panda::ir { ScriptFunction *MethodDefinition::Function() { - return value_->IsFunctionExpression() ? value_->AsFunctionExpression()->Function() : nullptr; + auto value = Value(); + return value->IsFunctionExpression() ? value->AsFunctionExpression()->Function() : nullptr; } const ScriptFunction *MethodDefinition::Function() const { - return value_->IsFunctionExpression() ? value_->AsFunctionExpression()->Function() : nullptr; + auto value = Value(); + return value->IsFunctionExpression() ? value->AsFunctionExpression()->Function() : nullptr; } PrivateFieldKind MethodDefinition::ToPrivateFieldKind(bool const isStatic) const { - switch (kind_) { + switch (Kind()) { case MethodDefinitionKind::METHOD: { return isStatic ? PrivateFieldKind::STATIC_METHOD : PrivateFieldKind::METHOD; } @@ -54,57 +56,69 @@ PrivateFieldKind MethodDefinition::ToPrivateFieldKind(bool const isStatic) const void MethodDefinition::ResolveReferences(const NodeTraverser &cb) const { - cb(key_); - cb(value_); + auto key = HISTORY_GET(key_); + cb(key); - for (auto *it : VectorIterationGuard(overloads_)) { + auto value = HISTORY_GET(value_); + cb(value); + + for (auto *it : VectorIterationGuard(Overloads())) { cb(it); } - for (auto *it : VectorIterationGuard(decorators_)) { + for (auto *it : VectorIterationGuard(Decorators())) { cb(it); } } void MethodDefinition::Iterate(const NodeTraverser &cb) const { - cb(key_); - cb(value_); + auto key = HISTORY_GET(key_); + cb(key); + + auto value = HISTORY_GET(value_); + cb(value); - for (auto *it : overloads_) { + for (auto *it : Overloads()) { if (it->Parent() == this) { cb(it); } } - for (auto *it : VectorIterationGuard(decorators_)) { + for (auto *it : VectorIterationGuard(Decorators())) { cb(it); } } void MethodDefinition::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { - if (auto *transformedNode = cb(key_); key_ != transformedNode) { - key_->SetTransformedNode(transformationName, transformedNode); - key_ = transformedNode->AsExpression(); + auto key = Key(); + if (auto *transformedNode = cb(key); key != transformedNode) { + key->SetTransformedNode(transformationName, transformedNode); + SetKey(transformedNode->AsExpression()); } - if (auto *transformedNode = cb(value_); value_ != transformedNode) { - value_->SetTransformedNode(transformationName, transformedNode); - value_ = transformedNode->AsExpression(); + auto value = Value(); + if (auto *transformedNode = cb(value); value != transformedNode) { + value->SetTransformedNode(transformationName, transformedNode); + SetValue(transformedNode->AsExpression()); } - for (auto *&it : VectorIterationGuard(overloads_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsMethodDefinition(); + auto &overloads = Overloads(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < overloads.size(); ix++) { + if (auto *transformedNode = cb(overloads[ix]); overloads[ix] != transformedNode) { + overloads[ix]->SetTransformedNode(transformationName, transformedNode); + OverloadsMutable()[ix] = transformedNode->AsMethodDefinition(); } } - for (auto *&it : VectorIterationGuard(decorators_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsDecorator(); + auto &decorators = Decorators(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < decorators.size(); ix++) { + if (auto *transformedNode = cb(decorators[ix]); decorators[ix] != transformedNode) { + decorators[ix]->SetTransformedNode(transformationName, transformedNode); + DecoratorsMutable()[ix] = transformedNode->AsDecorator(); } } } @@ -113,7 +127,7 @@ void MethodDefinition::Dump(ir::AstDumper *dumper) const { const char *kind = nullptr; - switch (kind_) { + switch (Kind()) { case MethodDefinitionKind::CONSTRUCTOR: { kind = "constructor"; break; @@ -147,16 +161,17 @@ void MethodDefinition::Dump(ir::AstDumper *dumper) const } } + // CC-OFFNXT(WordsTool.5) sensitive word copnflict dumper->Add({{"type", "MethodDefinition"}, - {"key", key_}, + {"key", Key()}, {"kind", kind}, - {"accessibility", AstDumper::Optional(AstDumper::ModifierToString(flags_))}, + {"accessibility", AstDumper::Optional(AstDumper::ModifierToString(Modifiers()))}, {"static", IsStatic()}, {"optional", IsOptionalDeclaration()}, - {"computed", isComputed_}, - {"value", value_}, - {"overloads", overloads_}, - {"decorators", decorators_}}); + {"computed", IsComputed()}, + {"value", Value()}, + {"overloads", Overloads()}, + {"decorators", Decorators()}}); } void MethodDefinition::DumpModifierPrefix(ir::SrcDumper *dumper) const @@ -218,13 +233,14 @@ void MethodDefinition::DumpPrefixForDeclGen(ir::SrcDumper *dumper) const return; } - if (key_ == nullptr) { + auto key = Key(); + if (key == nullptr) { return; } - if (key_->Parent()->IsExported()) { + if (key->Parent()->IsExported()) { dumper->Add("export declare function "); - } else if (key_->Parent()->IsDefaultExported()) { + } else if (key->Parent()->IsDefaultExported()) { dumper->Add("export default declare function "); } } @@ -266,11 +282,12 @@ bool MethodDefinition::FilterForDeclGen(ir::SrcDumper *dumper) const return false; } - if (key_ == nullptr) { + auto key = Key(); + if (key == nullptr) { return false; } - if (compiler::HasGlobalClassParent(this) && !key_->Parent()->IsExported() && !key_->Parent()->IsDefaultExported()) { + if (compiler::HasGlobalClassParent(this) && !key->Parent()->IsExported() && !key->Parent()->IsDefaultExported()) { return true; } @@ -306,12 +323,13 @@ void MethodDefinition::Dump(ir::SrcDumper *dumper) const return; } - for (auto method : overloads_) { + for (auto method : Overloads()) { method->Dump(dumper); dumper->Endl(); } - for (auto *anno : value_->AsFunctionExpression()->Function()->Annotations()) { + auto value = Value(); + for (auto *anno : value->AsFunctionExpression()->Function()->Annotations()) { // NOTE(zhelyapov): workaround, see #26031 if (anno->GetBaseName()->Name() != compiler::Signatures::DEFAULT_ANNO_FOR_FUNC) { anno->Dump(dumper); @@ -319,12 +337,13 @@ void MethodDefinition::Dump(ir::SrcDumper *dumper) const } DumpPrefix(dumper); - if (key_ != nullptr) { - key_->Dump(dumper); + auto key = Key(); + if (key != nullptr) { + key->Dump(dumper); } - if (value_ != nullptr) { - value_->Dump(dumper); + if (value != nullptr) { + value->Dump(dumper); } } @@ -350,9 +369,9 @@ checker::VerifiedType MethodDefinition::Check(checker::ETSChecker *checker) MethodDefinition *MethodDefinition::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const key = key_->Clone(allocator, nullptr)->AsExpression(); - auto *const value = value_->Clone(allocator, nullptr)->AsExpression(); - auto *const clone = allocator->New(kind_, key, value, flags_, allocator, isComputed_); + auto *const key = Key()->Clone(allocator, nullptr)->AsExpression(); + auto *const value = Value()->Clone(allocator, nullptr)->AsExpression(); + auto *const clone = allocator->New(Kind(), key, value, Modifiers(), allocator, IsComputed()); if (parent != nullptr) { clone->SetParent(parent); @@ -361,13 +380,13 @@ MethodDefinition *MethodDefinition::Clone(ArenaAllocator *const allocator, AstNo key->SetParent(clone); value->SetParent(clone); - for (auto *const decorator : decorators_) { + for (auto *const decorator : Decorators()) { clone->AddDecorator(decorator->Clone(allocator, clone)); } - clone->baseOverloadMethod_ = baseOverloadMethod_; + clone->SetBaseOverloadMethod(BaseOverloadMethod()); - for (auto *const overloads : overloads_) { + for (auto *const overloads : Overloads()) { clone->AddOverload(overloads->Clone(allocator, clone)); } @@ -378,19 +397,16 @@ void MethodDefinition::InitializeOverloadInfo() { ES2PANDA_ASSERT(this->Function() != nullptr); - overloadInfo_ = {this->Function()->Signature()->MinArgCount(), - this->Function()->Signature()->ArgCount(), - false, - this->IsDeclare(), - (this->Function()->Signature()->RestVar() != nullptr), - this->Function()->Signature()->ReturnType()->IsETSVoidType()}; + SetOverloadInfo({this->Function()->Signature()->MinArgCount(), this->Function()->Signature()->ArgCount(), false, + this->IsDeclare(), (this->Function()->Signature()->RestVar() != nullptr), + this->Function()->Signature()->ReturnType()->IsETSVoidType()}); } void MethodDefinition::ResetOverloads() { - auto baseOverloadMethod = baseOverloadMethod_; - baseOverloadMethod_ = nullptr; - for (auto *overload : overloads_) { + auto baseOverloadMethod = BaseOverloadMethod(); + SetBaseOverloadMethod(nullptr); + for (auto *overload : Overloads()) { overload->CleanUp(); } ClearOverloads(); @@ -411,7 +427,7 @@ void MethodDefinition::ResetOverloads() auto parent = baseOverloadMethod->Parent(); ES2PANDA_ASSERT(parent->IsClassDefinition() || parent->IsTSInterfaceBody()); auto &body = - parent->IsClassDefinition() ? parent->AsClassDefinition()->Body() : parent->AsTSInterfaceBody()->Body(); + parent->IsClassDefinition() ? parent->AsClassDefinition()->BodyMutable() : parent->AsTSInterfaceBody()->Body(); for (auto *elem : body) { if (elem == this) { diff --git a/ets2panda/ir/base/methodDefinition.h b/ets2panda/ir/base/methodDefinition.h index 22b53211293..fa0df6e7a54 100644 --- a/ets2panda/ir/base/methodDefinition.h +++ b/ets2panda/ir/base/methodDefinition.h @@ -66,113 +66,135 @@ public: baseOverloadMethod_(nullptr), asyncPairMethod_(nullptr) { + EnableHistory(); } - // NOTE (csabahurton): these friend relationships can be removed once there are getters for private fields - friend class checker::ETSAnalyzer; + // CC-OFFNXT(G.FUN.01-CPP) solid logic + explicit MethodDefinition(MethodDefinitionKind const kind, Expression *const key, Expression *const value, + ModifierFlags const modifiers, ArenaAllocator *const allocator, bool const isComputed, + AstNodeHistory *history) + : ClassElement(AstNodeType::METHOD_DEFINITION, key, value, modifiers, allocator, isComputed), + kind_(kind), + overloads_(allocator->Adapter()), + baseOverloadMethod_(nullptr), + asyncPairMethod_(nullptr) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } + } MethodDefinitionKind Kind() const { - return kind_; + return HISTORY_GET(kind_); } [[nodiscard]] bool IsConstructor() const noexcept { - return kind_ == MethodDefinitionKind::CONSTRUCTOR; + return Kind() == MethodDefinitionKind::CONSTRUCTOR; } [[nodiscard]] bool IsMethod() const noexcept { - return kind_ == MethodDefinitionKind::METHOD; + return Kind() == MethodDefinitionKind::METHOD; } [[nodiscard]] bool IsExtensionMethod() const noexcept { - return (kind_ == MethodDefinitionKind::EXTENSION_METHOD) || (kind_ == MethodDefinitionKind::EXTENSION_GET) || - (kind_ == MethodDefinitionKind::EXTENSION_SET); + auto kind = Kind(); + return (kind == MethodDefinitionKind::EXTENSION_METHOD) || (kind == MethodDefinitionKind::EXTENSION_GET) || + (kind == MethodDefinitionKind::EXTENSION_SET); } [[nodiscard]] bool IsGetter() const noexcept { - return kind_ == MethodDefinitionKind::GET; + return Kind() == MethodDefinitionKind::GET; } [[nodiscard]] bool IsSetter() const noexcept { - return kind_ == MethodDefinitionKind::SET; + return Kind() == MethodDefinitionKind::SET; } [[nodiscard]] bool IsDefaultAccessModifier() const noexcept { - return isDefault_; + return HISTORY_GET(isDefault_); } void SetDefaultAccessModifier(bool isDefault) { - isDefault_ = isDefault; + HISTORY_SET(isDefault_, isDefault); } [[nodiscard]] const OverloadsT &Overloads() const noexcept { - return overloads_; + return HISTORY_GET(overloads_); + } + + [[nodiscard]] ArenaVector &OverloadsMutable() noexcept + { + return HISTORY_GET_OR_CREATE(overloads_); } [[nodiscard]] const MethodDefinition *BaseOverloadMethod() const noexcept { - return baseOverloadMethod_; + return HISTORY_GET(baseOverloadMethod_); } [[nodiscard]] MethodDefinition *BaseOverloadMethod() noexcept { - return baseOverloadMethod_; + return HISTORY_GET(baseOverloadMethod_); } [[nodiscard]] const MethodDefinition *AsyncPairMethod() const noexcept { - return asyncPairMethod_; + return HISTORY_GET(asyncPairMethod_); } [[nodiscard]] MethodDefinition *AsyncPairMethod() noexcept { - return asyncPairMethod_; + return HISTORY_GET(asyncPairMethod_); } [[nodiscard]] OverloadInfo &GetOverloadInfo() noexcept { - return overloadInfo_; + return HISTORY_GET_OR_CREATE(overloadInfo_); } void SetOverloads(OverloadsT &&overloads) { - overloads_ = std::move(overloads); + HISTORY_GET_OR_CREATE(overloads_) = std::move(overloads); } void ClearOverloads() { - overloads_.clear(); + OverloadsMutable().clear(); } void AddOverload(MethodDefinition *const overload) { ES2PANDA_ASSERT(overload != nullptr); - overloads_.emplace_back(overload); + HISTORY_GET_OR_CREATE(overloads_).emplace_back(overload); overload->Function()->AddFlag((ir::ScriptFunctionFlags::OVERLOAD)); overload->SetBaseOverloadMethod(this); } void SetBaseOverloadMethod(MethodDefinition *const baseOverloadMethod) { - baseOverloadMethod_ = baseOverloadMethod; + HISTORY_SET(baseOverloadMethod_, baseOverloadMethod); } void SetAsyncPairMethod(MethodDefinition *const method) { - asyncPairMethod_ = method; + HISTORY_SET(asyncPairMethod_, method); } [[nodiscard]] bool HasOverload(MethodDefinition *overload) noexcept { - return std::find(overloads_.begin(), overloads_.end(), overload) != overloads_.end(); + auto &overloads = Overloads(); + return std::find(overloads.begin(), overloads.end(), overload) != overloads.end(); } ScriptFunction *Function(); @@ -213,6 +235,11 @@ private: void DumpPrefixForDeclGen(ir::SrcDumper *dumper) const; bool FilterForDeclGen(ir::SrcDumper *dumper) const; + void SetOverloadInfo(const OverloadInfo &overloadInfo) + { + HISTORY_GET_OR_CREATE(overloadInfo_) = overloadInfo; + } + friend class SizeOfNodeTest; bool isDefault_ = false; MethodDefinitionKind kind_; diff --git a/ets2panda/ir/base/scriptFunction.cpp b/ets2panda/ir/base/scriptFunction.cpp index 0eb77cd6c8a..3ea9a3905e2 100644 --- a/ets2panda/ir/base/scriptFunction.cpp +++ b/ets2panda/ir/base/scriptFunction.cpp @@ -44,13 +44,40 @@ ScriptFunction::ScriptFunction(ArenaAllocator *allocator, ScriptFunctionData &&d if (auto *typeParams = irSignature_.TypeParams(); typeParams != nullptr) { typeParams->SetParent(this); } + EnableHistory(); +} + +ScriptFunction::ScriptFunction(ArenaAllocator *allocator, ScriptFunctionData &&data, AstNodeHistory *history) + : JsDocAllowed>(AstNodeType::SCRIPT_FUNCTION, data.flags, allocator), + irSignature_(std::move(data.signature)), + body_(data.body), + funcFlags_(data.funcFlags), + lang_(data.lang), + returnStatements_(allocator->Adapter()) +{ + for (auto *param : irSignature_.Params()) { + param->SetParent(this); + } + + if (auto *returnType = irSignature_.ReturnType(); returnType != nullptr) { + returnType->SetParent(this); + } + + if (auto *typeParams = irSignature_.TypeParams(); typeParams != nullptr) { + typeParams->SetParent(this); + } + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } std::size_t ScriptFunction::FormalParamsLength() const noexcept { std::size_t length = 0U; - for (const auto *param : irSignature_.Params()) { + for (const auto *param : Params()) { if (param->IsRestElement() || param->IsAssignmentPattern()) { break; } @@ -63,8 +90,8 @@ std::size_t ScriptFunction::FormalParamsLength() const noexcept void ScriptFunction::SetIdent(Identifier *id) noexcept { - id_ = id; - id_->SetParent(this); + HISTORY_SET(id_, id); + id->SetParent(this); } ScriptFunction *ScriptFunction::Clone(ArenaAllocator *allocator, AstNode *parent) @@ -80,7 +107,7 @@ ScriptFunction *ScriptFunction::Clone(ArenaAllocator *allocator, AstNode *parent auto *res = util::NodeAllocator::ForceSetParent( allocator, allocator, ScriptFunctionData { - body_ != nullptr ? body_->Clone(allocator, nullptr) : nullptr, + Body() != nullptr ? Body()->Clone(allocator, nullptr) : nullptr, FunctionSignature { TypeParams() != nullptr ? TypeParams()->Clone(allocator, nullptr)->AsTSTypeParameterDeclaration() : nullptr, @@ -88,7 +115,7 @@ ScriptFunction *ScriptFunction::Clone(ArenaAllocator *allocator, AstNode *parent ReturnTypeAnnotation() != nullptr ? ReturnTypeAnnotation()->Clone(allocator, nullptr)->AsTypeNode() : nullptr, HasReceiver()}, - funcFlags_, flags_, lang_}); + Flags(), Modifiers(), Language()}); res->SetParent(parent); res->SetAnnotations(std::move(annotationUsages)); return res; @@ -96,38 +123,38 @@ ScriptFunction *ScriptFunction::Clone(ArenaAllocator *allocator, AstNode *parent void ScriptFunction::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { - if (id_ != nullptr) { - if (auto *transformedNode = cb(id_); id_ != transformedNode) { - id_->SetTransformedNode(transformationName, transformedNode); - id_ = transformedNode->AsIdentifier(); + auto id = Id(); + if (id != nullptr) { + if (auto *transformedNode = cb(id); id != transformedNode) { + id->SetTransformedNode(transformationName, transformedNode); + SetIdent(transformedNode->AsIdentifier()); } } - irSignature_.TransformChildren(cb, transformationName); + HISTORY_GET(irSignature_).TransformChildren(cb, transformationName); - if (body_ != nullptr) { - if (auto *transformedNode = cb(body_); body_ != transformedNode) { - body_->SetTransformedNode(transformationName, transformedNode); - body_ = transformedNode; + auto body = Body(); + if (body != nullptr) { + if (auto *transformedNode = cb(body); body != transformedNode) { + body->SetTransformedNode(transformationName, transformedNode); + SetBody(transformedNode); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void ScriptFunction::Iterate(const NodeTraverser &cb) const { - if (id_ != nullptr) { - cb(id_); + auto id = HISTORY_GET(id_); + if (id != nullptr) { + cb(id); } - irSignature_.Iterate(cb); - if (body_ != nullptr) { - cb(body_); + HISTORY_GET(irSignature_).Iterate(cb); + + auto body = HISTORY_GET(body_); + if (body != nullptr) { + cb(body); } for (auto *it : VectorIterationGuard(Annotations())) { cb(it); @@ -136,7 +163,7 @@ void ScriptFunction::Iterate(const NodeTraverser &cb) const void ScriptFunction::SetReturnTypeAnnotation(TypeNode *node) noexcept { - irSignature_.SetReturnType(node); + HISTORY_GET_OR_CREATE(irSignature_).SetReturnType(node); if (node != nullptr) { node->SetParent(this); } @@ -151,15 +178,15 @@ void ScriptFunction::Dump(ir::AstDumper *dumper) const throwMarker = "rethrows"; } dumper->Add({{"type", "ScriptFunction"}, - {"id", AstDumper::Nullish(id_)}, + {"id", AstDumper::Nullish(Id())}, {"generator", IsGenerator()}, {"async", IsAsyncFunc()}, - {"expression", ((funcFlags_ & ir::ScriptFunctionFlags::EXPRESSION) != 0)}, - {"params", irSignature_.Params()}, - {"returnType", AstDumper::Optional(irSignature_.ReturnType())}, - {"typeParameters", AstDumper::Optional(irSignature_.TypeParams())}, + {"expression", ((Flags() & ir::ScriptFunctionFlags::EXPRESSION) != 0)}, + {"params", Params()}, + {"returnType", AstDumper::Optional(ReturnTypeAnnotation())}, + {"typeParameters", AstDumper::Optional(TypeParams())}, {"declare", AstDumper::Optional(IsDeclare())}, - {"body", AstDumper::Optional(body_)}, + {"body", AstDumper::Optional(Body())}, {"annotations", AstDumper::Optional(Annotations())}, {"throwMarker", AstDumper::Optional(throwMarker)}}); } @@ -234,9 +261,9 @@ void ScriptFunction::DumpBody(ir::SrcDumper *dumper) const dumper->Add(" =>"); } - if (body_->IsBlockStatement()) { + if (Body()->IsBlockStatement()) { dumper->Add(" {"); - const auto &statements = body_->AsBlockStatement()->Statements(); + auto &statements = Body()->AsBlockStatement()->Statements(); if (!statements.empty()) { dumper->IncrIndent(); dumper->Endl(); @@ -279,7 +306,8 @@ ScriptFunction *ScriptFunction::Construct(ArenaAllocator *allocator) auto adapter = allocator->Adapter(); return allocator->New( allocator, - ScriptFunctionData {nullptr, FunctionSignature(nullptr, ArenaVector(adapter), nullptr)}); + ScriptFunctionData {nullptr, FunctionSignature(nullptr, ArenaVector(adapter), nullptr)}, + history_); } void ScriptFunction::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/base/scriptFunction.h b/ets2panda/ir/base/scriptFunction.h index 56516356429..49738269a4e 100644 --- a/ets2panda/ir/base/scriptFunction.h +++ b/ets2panda/ir/base/scriptFunction.h @@ -56,136 +56,138 @@ public: explicit ScriptFunction(ArenaAllocator *allocator, ScriptFunctionData &&data); + explicit ScriptFunction(ArenaAllocator *allocator, ScriptFunctionData &&data, AstNodeHistory *history); + [[nodiscard]] const Identifier *Id() const noexcept { - return id_; + return HISTORY_GET(id_); } [[nodiscard]] Identifier *Id() noexcept { - return id_; + return HISTORY_GET(id_); } [[nodiscard]] const checker::Signature *Signature() const noexcept { - return signature_; + return HISTORY_GET(signature_); } [[nodiscard]] checker::Signature *Signature() noexcept { - return signature_; + return HISTORY_GET(signature_); } [[nodiscard]] const ArenaVector &Params() const noexcept { - return irSignature_.Params(); + return HISTORY_GET(irSignature_).Params(); } - [[nodiscard]] ArenaVector &Params() noexcept + [[nodiscard]] ArenaVector &ParamsMutable() noexcept { - return irSignature_.Params(); + return HISTORY_GET_OR_CREATE(irSignature_).Params(); } const ArenaVector &ReturnStatements() const { - return returnStatements_; + return HISTORY_GET(returnStatements_); } - ArenaVector &ReturnStatements() + ArenaVector &ReturnStatementsMutable() noexcept { - return returnStatements_; + return HISTORY_GET_OR_CREATE(returnStatements_); } [[nodiscard]] const TSTypeParameterDeclaration *TypeParams() const noexcept { - return irSignature_.TypeParams(); + return HISTORY_GET(irSignature_).TypeParams(); } [[nodiscard]] TSTypeParameterDeclaration *TypeParams() noexcept { - return irSignature_.TypeParams(); + return HISTORY_GET(irSignature_).TypeParams(); } [[nodiscard]] const AstNode *Body() const noexcept { - return body_; + return HISTORY_GET(body_); } [[nodiscard]] AstNode *Body() noexcept { - return body_; + return HISTORY_GET(body_); } void AddReturnStatement(ReturnStatement *returnStatement) { - returnStatements_.push_back(returnStatement); + ReturnStatementsMutable().emplace_back(returnStatement); } void SetBody(AstNode *body) noexcept { - body_ = body; + HISTORY_SET(body_, body); } [[nodiscard]] const TypeNode *ReturnTypeAnnotation() const noexcept { - return irSignature_.ReturnType(); + return HISTORY_GET(irSignature_).ReturnType(); } [[nodiscard]] TypeNode *ReturnTypeAnnotation() noexcept { - return irSignature_.ReturnType(); + return HISTORY_GET(irSignature_).ReturnType(); } void SetReturnTypeAnnotation(TypeNode *node) noexcept; [[nodiscard]] bool IsEntryPoint() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::ENTRY_POINT) != 0; + return (Flags() & ir::ScriptFunctionFlags::ENTRY_POINT) != 0; } [[nodiscard]] bool IsGenerator() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::GENERATOR) != 0; + return (Flags() & ir::ScriptFunctionFlags::GENERATOR) != 0; } [[nodiscard]] bool IsAsyncFunc() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::ASYNC) != 0; + return (Flags() & ir::ScriptFunctionFlags::ASYNC) != 0; } [[nodiscard]] bool IsAsyncImplFunc() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::ASYNC_IMPL) != 0; + return (Flags() & ir::ScriptFunctionFlags::ASYNC_IMPL) != 0; } [[nodiscard]] bool IsArrow() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::ARROW) != 0; + return (Flags() & ir::ScriptFunctionFlags::ARROW) != 0; } [[nodiscard]] bool IsOverload() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::OVERLOAD) != 0; + return (Flags() & ir::ScriptFunctionFlags::OVERLOAD) != 0; } [[nodiscard]] bool IsExternalOverload() const { - return (funcFlags_ & ir::ScriptFunctionFlags::EXTERNAL_OVERLOAD) != 0; + return (Flags() & ir::ScriptFunctionFlags::EXTERNAL_OVERLOAD) != 0; } [[nodiscard]] bool IsConstructor() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::CONSTRUCTOR) != 0; + return (Flags() & ir::ScriptFunctionFlags::CONSTRUCTOR) != 0; } [[nodiscard]] bool IsGetter() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::GETTER) != 0; + return (Flags() & ir::ScriptFunctionFlags::GETTER) != 0; } [[nodiscard]] bool IsSetter() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::SETTER) != 0; + return (Flags() & ir::ScriptFunctionFlags::SETTER) != 0; } [[nodiscard]] bool IsExtensionAccessor() const noexcept @@ -195,72 +197,72 @@ public: [[nodiscard]] bool IsMethod() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::METHOD) != 0; + return (Flags() & ir::ScriptFunctionFlags::METHOD) != 0; } [[nodiscard]] bool IsProxy() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::PROXY) != 0; + return (Flags() & ir::ScriptFunctionFlags::PROXY) != 0; } [[nodiscard]] bool IsStaticBlock() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::STATIC_BLOCK) != 0; + return (Flags() & ir::ScriptFunctionFlags::STATIC_BLOCK) != 0; } [[nodiscard]] bool IsEnum() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::ENUM) != 0; + return (Flags() & ir::ScriptFunctionFlags::ENUM) != 0; } [[nodiscard]] bool IsHidden() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::HIDDEN) != 0; + return (Flags() & ir::ScriptFunctionFlags::HIDDEN) != 0; } [[nodiscard]] bool IsExternal() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::EXTERNAL) != 0; + return (Flags() & ir::ScriptFunctionFlags::EXTERNAL) != 0; } [[nodiscard]] bool IsImplicitSuperCallNeeded() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::IMPLICIT_SUPER_CALL_NEEDED) != 0; + return (Flags() & ir::ScriptFunctionFlags::IMPLICIT_SUPER_CALL_NEEDED) != 0; } [[nodiscard]] bool HasBody() const noexcept { - return body_ != nullptr; + return Body() != nullptr; } [[nodiscard]] bool HasRestParameter() const noexcept { - return signature_->RestVar() != nullptr; + return Signature()->RestVar() != nullptr; } [[nodiscard]] bool HasReturnStatement() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::HAS_RETURN) != 0; + return (Flags() & ir::ScriptFunctionFlags::HAS_RETURN) != 0; } [[nodiscard]] bool HasThrowStatement() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::HAS_THROW) != 0; + return (Flags() & ir::ScriptFunctionFlags::HAS_THROW) != 0; } [[nodiscard]] bool IsThrowing() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::THROWS) != 0; + return (Flags() & ir::ScriptFunctionFlags::THROWS) != 0; } [[nodiscard]] bool IsRethrowing() const noexcept { - return (funcFlags_ & ir::ScriptFunctionFlags::RETHROWS) != 0; + return (Flags() & ir::ScriptFunctionFlags::RETHROWS) != 0; } [[nodiscard]] bool IsDynamic() const noexcept { - return lang_.IsDynamic(); + return Language().IsDynamic(); } // Note: This method has been written into CAPI, cannot remove it simply. @@ -271,34 +273,38 @@ public: [[nodiscard]] ir::ScriptFunctionFlags Flags() const noexcept { - return funcFlags_; + return HISTORY_GET(funcFlags_); } [[nodiscard]] bool HasReceiver() const noexcept { - return irSignature_.HasReceiver(); + return HISTORY_GET(irSignature_).HasReceiver(); } void SetIdent(Identifier *id) noexcept; void SetSignature(checker::Signature *signature) noexcept { - signature_ = signature; + HISTORY_SET(signature_, signature); } void AddFlag(ir::ScriptFunctionFlags flags) noexcept { - funcFlags_ |= flags; + if (!All(Flags(), flags)) { + HISTORY_GET_OR_CREATE(funcFlags_) |= flags; + } } void ClearFlag(ir::ScriptFunctionFlags flags) noexcept { - funcFlags_ &= (~flags); + if (Any(Flags(), flags)) { + HISTORY_GET_OR_CREATE(funcFlags_) &= ~flags; + } } void AddModifier(ir::ModifierFlags flags) noexcept { - flags_ |= flags; + AstNode::AddModifier(flags); } [[nodiscard]] std::size_t FormalParamsLength() const noexcept; @@ -310,37 +316,37 @@ public: [[nodiscard]] varbinder::FunctionScope *Scope() const noexcept override { - return scope_; + return HISTORY_GET(scope_); } void SetScope(varbinder::FunctionScope *scope) noexcept { - scope_ = scope; + HISTORY_SET(scope_, scope); } void ClearScope() noexcept override { - scope_ = nullptr; + SetScope(nullptr); } [[nodiscard]] es2panda::Language Language() const noexcept { - return lang_; + return HISTORY_GET(lang_); } void SetPreferredReturnType(checker::Type *preferredReturnType) noexcept { - preferredReturnType_ = preferredReturnType; + HISTORY_SET(preferredReturnType_, preferredReturnType); } [[nodiscard]] checker::Type *GetPreferredReturnType() noexcept { - return preferredReturnType_; + return HISTORY_GET(preferredReturnType_); } [[nodiscard]] checker::Type const *GetPreferredReturnType() const noexcept { - return preferredReturnType_; + return HISTORY_GET(preferredReturnType_); } [[nodiscard]] ScriptFunction *Clone(ArenaAllocator *allocator, AstNode *parent) override; @@ -357,12 +363,12 @@ public: void SetIsolatedDeclgenReturnType(std::string type) noexcept { - isolatedDeclGenInferType_ = std::move(type); + HISTORY_GET_OR_CREATE(isolatedDeclGenInferType_) = std::move(type); } [[nodiscard]] std::string GetIsolatedDeclgenReturnType() const noexcept { - return isolatedDeclGenInferType_; + return HISTORY_GET(isolatedDeclGenInferType_); } void Accept(ASTVisitorT *v) override @@ -373,8 +379,8 @@ public: void CleanUp() override { AstNode::CleanUp(); - signature_ = nullptr; - preferredReturnType_ = nullptr; + SetSignature(nullptr); + SetPreferredReturnType(nullptr); } protected: diff --git a/ets2panda/ir/base/scriptFunctionSignature.h b/ets2panda/ir/base/scriptFunctionSignature.h index b3918b5fbe9..63b9a50bd7f 100644 --- a/ets2panda/ir/base/scriptFunctionSignature.h +++ b/ets2panda/ir/base/scriptFunctionSignature.h @@ -93,6 +93,7 @@ private: bool hasReceiver_; friend class ScriptFunction; + friend class ETSFunctionType; void CopyFrom(const FunctionSignature &other) { typeParams_ = other.typeParams_; diff --git a/ets2panda/ir/ets/etsFunctionType.cpp b/ets2panda/ir/ets/etsFunctionType.cpp index da4e93b20cf..a7448fa7eb1 100644 --- a/ets2panda/ir/ets/etsFunctionType.cpp +++ b/ets2panda/ir/ets/etsFunctionType.cpp @@ -23,18 +23,13 @@ namespace ark::es2panda::ir { void ETSFunctionType::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - signature_.TransformChildren(cb, transformationName); - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + HISTORY_GET(signature_).TransformChildren(cb, transformationName); + TransformAnnotations(cb, transformationName); } void ETSFunctionType::Iterate(const NodeTraverser &cb) const { - signature_.Iterate(cb); + HISTORY_GET(signature_).Iterate(cb); for (auto *it : VectorIterationGuard(Annotations())) { cb(it); } @@ -49,9 +44,9 @@ void ETSFunctionType::Dump(ir::AstDumper *dumper) const throwMarker = "rethrows"; } dumper->Add({{"type", "ETSFunctionType"}, - {"params", signature_.Params()}, - {"typeParameters", AstDumper::Optional(signature_.TypeParams())}, - {"returnType", signature_.ReturnType()}, + {"params", Params()}, + {"typeParameters", AstDumper::Optional(TypeParams())}, + {"returnType", ReturnType()}, {"throwMarker", AstDumper::Optional(throwMarker)}, {"annotations", AstDumper::Optional(Annotations())}}); } @@ -122,19 +117,17 @@ ETSFunctionType *ETSFunctionType::Clone(ArenaAllocator *const allocator, AstNode { ArenaVector paramsClone(allocator->Adapter()); - for (auto *const param : signature_.Params()) { + for (auto *const param : Params()) { paramsClone.emplace_back(param->Clone(allocator, nullptr)->AsExpression()); } auto *const typeParamsClone = - signature_.TypeParams() != nullptr - ? signature_.TypeParams()->Clone(allocator, nullptr)->AsTSTypeParameterDeclaration() - : nullptr; + TypeParams() != nullptr ? TypeParams()->Clone(allocator, nullptr)->AsTSTypeParameterDeclaration() : nullptr; auto *const returnTypeClone = - signature_.ReturnType() != nullptr ? signature_.ReturnType()->Clone(allocator, nullptr)->AsTypeNode() : nullptr; + ReturnType() != nullptr ? ReturnType()->Clone(allocator, nullptr)->AsTypeNode() : nullptr; auto *const clone = allocator->New( - FunctionSignature(typeParamsClone, std::move(paramsClone), returnTypeClone), funcFlags_, allocator); + FunctionSignature(typeParamsClone, std::move(paramsClone), returnTypeClone), Flags(), allocator); if (typeParamsClone != nullptr) { typeParamsClone->SetParent(clone); @@ -162,8 +155,27 @@ ETSFunctionType *ETSFunctionType::Clone(ArenaAllocator *const allocator, AstNode // If the scope is set to empty, it will result in the inability to retrieve the scope after clone, // and an error cannot find type will be reported - clone->SetScope(this->scope_); + clone->SetScope(Scope()); return clone; } + +AstNode *ETSFunctionType::Construct(ArenaAllocator *allocator) +{ + return allocator->New( + FunctionSignature {nullptr, ArenaVector {allocator->Adapter()}, nullptr}, + ir::ScriptFunctionFlags::NONE, allocator, history_); +} + +void ETSFunctionType::CopyTo(AstNode *other) const +{ + auto otherImpl = other->AsETSFunctionType(); + + otherImpl->scope_ = scope_; + otherImpl->signature_.CopyFrom(signature_); + otherImpl->functionalInterface_ = functionalInterface_; + otherImpl->funcFlags_ = funcFlags_; + + TypeNode::CopyTo(other); +} } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/ets/etsFunctionType.h b/ets2panda/ir/ets/etsFunctionType.h index b6ae35203b3..d6a619e533f 100644 --- a/ets2panda/ir/ets/etsFunctionType.h +++ b/ets2panda/ir/ets/etsFunctionType.h @@ -32,6 +32,18 @@ public: ArenaAllocator *const allocator) noexcept : TypeNode(AstNodeType::ETS_FUNCTION_TYPE, allocator), signature_(std::move(signature)), funcFlags_(funcFlags) { + EnableHistory(); + } + + explicit ETSFunctionType(FunctionSignature &&signature, ir::ScriptFunctionFlags const funcFlags, + ArenaAllocator *const allocator, AstNodeHistory *history) noexcept + : TypeNode(AstNodeType::ETS_FUNCTION_TYPE, allocator), signature_(std::move(signature)), funcFlags_(funcFlags) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } ETSFunctionType() = delete; @@ -46,77 +58,77 @@ public: [[nodiscard]] varbinder::Scope *Scope() const noexcept override { - return scope_; + return HISTORY_GET(scope_); } void SetScope(varbinder::Scope *scope) { - scope_ = scope; + HISTORY_SET(scope_, scope); } void ClearScope() noexcept override { - scope_ = nullptr; + SetScope(nullptr); } const TSTypeParameterDeclaration *TypeParams() const { - return signature_.TypeParams(); + return HISTORY_GET(signature_).TypeParams(); } TSTypeParameterDeclaration *TypeParams() { - return signature_.TypeParams(); + return HISTORY_GET(signature_).TypeParams(); } const ArenaVector &Params() const { - return signature_.Params(); + return HISTORY_GET(signature_).Params(); } const TypeNode *ReturnType() const { - return signature_.ReturnType(); + return HISTORY_GET(signature_).ReturnType(); } TypeNode *ReturnType() { - return signature_.ReturnType(); + return HISTORY_GET(signature_).ReturnType(); } ir::TSInterfaceDeclaration *FunctionalInterface() { - return functionalInterface_; + return HISTORY_GET(functionalInterface_); } const ir::TSInterfaceDeclaration *FunctionalInterface() const { - return functionalInterface_; + return HISTORY_GET(functionalInterface_); } void SetFunctionalInterface(ir::TSInterfaceDeclaration *functionalInterface) { - functionalInterface_ = functionalInterface; + HISTORY_SET(functionalInterface_, functionalInterface); } - ir::ScriptFunctionFlags Flags() + ir::ScriptFunctionFlags Flags() const { - return funcFlags_; + return HISTORY_GET(funcFlags_); } bool IsThrowing() const { - return (funcFlags_ & ir::ScriptFunctionFlags::THROWS) != 0; + return (Flags() & ir::ScriptFunctionFlags::THROWS) != 0; } bool IsRethrowing() const { - return (funcFlags_ & ir::ScriptFunctionFlags::RETHROWS) != 0; + return (Flags() & ir::ScriptFunctionFlags::RETHROWS) != 0; } bool IsExtensionFunction() const { - return signature_.HasReceiver(); + return HISTORY_GET(signature_).HasReceiver(); } void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; @@ -137,7 +149,14 @@ public: [[nodiscard]] ETSFunctionType *Clone(ArenaAllocator *allocator, AstNode *parent) override; +protected: + AstNode *Construct(ArenaAllocator *allocator) override; + + void CopyTo(AstNode *other) const override; + private: + friend class SizeOfNodeTest; + varbinder::Scope *scope_ {}; FunctionSignature signature_; ir::TSInterfaceDeclaration *functionalInterface_ {}; diff --git a/ets2panda/ir/ets/etsImportDeclaration.h b/ets2panda/ir/ets/etsImportDeclaration.h index 4abdaff7648..a94c475b6a9 100644 --- a/ets2panda/ir/ets/etsImportDeclaration.h +++ b/ets2panda/ir/ets/etsImportDeclaration.h @@ -32,6 +32,7 @@ public: : ImportDeclaration(importPath, std::move(specifiers), importKinds), importMetadata_(importMetadata) { SetType(AstNodeType::ETS_IMPORT_DECLARATION); + EnableHistory(); } ETSImportDeclaration(ir::StringLiteral *importPath, ArenaVector &&specifiers, @@ -39,36 +40,44 @@ public: : ETSImportDeclaration(importPath, util::ImportPathManager::ImportMetadata {}, std::move(specifiers), importKinds) { + EnableHistory(); + } + + ETSImportDeclaration(ir::StringLiteral *importPath, ArenaVector &&specifiers, AstNodeHistory *history) + : ETSImportDeclaration(importPath, util::ImportPathManager::ImportMetadata {}, std::move(specifiers), + ImportKinds::ALL) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } void SetImportMetadata(util::ImportFlags importFlags, Language::Id lang, std::string_view resolvedSource, std::string_view declPath, std::string_view ohmUrl) { - importMetadata_.importFlags = importFlags; - importMetadata_.lang = lang; - importMetadata_.resolvedSource = resolvedSource; - importMetadata_.declPath = declPath; - importMetadata_.ohmUrl = ohmUrl; + HISTORY_GET_OR_CREATE(importMetadata_) = {importFlags, lang, resolvedSource, declPath, ohmUrl}; } es2panda::Language Language() const { - return es2panda::Language {importMetadata_.lang}; + return es2panda::Language {ImportMetadata().lang}; } std::string_view DeclPath() const { - return importMetadata_.declPath; + return ImportMetadata().declPath; } std::string_view OhmUrl() const { - return importMetadata_.ohmUrl; + return ImportMetadata().ohmUrl; } bool IsValid() const { - return (Source()->Str() != ERROR_LITERAL) && importMetadata_.IsValid(); + return (Source()->Str() != ERROR_LITERAL) && ImportMetadata().IsValid(); } bool IsPureDynamic() const @@ -78,22 +87,22 @@ public: util::StringView &AssemblerName() { - return assemblerName_; + return HISTORY_GET_OR_CREATE(assemblerName_); } const util::StringView &AssemblerName() const { - return assemblerName_; + return HISTORY_GET(assemblerName_); } std::string_view ResolvedSource() const { - return importMetadata_.resolvedSource; + return ImportMetadata().resolvedSource; } - const auto &ImportMetadata() const + const util::ImportPathManager::ImportMetadata &ImportMetadata() const { - return importMetadata_; + return HISTORY_GET(importMetadata_); } void Accept(ASTVisitorT *v) override @@ -101,6 +110,22 @@ public: v->Accept(this); } + ETSImportDeclaration *Construct(ArenaAllocator *allocator) override + { + ArenaVector specifiers(allocator->Adapter()); + return allocator->New(nullptr, std::move(specifiers), history_); + } + + void CopyTo(AstNode *other) const override + { + auto otherImpl = other->AsETSImportDeclaration(); + + otherImpl->importMetadata_ = importMetadata_; + otherImpl->assemblerName_ = assemblerName_; + + ImportDeclaration::CopyTo(other); + }; + private: util::ImportPathManager::ImportMetadata importMetadata_; util::StringView assemblerName_ {}; diff --git a/ets2panda/ir/ets/etsModule.cpp b/ets2panda/ir/ets/etsModule.cpp index 3fea029e815..529043167c4 100644 --- a/ets2panda/ir/ets/etsModule.cpp +++ b/ets2panda/ir/ets/etsModule.cpp @@ -34,7 +34,7 @@ void ETSModule::Dump(ir::SrcDumper *dumper) const } dumper->Add("namespace "); - ident_->Dump(dumper); + Ident()->Dump(dumper); dumper->Add(" {"); dumper->IncrIndent(); } @@ -56,8 +56,7 @@ void ETSModule::Dump(ir::SrcDumper *dumper) const ETSModule *ETSModule::Construct(ArenaAllocator *allocator) { - ArenaVector statementList(allocator->Adapter()); - return allocator->New(allocator, std::move(statementList), nullptr, ModuleFlag::NONE, nullptr); + return allocator->New(allocator, ArenaVector {allocator->Adapter()}, history_); } void ETSModule::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ets/etsModule.h b/ets2panda/ir/ets/etsModule.h index 0c967d8d245..bd782000b2a 100644 --- a/ets2panda/ir/ets/etsModule.h +++ b/ets2panda/ir/ets/etsModule.h @@ -54,47 +54,62 @@ public: program_(program) { type_ = AstNodeType::ETS_MODULE; + EnableHistory(); + } + + explicit ETSModule(ArenaAllocator *allocator, ArenaVector &&statementList, AstNodeHistory *history) + : JsDocAllowed>(allocator, std::move(statementList)), + ident_(nullptr), + flag_(ModuleFlag::NONE), + program_(nullptr) + { + type_ = AstNodeType::ETS_MODULE; + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } ir::Identifier *Ident() { - return ident_; + return HISTORY_GET(ident_); } const ir::Identifier *Ident() const { - return ident_; + return HISTORY_GET(ident_); } parser::Program *Program() { - return program_; + return HISTORY_GET(program_); } [[nodiscard]] bool IsETSScript() const noexcept { - return (flag_ & ModuleFlag::ETSSCRIPT) != 0; + return (ModuleFlags() & ModuleFlag::ETSSCRIPT) != 0; } [[nodiscard]] bool IsNamespace() const noexcept { - return (flag_ & ModuleFlag::NAMESPACE) != 0; + return (ModuleFlags() & ModuleFlag::NAMESPACE) != 0; } [[nodiscard]] bool IsNamespaceChainLastNode() const noexcept { - return (flag_ & ModuleFlag::NAMESPACE_CHAIN_LAST_NODE) != 0; + return (ModuleFlags() & ModuleFlag::NAMESPACE_CHAIN_LAST_NODE) != 0; } void SetNamespaceChainLastNode() noexcept { ES2PANDA_ASSERT(IsNamespace()); - flag_ |= ModuleFlag::NAMESPACE_CHAIN_LAST_NODE; + AddModuleFlag(ModuleFlag::NAMESPACE_CHAIN_LAST_NODE); } const parser::Program *Program() const { - return program_; + return HISTORY_GET(program_); } void Dump(ir::SrcDumper *dumper) const override; void Accept(ASTVisitorT *v) override @@ -107,6 +122,25 @@ public: private: friend class SizeOfNodeTest; + ModuleFlag ModuleFlags() const + { + return HISTORY_GET(flag_); + } + + void AddModuleFlag(ModuleFlag flag) noexcept + { + if (!All(ModuleFlags(), flag)) { + HISTORY_GET_OR_CREATE(flag_) |= flag; + } + } + + void ClearModuleFlag(ModuleFlag flag) noexcept + { + if (Any(ModuleFlags(), flag)) { + HISTORY_GET_OR_CREATE(flag_) &= ~flag; + } + } + Identifier *ident_; ModuleFlag flag_; parser::Program *program_; diff --git a/ets2panda/ir/ets/etsNeverType.cpp b/ets2panda/ir/ets/etsNeverType.cpp index 79284dd1f72..3f40e347507 100644 --- a/ets2panda/ir/ets/etsNeverType.cpp +++ b/ets2panda/ir/ets/etsNeverType.cpp @@ -21,12 +21,7 @@ namespace ark::es2panda::ir { void ETSNeverType::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void ETSNeverType::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ets/etsNullishTypes.cpp b/ets2panda/ir/ets/etsNullishTypes.cpp index e3e9e798367..0957d162a44 100644 --- a/ets2panda/ir/ets/etsNullishTypes.cpp +++ b/ets2panda/ir/ets/etsNullishTypes.cpp @@ -21,12 +21,7 @@ namespace ark::es2panda::ir { void ETSUndefinedType::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void ETSUndefinedType::Iterate([[maybe_unused]] const NodeTraverser &cb) const @@ -92,12 +87,7 @@ ETSUndefinedType *ETSUndefinedType::Clone(ArenaAllocator *allocator, AstNode *pa void ETSNullType::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void ETSNullType::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ets/etsParameterExpression.cpp b/ets2panda/ir/ets/etsParameterExpression.cpp index 382a8a6f113..e8ce96cb187 100644 --- a/ets2panda/ir/ets/etsParameterExpression.cpp +++ b/ets2panda/ir/ets/etsParameterExpression.cpp @@ -24,6 +24,12 @@ namespace ark::es2panda::ir { ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identOrSpread, bool isOptional, ArenaAllocator *const allocator) + : ETSParameterExpression(identOrSpread, isOptional, allocator, nullptr) +{ +} + +ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identOrSpread, bool isOptional, + ArenaAllocator *const allocator, AstNodeHistory *history) : AnnotationAllowed(AstNodeType::ETS_PARAMETER_EXPRESSION, allocator) { SetOptional(isOptional); @@ -43,125 +49,139 @@ ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identO } else { ES2PANDA_UNREACHABLE(); } + + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identOrSpread, ir::Expression *initializer, ArenaAllocator *const allocator) + : ETSParameterExpression(identOrSpread, initializer, allocator, nullptr) +{ +} + +ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identOrSpread, ir::Expression *initializer, + ArenaAllocator *const allocator, AstNodeHistory *history) : ETSParameterExpression(identOrSpread, true, allocator) { SetInitializer(initializer); + + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } const util::StringView &ETSParameterExpression::Name() const noexcept { - return ident_->Name(); + return Ident()->Name(); } const Identifier *ETSParameterExpression::Ident() const noexcept { - return ident_; + return HISTORY_GET(ident_); } Identifier *ETSParameterExpression::Ident() noexcept { - return ident_; + return HISTORY_GET(ident_); } const SpreadElement *ETSParameterExpression::RestParameter() const noexcept { - return spread_; + return HISTORY_GET(spread_); } SpreadElement *ETSParameterExpression::RestParameter() noexcept { - return spread_; + return HISTORY_GET(spread_); } const Expression *ETSParameterExpression::Initializer() const noexcept { - return initializer_; + return HISTORY_GET(initializer_); } Expression *ETSParameterExpression::Initializer() noexcept { - return initializer_; + return HISTORY_GET(initializer_); } varbinder::Variable *ETSParameterExpression::Variable() const noexcept { - return ident_->Variable(); + return Ident()->Variable(); } TypeNode const *ETSParameterExpression::TypeAnnotation() const noexcept { - return !IsRestParameter() ? ident_->TypeAnnotation() : spread_->TypeAnnotation(); + return !IsRestParameter() ? Ident()->TypeAnnotation() : Spread()->TypeAnnotation(); } TypeNode *ETSParameterExpression::TypeAnnotation() noexcept { - return !IsRestParameter() ? ident_->TypeAnnotation() : spread_->TypeAnnotation(); + return !IsRestParameter() ? Ident()->TypeAnnotation() : Spread()->TypeAnnotation(); } void ETSParameterExpression::SetTypeAnnotation(TypeNode *typeNode) noexcept { - !IsRestParameter() ? ident_->SetTsTypeAnnotation(typeNode) : spread_->SetTsTypeAnnotation(typeNode); + !IsRestParameter() ? Ident()->SetTsTypeAnnotation(typeNode) : Spread()->SetTsTypeAnnotation(typeNode); } void ETSParameterExpression::SetVariable(varbinder::Variable *const variable) noexcept { - ident_->SetVariable(variable); -} - -void ETSParameterExpression::SetLexerSaved(util::StringView s) noexcept -{ - savedLexer_ = s; + Ident()->SetVariable(variable); } util::StringView ETSParameterExpression::LexerSaved() const noexcept { - return savedLexer_; + return HISTORY_GET(savedLexer_); } void ETSParameterExpression::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { if (IsRestParameter()) { - if (auto *transformedNode = cb(spread_); spread_ != transformedNode) { - spread_->SetTransformedNode(transformationName, transformedNode); - spread_ = transformedNode->AsRestElement(); + auto spread = Spread(); + if (auto *transformedNode = cb(spread); spread != transformedNode) { + spread->SetTransformedNode(transformationName, transformedNode); + SetSpread(transformedNode->AsRestElement()); } - ident_ = spread_->Argument()->AsIdentifier(); + HISTORY_GET_OR_CREATE(ident_) = Spread()->Argument()->AsIdentifier(); } else { - if (auto *transformedNode = cb(ident_); ident_ != transformedNode) { - ident_->SetTransformedNode(transformationName, transformedNode); - ident_ = transformedNode->AsIdentifier(); + auto ident = Ident(); + if (auto *transformedNode = cb(ident); ident != transformedNode) { + ident->SetTransformedNode(transformationName, transformedNode); + SetIdent(transformedNode->AsIdentifier()); } } - if (initializer_ != nullptr) { - if (auto *transformedNode = cb(initializer_); initializer_ != transformedNode) { - initializer_->SetTransformedNode(transformationName, transformedNode); - initializer_ = transformedNode->AsExpression(); + auto initializer = Initializer(); + if (initializer != nullptr) { + if (auto *transformedNode = cb(initializer); initializer != transformedNode) { + initializer->SetTransformedNode(transformationName, transformedNode); + SetInitializer(transformedNode->AsExpression()); } } - for (auto *&it : Annotations()) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void ETSParameterExpression::Iterate(const NodeTraverser &cb) const { if (IsRestParameter()) { - cb(spread_); + auto spread = HISTORY_GET(spread_); + cb(spread); } else { - cb(ident_); + auto ident = HISTORY_GET(ident_); + cb(ident); } - if (initializer_ != nullptr) { - cb(initializer_); + auto initializer = HISTORY_GET(initializer_); + if (initializer != nullptr) { + cb(initializer); } for (auto *it : Annotations()) { @@ -173,12 +193,12 @@ void ETSParameterExpression::Dump(ir::AstDumper *const dumper) const { if (!IsRestParameter()) { dumper->Add({{"type", "ETSParameterExpression"}, - {"name", ident_}, - {"initializer", AstDumper::Optional(initializer_)}, + {"name", Ident()}, + {"initializer", AstDumper::Optional(Initializer())}, {"annotations", AstDumper::Optional(Annotations())}}); } else { dumper->Add({{"type", "ETSParameterExpression"}, - {"rest parameter", spread_}, + {"rest parameter", Spread()}, {"annotations", AstDumper::Optional(Annotations())}}); } } @@ -190,23 +210,25 @@ void ETSParameterExpression::Dump(ir::SrcDumper *const dumper) const } if (IsRestParameter()) { - spread_->Dump(dumper); + Spread()->Dump(dumper); } else { - if (ident_ != nullptr) { - ES2PANDA_ASSERT(ident_->IsAnnotatedExpression()); - ident_->Dump(dumper); - if (isOptional_ && initializer_ == nullptr) { + auto ident = Ident(); + auto initializer = Initializer(); + if (ident != nullptr) { + ES2PANDA_ASSERT(ident->IsAnnotatedExpression()); + ident->Dump(dumper); + if (IsOptional() && initializer == nullptr) { dumper->Add("?"); } - auto typeAnnotation = ident_->AsAnnotatedExpression()->TypeAnnotation(); + auto typeAnnotation = ident->AsAnnotatedExpression()->TypeAnnotation(); if (typeAnnotation != nullptr) { dumper->Add(": "); typeAnnotation->Dump(dumper); } } - if (initializer_ != nullptr) { + if (initializer != nullptr) { dumper->Add(" = "); - initializer_->Dump(dumper); + initializer->Dump(dumper); } } } @@ -233,12 +255,12 @@ checker::VerifiedType ETSParameterExpression::Check(checker::ETSChecker *const c ETSParameterExpression *ETSParameterExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const identOrSpread = spread_ != nullptr ? spread_->Clone(allocator, nullptr)->AsAnnotatedExpression() - : ident_->Clone(allocator, nullptr)->AsAnnotatedExpression(); + auto *const identOrSpread = Spread() != nullptr ? Spread()->Clone(allocator, nullptr)->AsAnnotatedExpression() + : Ident()->Clone(allocator, nullptr)->AsAnnotatedExpression(); auto *const initializer = - initializer_ != nullptr ? initializer_->Clone(allocator, nullptr)->AsExpression() : nullptr; + Initializer() != nullptr ? Initializer()->Clone(allocator, nullptr)->AsExpression() : nullptr; - auto *const clone = initializer_ != nullptr + auto *const clone = Initializer() != nullptr ? allocator->New(identOrSpread, initializer, allocator) : allocator->New(identOrSpread, isOptional_, allocator); identOrSpread->SetParent(clone); @@ -251,7 +273,7 @@ ETSParameterExpression *ETSParameterExpression::Clone(ArenaAllocator *const allo clone->SetParent(parent); } - clone->SetRequiredParams(extraValue_); + clone->SetRequiredParams(GetRequiredParams()); if (!Annotations().empty()) { ArenaVector annotationUsages {allocator->Adapter()}; @@ -266,7 +288,7 @@ ETSParameterExpression *ETSParameterExpression::Clone(ArenaAllocator *const allo ETSParameterExpression *ETSParameterExpression::Construct(ArenaAllocator *allocator) { - return allocator->New(nullptr, false, allocator); + return allocator->New(nullptr, false, allocator, history_); } void ETSParameterExpression::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ets/etsParameterExpression.h b/ets2panda/ir/ets/etsParameterExpression.h index a38f760c793..503b8c7e494 100644 --- a/ets2panda/ir/ets/etsParameterExpression.h +++ b/ets2panda/ir/ets/etsParameterExpression.h @@ -38,9 +38,15 @@ public: explicit ETSParameterExpression(AnnotatedExpression *identOrSpread, bool isOptional, ArenaAllocator *const allocator); + explicit ETSParameterExpression(AnnotatedExpression *identOrSpread, bool isOptional, + ArenaAllocator *const allocator, AstNodeHistory *history); + explicit ETSParameterExpression(AnnotatedExpression *identOrSpread, ir::Expression *initializer, ArenaAllocator *const allocator); + explicit ETSParameterExpression(AnnotatedExpression *identOrSpread, ir::Expression *initializer, + ArenaAllocator *const allocator, AstNodeHistory *history); + [[nodiscard]] const util::StringView &Name() const noexcept; [[nodiscard]] const Identifier *Ident() const noexcept; @@ -48,8 +54,8 @@ public: void SetIdent(Identifier *ident) noexcept { - ident_ = ident; - ident_->SetParent(this); + HISTORY_SET(ident_, ident); + ident->SetParent(this); } [[nodiscard]] const SpreadElement *RestParameter() const noexcept; @@ -58,7 +64,11 @@ public: [[nodiscard]] const Expression *Initializer() const noexcept; [[nodiscard]] Expression *Initializer() noexcept; - void SetLexerSaved(util::StringView s) noexcept; + void SetLexerSaved(util::StringView s) noexcept + { + HISTORY_SET(savedLexer_, s); + } + [[nodiscard]] util::StringView LexerSaved() const noexcept; [[nodiscard]] varbinder::Variable *Variable() const noexcept; @@ -71,34 +81,34 @@ public: [[nodiscard]] bool IsOptional() const noexcept { - return isOptional_; + return HISTORY_GET(isOptional_); } void SetOptional(bool value) noexcept { - isOptional_ = value; - ES2PANDA_ASSERT(isOptional_ || initializer_ == nullptr); + HISTORY_SET(isOptional_, value); + ES2PANDA_ASSERT(IsOptional() || Initializer() == nullptr); } void SetInitializer(Expression *initExpr) noexcept { - initializer_ = initExpr; - ES2PANDA_ASSERT(isOptional_ || initializer_ == nullptr); + HISTORY_SET(initializer_, initExpr); + ES2PANDA_ASSERT(IsOptional() || Initializer() == nullptr); } [[nodiscard]] bool IsRestParameter() const noexcept { - return spread_ != nullptr; + return Spread() != nullptr; } [[nodiscard]] std::size_t GetRequiredParams() const noexcept { - return extraValue_; + return HISTORY_GET(extraValue_); } void SetRequiredParams(std::size_t const value) noexcept { - extraValue_ = value; + HISTORY_SET(extraValue_, value); } [[nodiscard]] ETSParameterExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; @@ -122,6 +132,21 @@ public: private: friend class SizeOfNodeTest; + SpreadElement *Spread() noexcept + { + return HISTORY_GET(spread_); + } + + const SpreadElement *Spread() const noexcept + { + return HISTORY_GET(spread_); + } + + void SetSpread(SpreadElement *spread) + { + HISTORY_SET(spread_, spread); + } + Identifier *ident_; Expression *initializer_ = nullptr; SpreadElement *spread_ = nullptr; diff --git a/ets2panda/ir/ets/etsPrimitiveType.cpp b/ets2panda/ir/ets/etsPrimitiveType.cpp index c18f7435026..20708e3048d 100644 --- a/ets2panda/ir/ets/etsPrimitiveType.cpp +++ b/ets2panda/ir/ets/etsPrimitiveType.cpp @@ -24,12 +24,7 @@ namespace ark::es2panda::ir { void ETSPrimitiveType::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void ETSPrimitiveType::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ets/etsReExportDeclaration.cpp b/ets2panda/ir/ets/etsReExportDeclaration.cpp index c5df1d644b1..5afd958c222 100644 --- a/ets2panda/ir/ets/etsReExportDeclaration.cpp +++ b/ets2panda/ir/ets/etsReExportDeclaration.cpp @@ -32,24 +32,44 @@ ETSReExportDeclaration::ETSReExportDeclaration(ETSImportDeclaration *etsImportDe } } +ETSReExportDeclaration::ETSReExportDeclaration(ETSImportDeclaration *etsImportDeclarations, + const std::vector &userPaths, util::StringView programPath, + ArenaAllocator *allocator, AstNodeHistory *history) + : Statement(AstNodeType::REEXPORT_STATEMENT), + etsImportDeclarations_(etsImportDeclarations), + userPaths_(allocator->Adapter()), + programPath_(programPath) +{ + for (const auto &path : userPaths) { + userPaths_.emplace_back(util::UString(path, allocator).View()); + } + + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } +} + void ETSReExportDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { - if (etsImportDeclarations_ != nullptr) { - if (auto *transformedNode = cb(etsImportDeclarations_); etsImportDeclarations_ != transformedNode) { - etsImportDeclarations_->SetTransformedNode(transformationName, transformedNode); - etsImportDeclarations_ = transformedNode->AsETSImportDeclaration(); + auto etsImportDeclarations = GetETSImportDeclarations(); + if (etsImportDeclarations != nullptr) { + if (auto *transformedNode = cb(etsImportDeclarations); etsImportDeclarations != transformedNode) { + etsImportDeclarations->SetTransformedNode(transformationName, transformedNode); + SetETSImportDeclarations(transformedNode->AsETSImportDeclaration()); } } } void ETSReExportDeclaration::Iterate(const NodeTraverser &cb) const { - etsImportDeclarations_->Iterate(cb); + GetETSImportDeclarations()->Iterate(cb); } void ETSReExportDeclaration::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", "ETSReExportDeclaration"}, {"ets_import_declarations", etsImportDeclarations_}}); + dumper->Add({{"type", "ETSReExportDeclaration"}, {"ets_import_declarations", GetETSImportDeclarations()}}); } void ETSReExportDeclaration::Dump([[maybe_unused]] ir::SrcDumper *dumper) const @@ -84,7 +104,8 @@ checker::VerifiedType ETSReExportDeclaration::Check(checker::ETSChecker * /*chec AstNode *ETSReExportDeclaration::Construct(ArenaAllocator *allocator) { - return allocator->New(nullptr, std::vector {}, util::StringView {}, allocator); + return allocator->New(nullptr, std::vector {}, util::StringView {}, allocator, + history_); } void ETSReExportDeclaration::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ets/etsReExportDeclaration.h b/ets2panda/ir/ets/etsReExportDeclaration.h index 48d7e654595..38079d9cca7 100644 --- a/ets2panda/ir/ets/etsReExportDeclaration.h +++ b/ets2panda/ir/ets/etsReExportDeclaration.h @@ -29,24 +29,28 @@ public: const std::vector &userPaths, util::StringView programPath, ArenaAllocator *allocator); + explicit ETSReExportDeclaration(ETSImportDeclaration *etsImportDeclarations, + const std::vector &userPaths, util::StringView programPath, + ArenaAllocator *allocator, AstNodeHistory *history); + ETSImportDeclaration *GetETSImportDeclarations() const { - return etsImportDeclarations_; + return HISTORY_GET(etsImportDeclarations_); } ETSImportDeclaration *GetETSImportDeclarations() { - return etsImportDeclarations_; + return HISTORY_GET(etsImportDeclarations_); } const ArenaVector &GetUserPaths() const { - return userPaths_; + return HISTORY_GET(userPaths_); } util::StringView const &GetProgramPath() const { - return programPath_; + return HISTORY_GET(programPath_); } void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; @@ -78,6 +82,11 @@ protected: private: friend class SizeOfNodeTest; + void SetETSImportDeclarations(ETSImportDeclaration *etsImportDeclarations) + { + HISTORY_SET(etsImportDeclarations_, etsImportDeclarations); + } + // NOTE(rsipka): this should use a singular name ETSImportDeclaration *etsImportDeclarations_; ArenaVector userPaths_; diff --git a/ets2panda/ir/ets/etsStringLiteralType.cpp b/ets2panda/ir/ets/etsStringLiteralType.cpp index d6227f2673e..178160de402 100644 --- a/ets2panda/ir/ets/etsStringLiteralType.cpp +++ b/ets2panda/ir/ets/etsStringLiteralType.cpp @@ -21,12 +21,7 @@ namespace ark::es2panda::ir { void ETSStringLiteralType::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void ETSStringLiteralType::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ets/etsStructDeclaration.h b/ets2panda/ir/ets/etsStructDeclaration.h index 538797da5dd..b3c0142539b 100644 --- a/ets2panda/ir/ets/etsStructDeclaration.h +++ b/ets2panda/ir/ets/etsStructDeclaration.h @@ -30,6 +30,17 @@ public: explicit ETSStructDeclaration(ClassDefinition *const def, ArenaAllocator *const allocator) : ClassDeclaration(AstNodeType::STRUCT_DECLARATION, def, allocator) { + EnableHistory(); + } + + explicit ETSStructDeclaration(ClassDefinition *const def, ArenaAllocator *const allocator, AstNodeHistory *history) + : ClassDeclaration(AstNodeType::STRUCT_DECLARATION, def, allocator) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } void Dump(ir::AstDumper *dumper) const override; @@ -42,6 +53,16 @@ public: { v->Accept(this); } + + ETSStructDeclaration *Construct(ArenaAllocator *allocator) override + { + return allocator->New(nullptr, allocator, history_); + } + + void CopyTo(AstNode *other) const override + { + ClassDeclaration::CopyTo(other); + }; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/ets/etsTuple.cpp b/ets2panda/ir/ets/etsTuple.cpp index b79654c62e2..79b9e906fb6 100644 --- a/ets2panda/ir/ets/etsTuple.cpp +++ b/ets2panda/ir/ets/etsTuple.cpp @@ -29,12 +29,7 @@ void ETSTuple::TransformChildren(const NodeTransformer &cb, std::string_view con } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void ETSTuple::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ets/etsTypeReference.cpp b/ets2panda/ir/ets/etsTypeReference.cpp index 21db7e18148..b50b2c91d9b 100644 --- a/ets2panda/ir/ets/etsTypeReference.cpp +++ b/ets2panda/ir/ets/etsTypeReference.cpp @@ -23,21 +23,19 @@ namespace ark::es2panda::ir { void ETSTypeReference::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { - if (auto *transformedNode = cb(part_); part_ != transformedNode) { - part_->SetTransformedNode(transformationName, transformedNode); - part_ = transformedNode->AsETSTypeReferencePart(); - } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } + auto part = Part(); + if (auto *transformedNode = cb(part); part != transformedNode) { + part->SetTransformedNode(transformationName, transformedNode); + SetPart(transformedNode->AsETSTypeReferencePart()); } + + TransformAnnotations(cb, transformationName); } void ETSTypeReference::Iterate(const NodeTraverser &cb) const { - cb(part_); + auto part = Part(); + cb(part); for (auto *it : VectorIterationGuard(Annotations())) { cb(it); } @@ -45,7 +43,7 @@ void ETSTypeReference::Iterate(const NodeTraverser &cb) const ir::Identifier *ETSTypeReference::BaseName() const { - ir::ETSTypeReferencePart *partIter = part_; + ir::ETSTypeReferencePart *partIter = Part(); while (partIter->Previous() != nullptr) { partIter = partIter->Previous(); @@ -68,7 +66,7 @@ ir::Identifier *ETSTypeReference::BaseName() const void ETSTypeReference::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", "ETSTypeReference"}, {"part", part_}, {"annotations", AstDumper::Optional(Annotations())}}); + dumper->Add({{"type", "ETSTypeReference"}, {"part", Part()}, {"annotations", AstDumper::Optional(Annotations())}}); } void ETSTypeReference::Dump(ir::SrcDumper *dumper) const @@ -76,8 +74,8 @@ void ETSTypeReference::Dump(ir::SrcDumper *dumper) const for (auto *anno : Annotations()) { anno->Dump(dumper); } - ES2PANDA_ASSERT(part_ != nullptr); - part_->Dump(dumper); + ES2PANDA_ASSERT(Part() != nullptr); + Part()->Dump(dumper); } void ETSTypeReference::Compile(compiler::PandaGen *pg) const @@ -103,7 +101,7 @@ checker::Type *ETSTypeReference::GetType(checker::ETSChecker *checker) if (TsType() != nullptr) { return TsType(); } - auto *type = part_->GetType(checker); + auto *type = Part()->GetType(checker); if (IsReadonlyType()) { type = checker->GetReadonlyType(type); } @@ -112,14 +110,14 @@ checker::Type *ETSTypeReference::GetType(checker::ETSChecker *checker) ETSTypeReference *ETSTypeReference::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const partClone = part_ != nullptr ? part_->Clone(allocator, nullptr)->AsETSTypeReferencePart() : nullptr; + auto *const partClone = Part() != nullptr ? Part()->Clone(allocator, nullptr)->AsETSTypeReferencePart() : nullptr; auto *const clone = allocator->New(partClone, allocator); if (partClone != nullptr) { partClone->SetParent(clone); } - clone->flags_ = flags_; + clone->SetModifiers(Modifiers()); if (parent != nullptr) { clone->SetParent(parent); @@ -139,7 +137,7 @@ ETSTypeReference *ETSTypeReference::Clone(ArenaAllocator *const allocator, AstNo ETSTypeReference *ETSTypeReference::Construct(ArenaAllocator *allocator) { - return allocator->New(nullptr, allocator); + return allocator->New(nullptr, allocator, history_); } void ETSTypeReference::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ets/etsTypeReference.h b/ets2panda/ir/ets/etsTypeReference.h index f100af2e565..bc8f36637df 100644 --- a/ets2panda/ir/ets/etsTypeReference.h +++ b/ets2panda/ir/ets/etsTypeReference.h @@ -25,16 +25,27 @@ public: explicit ETSTypeReference(ir::ETSTypeReferencePart *part, ArenaAllocator *const allocator) : TypeNode(AstNodeType::ETS_TYPE_REFERENCE, allocator), part_(part) { + EnableHistory(); + } + + explicit ETSTypeReference(ir::ETSTypeReferencePart *part, ArenaAllocator *const allocator, AstNodeHistory *history) + : TypeNode(AstNodeType::ETS_TYPE_REFERENCE, allocator), part_(part) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } ir::ETSTypeReferencePart *Part() { - return part_; + return HISTORY_GET(part_); } ir::ETSTypeReferencePart *Part() const { - return part_; + return HISTORY_GET(part_); } ir::Identifier *BaseName() const; @@ -61,6 +72,11 @@ public: private: friend class SizeOfNodeTest; + void SetPart(ETSTypeReferencePart *part) + { + HISTORY_SET(part_, part); + } + ir::ETSTypeReferencePart *part_; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/ets/etsTypeReferencePart.cpp b/ets2panda/ir/ets/etsTypeReferencePart.cpp index e0686ef0761..a5c2df38737 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.cpp +++ b/ets2panda/ir/ets/etsTypeReferencePart.cpp @@ -22,55 +22,64 @@ #include "compiler/core/pandagen.h" namespace ark::es2panda::ir { + void ETSTypeReferencePart::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { - if (auto *transformedNode = cb(name_); name_ != transformedNode) { - name_->SetTransformedNode(transformationName, transformedNode); - name_ = transformedNode->AsExpression(); + auto name = Name(); + if (name != nullptr) { + if (auto *transformedNode = cb(name); name != transformedNode) { + name->SetTransformedNode(transformationName, transformedNode); + SetName(transformedNode->AsExpression()); + } } - if (typeParams_ != nullptr) { - if (auto *transformedNode = cb(typeParams_); typeParams_ != transformedNode) { - typeParams_->SetTransformedNode(transformationName, transformedNode); - typeParams_ = transformedNode->AsTSTypeParameterInstantiation(); + auto typeParams = TypeParams(); + if (typeParams != nullptr) { + if (auto *transformedNode = cb(typeParams); typeParams != transformedNode) { + typeParams->SetTransformedNode(transformationName, transformedNode); + SetTypeParams(transformedNode->AsTSTypeParameterInstantiation()); } } - if (prev_ != nullptr) { - if (auto *transformedNode = cb(prev_); prev_ != transformedNode) { - prev_->SetTransformedNode(transformationName, transformedNode); - prev_ = transformedNode->AsETSTypeReferencePart(); + auto prev = Previous(); + if (prev != nullptr) { + if (auto *transformedNode = cb(prev); prev != transformedNode) { + prev->SetTransformedNode(transformationName, transformedNode); + SetPrevious(transformedNode->AsETSTypeReferencePart()); } } } void ETSTypeReferencePart::Iterate(const NodeTraverser &cb) const { - cb(name_); + auto name = HISTORY_GET(name_); + cb(name); - if (typeParams_ != nullptr) { - cb(typeParams_); + auto typeParams = HISTORY_GET(typeParams_); + if (typeParams != nullptr) { + cb(typeParams); } - if (prev_ != nullptr) { - cb(prev_); + auto prev = HISTORY_GET(prev_); + if (prev != nullptr) { + cb(prev); } } void ETSTypeReferencePart::Dump(ir::AstDumper *dumper) const { dumper->Add({{"type", "ETSTypeReferencePart"}, - {"name", name_}, - {"typeParams", AstDumper::Optional(typeParams_)}, - {"previous", AstDumper::Optional(prev_)}}); + {"name", Name()}, + {"typeParams", AstDumper::Optional(TypeParams())}, + {"previous", AstDumper::Optional(Previous())}}); } void ETSTypeReferencePart::Dump(ir::SrcDumper *dumper) const { - ES2PANDA_ASSERT(name_ != nullptr); - name_->Dump(dumper); - if (typeParams_ != nullptr) { - typeParams_->Dump(dumper); + ES2PANDA_ASSERT(Name() != nullptr); + Name()->Dump(dumper); + if (TypeParams() != nullptr) { + TypeParams()->Dump(dumper); } } @@ -95,24 +104,25 @@ checker::VerifiedType ETSTypeReferencePart::Check(checker::ETSChecker *checker) checker::Type *ETSTypeReferencePart::HandleInternalTypes(checker::ETSChecker *const checker) { - ES2PANDA_ASSERT(name_->IsIdentifier() || name_->IsTSQualifiedName()); + auto const name = Name(); + ES2PANDA_ASSERT(name->IsIdentifier() || name->IsTSQualifiedName()); Identifier *ident = GetIdent(); varbinder::Variable *variable = nullptr; - if (name_->IsIdentifier()) { + if (name->IsIdentifier()) { variable = ident->Variable(); } else { - if (name_->AsTSQualifiedName()->Left()->Variable() != nullptr && - name_->AsTSQualifiedName()->Left()->Variable()->TsType() != nullptr && - name_->AsTSQualifiedName()->Left()->Variable()->TsType()->IsETSObjectType()) { - variable = name_->AsTSQualifiedName()->Left()->Variable()->TsType()->AsETSObjectType()->GetProperty( + if (name->AsTSQualifiedName()->Left()->Variable() != nullptr && + name->AsTSQualifiedName()->Left()->Variable()->TsType() != nullptr && + name->AsTSQualifiedName()->Left()->Variable()->TsType()->IsETSObjectType()) { + variable = name->AsTSQualifiedName()->Left()->Variable()->TsType()->AsETSObjectType()->GetProperty( ident->Name(), checker::PropertySearchFlags::SEARCH_DECL); } } if (variable != nullptr && variable->Declaration()->IsTypeAliasDecl()) { - return checker->HandleTypeAlias(name_, typeParams_, + return checker->HandleTypeAlias(name, TypeParams(), variable->Declaration()->AsTypeAliasDecl()->Node()->AsTSTypeAliasDeclaration()); } @@ -130,7 +140,7 @@ checker::Type *ETSTypeReferencePart::HandleInternalTypes(checker::ETSChecker *co if (ident->Name() == compiler::Signatures::READONLY_TYPE_NAME || ident->Name() == compiler::Signatures::REQUIRED_TYPE_NAME) { - return checker->HandleUtilityTypeParameterNode(typeParams_, ident); + return checker->HandleUtilityTypeParameterNode(TypeParams(), ident); } if (ident->Name() == compiler::Signatures::PARTIAL_TYPE_NAME) { @@ -150,11 +160,12 @@ checker::Type *ETSTypeReferencePart::HandleInternalTypes(checker::ETSChecker *co checker::Type *ETSTypeReferencePart::HandleFixedArrayType(checker::ETSChecker *const checker) { - if (typeParams_ == nullptr || typeParams_->Params().size() != 1) { + auto const typeParams = TypeParams(); + if (typeParams == nullptr || typeParams->Params().size() != 1) { checker->LogError(diagnostic::FIXED_ARRAY_PARAM_ERROR, {}, Start()); return checker->GlobalTypeError(); } - checker::Type *type = checker->CreateETSArrayType(typeParams_->Params()[0]->GetType(checker), IsReadonlyType()); + checker::Type *type = checker->CreateETSArrayType(typeParams->Params()[0]->GetType(checker), IsReadonlyType()); SetTsType(type); return type; } @@ -162,14 +173,15 @@ checker::Type *ETSTypeReferencePart::HandleFixedArrayType(checker::ETSChecker *c checker::Type *ETSTypeReferencePart::HandlePartialType(checker::ETSChecker *const checker, const Identifier *const ident) { - auto *baseType = checker->HandleUtilityTypeParameterNode(typeParams_, ident); + auto const typeParams = TypeParams(); + auto *baseType = checker->HandleUtilityTypeParameterNode(typeParams, ident); if (baseType != nullptr && baseType->IsETSObjectType() && !baseType->AsETSObjectType()->TypeArguments().empty()) { // we treat Partial> class as a different copy from A now, // but not a generic type param for Partial<> - if (typeParams_ != nullptr) { - for (auto &typeRef : typeParams_->Params()) { + if (typeParams != nullptr) { + for (auto &typeRef : typeParams->Params()) { checker::InstantiationContext ctx(checker, baseType->AsETSObjectType(), - typeRef->AsETSTypeReference()->Part()->typeParams_, Start()); + typeRef->AsETSTypeReference()->Part()->TypeParams(), Start()); baseType = ctx.Result(); } } @@ -187,35 +199,37 @@ checker::Type *ETSTypeReferencePart::GetType(checker::ETSChecker *checker) } } } - if (prev_ == nullptr) { - if (name_->IsIdentifier() || name_->IsTSQualifiedName()) { + auto const name = Name(); + if (Previous() == nullptr) { + if (name->IsIdentifier() || name->IsTSQualifiedName()) { SetTsType(HandleInternalTypes(checker)); } if (TsType() == nullptr) { - checker::Type *baseType = checker->GetReferencedTypeBase(name_); + checker::Type *baseType = checker->GetReferencedTypeBase(name); ES2PANDA_ASSERT(baseType != nullptr); if (baseType->IsETSObjectType()) { - checker::InstantiationContext ctx(checker, baseType->AsETSObjectType(), typeParams_, Start()); + checker::InstantiationContext ctx(checker, baseType->AsETSObjectType(), TypeParams(), Start()); SetTsType(ctx.Result()); } else { SetTsType(baseType); } } } else { - checker::Type *baseType = prev_->GetType(checker); - SetTsType(checker->GetReferencedTypeFromBase(baseType, name_)); + checker::Type *baseType = Previous()->GetType(checker); + SetTsType(checker->GetReferencedTypeFromBase(baseType, name)); } return TsType(); } ETSTypeReferencePart *ETSTypeReferencePart::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const nameClone = name_ != nullptr ? name_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const nameClone = Name() != nullptr ? Name()->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const typeParamsClone = - typeParams_ != nullptr ? typeParams_->Clone(allocator, nullptr)->AsTSTypeParameterInstantiation() : nullptr; - auto *const prevClone = prev_ != nullptr ? prev_->Clone(allocator, nullptr)->AsETSTypeReferencePart() : nullptr; + TypeParams() != nullptr ? TypeParams()->Clone(allocator, nullptr)->AsTSTypeParameterInstantiation() : nullptr; + auto *const prevClone = + Previous() != nullptr ? Previous()->Clone(allocator, nullptr)->AsETSTypeReferencePart() : nullptr; auto *const clone = allocator->New(nameClone, typeParamsClone, prevClone, allocator); if (nameClone != nullptr) { @@ -240,12 +254,13 @@ ETSTypeReferencePart *ETSTypeReferencePart::Clone(ArenaAllocator *const allocato ir::Identifier *ETSTypeReferencePart::GetIdent() { - if (name_->IsTSQualifiedName()) { - auto ident = name_->AsTSQualifiedName()->Right(); + auto const name = Name(); + if (name->IsTSQualifiedName()) { + auto ident = name->AsTSQualifiedName()->Right(); ES2PANDA_ASSERT(ident->IsIdentifier()); return ident->AsIdentifier(); } - return name_->AsIdentifier(); + return name->AsIdentifier(); } ETSTypeReferencePart *ETSTypeReferencePart::Construct(ArenaAllocator *allocator) diff --git a/ets2panda/ir/ets/etsTypeReferencePart.h b/ets2panda/ir/ets/etsTypeReferencePart.h index 4b1e6aba373..d3f4db6da0c 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.h +++ b/ets2panda/ir/ets/etsTypeReferencePart.h @@ -26,36 +26,65 @@ public: ir::ETSTypeReferencePart *prev, ArenaAllocator *const allocator) : TypeNode(AstNodeType::ETS_TYPE_REFERENCE_PART, allocator), name_(name), typeParams_(typeParams), prev_(prev) { + EnableHistory(); } explicit ETSTypeReferencePart(ir::Expression *name, ArenaAllocator *const allocator) : TypeNode(AstNodeType::ETS_TYPE_REFERENCE_PART, allocator), name_(name) { + EnableHistory(); + } + + explicit ETSTypeReferencePart(ir::Expression *name, ArenaAllocator *const allocator, AstNodeHistory *history) + : TypeNode(AstNodeType::ETS_TYPE_REFERENCE_PART, allocator), name_(name) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } + } + + explicit ETSTypeReferencePart(ir::Expression *name, ir::TSTypeParameterInstantiation *typeParams, + ir::ETSTypeReferencePart *prev, ArenaAllocator *const allocator, + AstNodeHistory *history) + : TypeNode(AstNodeType::ETS_TYPE_REFERENCE_PART, allocator), name_(name), typeParams_(typeParams), prev_(prev) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } ir::ETSTypeReferencePart *Previous() { - return prev_; + return HISTORY_GET(prev_); } const ir::ETSTypeReferencePart *Previous() const { - return prev_; + return HISTORY_GET(prev_); } ir::Expression *Name() { - return name_; + return HISTORY_GET(name_); } ir::TSTypeParameterInstantiation *TypeParams() { - return typeParams_; + return HISTORY_GET(typeParams_); + } + + const ir::TSTypeParameterInstantiation *TypeParams() const + { + return HISTORY_GET(typeParams_); } const ir::Expression *Name() const { - return name_; + return HISTORY_GET(name_); } void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; @@ -85,6 +114,21 @@ private: checker::Type *HandleFixedArrayType(checker::ETSChecker *const checker); friend class SizeOfNodeTest; + void SetName(ir::Expression *name) + { + HISTORY_SET(name_, name); + } + + void SetTypeParams(ir::TSTypeParameterInstantiation *typeParams) + { + HISTORY_SET(typeParams_, typeParams); + } + + void SetPrevious(ir::ETSTypeReferencePart *prev) + { + HISTORY_SET(prev_, prev); + } + ir::Expression *name_; ir::TSTypeParameterInstantiation *typeParams_ {}; ir::ETSTypeReferencePart *prev_ {}; diff --git a/ets2panda/ir/ets/etsUnionType.cpp b/ets2panda/ir/ets/etsUnionType.cpp index 39860832e49..a64059e95a8 100644 --- a/ets2panda/ir/ets/etsUnionType.cpp +++ b/ets2panda/ir/ets/etsUnionType.cpp @@ -26,12 +26,8 @@ void ETSUnionType::TransformChildren(const NodeTransformer &cb, std::string_view it = static_cast(transformedNode); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void ETSUnionType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ets/etsWildcardType.cpp b/ets2panda/ir/ets/etsWildcardType.cpp index 24000a8aa5c..ab5ffc9e50f 100644 --- a/ets2panda/ir/ets/etsWildcardType.cpp +++ b/ets2panda/ir/ets/etsWildcardType.cpp @@ -32,12 +32,8 @@ void ETSWildcardType::TransformChildren(const NodeTransformer &cb, std::string_v typeReference_ = transformedNode->AsETSTypeReference(); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void ETSWildcardType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/expression.h b/ets2panda/ir/expression.h index 52b74a8329b..cf38baa92cc 100644 --- a/ets2panda/ir/expression.h +++ b/ets2panda/ir/expression.h @@ -33,12 +33,12 @@ public: [[nodiscard]] bool IsGrouped() const noexcept { - return grouped_; + return HISTORY_GET(grouped_); } void SetGrouped() noexcept { - grouped_ = true; + HISTORY_SET(grouped_, true); } [[nodiscard]] const Literal *AsLiteral() const @@ -109,7 +109,7 @@ protected: Expression(Expression const &other) : TypedAstNode(static_cast(other)) { - grouped_ = other.grouped_; + grouped_ = other.IsGrouped(); } private: diff --git a/ets2panda/ir/expressions/arrowFunctionExpression.cpp b/ets2panda/ir/expressions/arrowFunctionExpression.cpp index c4941954ec3..772cf69fc00 100644 --- a/ets2panda/ir/expressions/arrowFunctionExpression.cpp +++ b/ets2panda/ir/expressions/arrowFunctionExpression.cpp @@ -28,12 +28,7 @@ void ArrowFunctionExpression::TransformChildren(const NodeTransformer &cb, std:: func_ = transformedNode->AsScriptFunction(); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void ArrowFunctionExpression::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/module/importDeclaration.cpp b/ets2panda/ir/module/importDeclaration.cpp index d48246d8877..2950288951e 100644 --- a/ets2panda/ir/module/importDeclaration.cpp +++ b/ets2panda/ir/module/importDeclaration.cpp @@ -26,44 +26,48 @@ namespace ark::es2panda::ir { void ImportDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - if (auto *transformedNode = cb(source_); source_ != transformedNode) { - source_->SetTransformedNode(transformationName, transformedNode); - source_ = transformedNode->AsStringLiteral(); + auto source = Source(); + if (auto *transformedNode = cb(source); source != transformedNode) { + source->SetTransformedNode(transformationName, transformedNode); + SetSource(transformedNode->AsStringLiteral()); } - for (auto *&it : VectorIterationGuard(specifiers_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode; + auto &specifiers = Specifiers(); + for (size_t index = 0; index < specifiers.size(); ++index) { + if (auto *transformedNode = cb(specifiers[index]); specifiers[index] != transformedNode) { + specifiers[index]->SetTransformedNode(transformationName, transformedNode); + SpecifiersMutable()[index] = transformedNode; } } } void ImportDeclaration::Iterate(const NodeTraverser &cb) const { - cb(source_); + auto source = HISTORY_GET(source_); + cb(source); - for (auto *it : VectorIterationGuard(specifiers_)) { + for (auto *it : VectorIterationGuard(Specifiers())) { cb(it); } } void ImportDeclaration::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", "ImportDeclaration"}, {"source", source_}, {"specifiers", specifiers_}}); + dumper->Add({{"type", "ImportDeclaration"}, {"source", Source()}, {"specifiers", Specifiers()}}); } void ImportDeclaration::Dump(ir::SrcDumper *dumper) const { dumper->Add("import "); - if (specifiers_.size() == 1 && - (specifiers_[0]->IsImportNamespaceSpecifier() || specifiers_[0]->IsImportDefaultSpecifier())) { - specifiers_[0]->Dump(dumper); + auto &specifiers = Specifiers(); + if (specifiers.size() == 1 && + (specifiers[0]->IsImportNamespaceSpecifier() || specifiers[0]->IsImportDefaultSpecifier())) { + specifiers[0]->Dump(dumper); } else { dumper->Add("{ "); - for (auto specifier : specifiers_) { + for (auto specifier : specifiers) { specifier->Dump(dumper); - if (specifier != specifiers_.back()) { + if (specifier != specifiers.back()) { dumper->Add(", "); } } @@ -71,7 +75,7 @@ void ImportDeclaration::Dump(ir::SrcDumper *dumper) const } dumper->Add(" from "); - source_->Dump(dumper); + Source()->Dump(dumper); dumper->Add(";"); dumper->Endl(); } @@ -99,12 +103,12 @@ checker::VerifiedType ImportDeclaration::Check(checker::ETSChecker *checker) ImportDeclaration *ImportDeclaration::Construct(ArenaAllocator *allocator) { ArenaVector specifiers(allocator->Adapter()); - return allocator->New(nullptr, std::move(specifiers)); + return allocator->New(nullptr, std::move(specifiers), history_); } void ImportDeclaration::CopyTo(AstNode *other) const { - auto otherImpl = other->AsImportDeclaration(); + auto otherImpl = static_cast(other); otherImpl->source_ = source_; otherImpl->specifiers_ = specifiers_; diff --git a/ets2panda/ir/module/importDeclaration.h b/ets2panda/ir/module/importDeclaration.h index c3f28438e23..3e97113d97b 100644 --- a/ets2panda/ir/module/importDeclaration.h +++ b/ets2panda/ir/module/importDeclaration.h @@ -32,26 +32,40 @@ public: specifiers_(std::move(specifiers)), importKinds_(importKinds) { + EnableHistory(); + } + + explicit ImportDeclaration(StringLiteral *source, ArenaVector &&specifiers, AstNodeHistory *history) + : Statement(AstNodeType::IMPORT_DECLARATION), + source_(source), + specifiers_(std::move(specifiers)), + importKinds_(ImportKinds::ALL) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } const StringLiteral *Source() const { - return source_; + return HISTORY_GET(source_); } StringLiteral *Source() { - return source_; + return HISTORY_GET(source_); } const ArenaVector &Specifiers() const { - return specifiers_; + return HISTORY_GET(specifiers_); } - ArenaVector &Specifiers() + ArenaVector &SpecifiersMutable() { - return specifiers_; + return HISTORY_GET_OR_CREATE(specifiers_); } void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; @@ -70,7 +84,7 @@ public: bool IsTypeKind() const { - return importKinds_ == ImportKinds::TYPES; + return HISTORY_GET(importKinds_) == ImportKinds::TYPES; } ImportDeclaration *Construct(ArenaAllocator *allocator) override; @@ -78,6 +92,11 @@ public: private: friend class SizeOfNodeTest; + void SetSource(StringLiteral *source) + { + HISTORY_SET(source_, source); + } + StringLiteral *source_; ArenaVector specifiers_; ImportKinds importKinds_; diff --git a/ets2panda/ir/opaqueTypeNode.cpp b/ets2panda/ir/opaqueTypeNode.cpp index b76b69d868e..4a74b389756 100644 --- a/ets2panda/ir/opaqueTypeNode.cpp +++ b/ets2panda/ir/opaqueTypeNode.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void OpaqueTypeNode::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void OpaqueTypeNode::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/statements/annotationDeclaration.cpp b/ets2panda/ir/statements/annotationDeclaration.cpp index aab66f2db27..c0f42aacb22 100644 --- a/ets2panda/ir/statements/annotationDeclaration.cpp +++ b/ets2panda/ir/statements/annotationDeclaration.cpp @@ -23,34 +23,33 @@ namespace ark::es2panda::ir { void AnnotationDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(properties_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode; + auto &properties = Properties(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < properties.size(); ix++) { + if (auto *transformedNode = cb(properties[ix]); properties[ix] != transformedNode) { + properties[ix]->SetTransformedNode(transformationName, transformedNode); + PropertiesMutable()[ix] = transformedNode; } } - if (expr_ != nullptr) { - if (auto *transformedNode = cb(expr_); expr_ != transformedNode) { - expr_->SetTransformedNode(transformationName, transformedNode); - expr_ = transformedNode->AsIdentifier(); + auto expr = Expr(); + if (expr != nullptr) { + if (auto *transformedNode = cb(expr); expr != transformedNode) { + expr->SetTransformedNode(transformationName, transformedNode); + SetExpr(transformedNode->AsIdentifier()); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void AnnotationDeclaration::Iterate(const NodeTraverser &cb) const { - if (expr_ != nullptr) { - cb(expr_); + auto expr = HISTORY_GET(expr_); + if (expr != nullptr) { + cb(expr); } - for (auto *it : VectorIterationGuard(properties_)) { + for (auto *it : VectorIterationGuard(Properties())) { cb(it); } @@ -61,24 +60,27 @@ void AnnotationDeclaration::Iterate(const NodeTraverser &cb) const void AnnotationDeclaration::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"Expr", expr_}, {"properties", properties_}, {"annotations", AstDumper::Optional(Annotations())}}); + dumper->Add({{"Expr", Expr()}, {"properties", Properties()}, {"annotations", AstDumper::Optional(Annotations())}}); } + void AnnotationDeclaration::Dump(ir::SrcDumper *dumper) const { // re-understand for (auto *anno : Annotations()) { anno->Dump(dumper); } - ES2PANDA_ASSERT(expr_ != nullptr); + auto expr = Expr(); + ES2PANDA_ASSERT(expr != nullptr); dumper->Add("@interface "); - expr_->Dump(dumper); + expr->Dump(dumper); dumper->Add(" {"); - if (!properties_.empty()) { + auto &properties = Properties(); + if (!properties.empty()) { dumper->IncrIndent(); dumper->Endl(); - for (auto elem : properties_) { + for (auto elem : properties) { elem->Dump(dumper); - if (elem == properties_.back()) { + if (elem == properties.back()) { dumper->DecrIndent(); } } @@ -108,16 +110,17 @@ checker::VerifiedType AnnotationDeclaration::Check(checker::ETSChecker *checker) Identifier *AnnotationDeclaration::GetBaseName() const { - if (expr_->IsIdentifier()) { - return expr_->AsIdentifier(); + auto expr = HISTORY_GET(expr_); + if (expr->IsIdentifier()) { + return expr->AsIdentifier(); } - auto *part = expr_->AsETSTypeReference()->Part(); + auto *part = expr->AsETSTypeReference()->Part(); return part->Name()->AsTSQualifiedName()->Right(); } AstNode *AnnotationDeclaration::Construct(ArenaAllocator *allocator) { - return allocator->New(nullptr, allocator); + return allocator->New(allocator, history_); } void AnnotationDeclaration::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/statements/annotationDeclaration.h b/ets2panda/ir/statements/annotationDeclaration.h index f55f5914444..cc35cb5816c 100644 --- a/ets2panda/ir/statements/annotationDeclaration.h +++ b/ets2panda/ir/statements/annotationDeclaration.h @@ -42,42 +42,57 @@ public: expr_(expr), properties_(allocator->Adapter()) { + EnableHistory(); } + + explicit AnnotationDeclaration(ArenaAllocator *allocator, AstNodeHistory *history) + : AnnotationAllowed(AstNodeType::ANNOTATION_DECLARATION, allocator), + expr_(nullptr), + properties_(allocator->Adapter()) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } + } + explicit AnnotationDeclaration(Expression *expr, ArenaVector &&properties, ArenaAllocator *allocator) : AnnotationAllowed(AstNodeType::ANNOTATION_DECLARATION, allocator), expr_(expr), properties_(std::move(properties)) { + EnableHistory(); } const util::StringView &InternalName() const { - return internalName_; + return HISTORY_GET(internalName_); } void SetInternalName(util::StringView internalName) { - internalName_ = internalName; + HISTORY_SET(internalName_, internalName); } [[nodiscard]] const Expression *Expr() const noexcept { - return expr_; + return HISTORY_GET(expr_); } [[nodiscard]] Expression *Expr() noexcept { - return expr_; + return HISTORY_GET(expr_); } - [[nodiscard]] ArenaVector &Properties() noexcept + [[nodiscard]] ArenaVector &PropertiesMutable() noexcept { - return properties_; + return HISTORY_GET_OR_CREATE(properties_); } [[nodiscard]] const ArenaVector &Properties() const noexcept { - return properties_; + return HISTORY_GET(properties_); } [[nodiscard]] const ArenaVector *PropertiesPtr() const @@ -87,37 +102,37 @@ public: void AddProperties(ArenaVector &&properties) { - properties_ = std::move(properties); + HISTORY_GET_OR_CREATE(properties_) = std::move(properties); } [[nodiscard]] bool IsSourceRetention() const noexcept { - return (policy_ & RetentionPolicy::SOURCE) != 0; + return (Policy() & RetentionPolicy::SOURCE) != 0; } [[nodiscard]] bool IsBytecodeRetention() const noexcept { - return (policy_ & RetentionPolicy::BYTECODE) != 0; + return (Policy() & RetentionPolicy::BYTECODE) != 0; } [[nodiscard]] bool IsRuntimeRetention() const noexcept { - return (policy_ & RetentionPolicy::RUNTIME) != 0; + return (Policy() & RetentionPolicy::RUNTIME) != 0; } void SetSourceRetention() noexcept { - policy_ = RetentionPolicy::SOURCE; + HISTORY_SET(policy_, RetentionPolicy::SOURCE); } void SetBytecodeRetention() noexcept { - policy_ = RetentionPolicy::BYTECODE; + HISTORY_SET(policy_, RetentionPolicy::BYTECODE); } void SetRuntimeRetention() noexcept { - policy_ = RetentionPolicy::RUNTIME; + HISTORY_SET(policy_, RetentionPolicy::RUNTIME); } void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; @@ -141,18 +156,18 @@ public: [[nodiscard]] varbinder::LocalScope *Scope() const noexcept override { - return scope_; + return HISTORY_GET(scope_); } void SetScope(varbinder::LocalScope *scope) { - ES2PANDA_ASSERT(scope_ == nullptr); - scope_ = scope; + ES2PANDA_ASSERT(Scope() == nullptr); + HISTORY_SET(scope_, scope); } void ClearScope() noexcept override { - scope_ = nullptr; + HISTORY_SET(scope_, nullptr); } Identifier *GetBaseName() const; @@ -163,6 +178,16 @@ protected: private: friend class SizeOfNodeTest; + RetentionPolicy Policy() const + { + return HISTORY_GET(policy_); + } + + void SetExpr(Expression *expr) + { + HISTORY_SET(expr_, expr); + } + util::StringView internalName_ {}; varbinder::LocalScope *scope_ {}; Expression *expr_; diff --git a/ets2panda/ir/statements/blockStatement.cpp b/ets2panda/ir/statements/blockStatement.cpp index 63cc1287f05..70943efd3a3 100644 --- a/ets2panda/ir/statements/blockStatement.cpp +++ b/ets2panda/ir/statements/blockStatement.cpp @@ -28,11 +28,13 @@ namespace ark::es2panda::ir { void BlockStatement::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { // This will survive pushing element to the back of statements_ in the process + auto &statements = Statements(); // NOLINTNEXTLINE(modernize-loop-convert) - for (size_t ix = 0; ix < statements_.size(); ix++) { - if (auto *transformedNode = cb(statements_[ix]); statements_[ix] != transformedNode) { - statements_[ix]->SetTransformedNode(transformationName, transformedNode); - statements_[ix] = transformedNode->AsStatement(); + for (size_t index = 0; index < statements.size(); index++) { + auto statement = statements[index]; + if (auto *transformedNode = cb(statement); statement != transformedNode) { + statement->SetTransformedNode(transformationName, transformedNode); + StatementsMutable()[index] = transformedNode->AsStatement(); } } } @@ -41,7 +43,7 @@ AstNode *BlockStatement::Clone(ArenaAllocator *const allocator, AstNode *const p { ArenaVector statements(allocator->Adapter()); - for (auto *statement : this->statements_) { + for (auto *statement : Statements()) { statements.push_back(statement->Clone(allocator, parent)->AsStatement()); } @@ -54,35 +56,37 @@ AstNode *BlockStatement::Clone(ArenaAllocator *const allocator, AstNode *const p void BlockStatement::Iterate(const NodeTraverser &cb) const { // This will survive pushing element to the back of statements_ in the process + auto &statements = Statements(); // NOLINTNEXTLINE(modernize-loop-convert) - for (size_t ix = 0; ix < statements_.size(); ix++) { - cb(statements_[ix]); + for (size_t ix = 0; ix < statements.size(); ix++) { + cb(statements[ix]); } } void BlockStatement::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", IsProgram() ? "Program" : "BlockStatement"}, {"statements", statements_}}); + dumper->Add({{"type", IsProgram() ? "Program" : "BlockStatement"}, {"statements", Statements()}}); } void BlockStatement::Dump(ir::SrcDumper *dumper) const { + auto &statements = Statements(); // NOTE(nsizov): trailing blocks if (Parent() != nullptr && (Parent()->IsBlockStatement() || Parent()->IsCallExpression())) { dumper->Add("{"); - if (!statements_.empty()) { + if (!statements.empty()) { dumper->IncrIndent(); dumper->Endl(); } } - for (auto statement : statements_) { + for (auto statement : statements) { statement->Dump(dumper); - if (statement != statements_.back()) { + if (statement != statements.back()) { dumper->Endl(); } } if (Parent() != nullptr && (Parent()->IsBlockStatement() || Parent()->IsCallExpression())) { - if (!statements_.empty()) { + if (!statements.empty()) { dumper->DecrIndent(); dumper->Endl(); } @@ -113,12 +117,12 @@ checker::VerifiedType BlockStatement::Check([[maybe_unused]] checker::ETSChecker BlockStatement *BlockStatement::Construct(ArenaAllocator *allocator) { ArenaVector statementList(allocator->Adapter()); - return allocator->New(allocator, std::move(statementList)); + return allocator->New(allocator, std::move(statementList), history_); } void BlockStatement::CopyTo(AstNode *other) const { - auto otherImpl = other->AsBlockStatement(); + auto otherImpl = static_cast(other); otherImpl->scope_ = scope_; otherImpl->statements_ = statements_; diff --git a/ets2panda/ir/statements/blockStatement.h b/ets2panda/ir/statements/blockStatement.h index 81745d7f37b..9b1cec21031 100644 --- a/ets2panda/ir/statements/blockStatement.h +++ b/ets2panda/ir/statements/blockStatement.h @@ -31,10 +31,21 @@ public: statements_(std::move(statementList)), trailingBlocks_(allocator->Adapter()) { + EnableHistory(); } - // NOTE (somas): this friend relationship can be removed once there are getters for private fields - friend class checker::ETSAnalyzer; + explicit BlockStatement(ArenaAllocator *allocator, ArenaVector &&statementList, + AstNodeHistory *history) + : Statement(AstNodeType::BLOCK_STATEMENT), + statements_(std::move(statementList)), + trailingBlocks_(allocator->Adapter()) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } + } [[nodiscard]] bool IsScopeBearer() const noexcept override { @@ -43,34 +54,34 @@ public: [[nodiscard]] varbinder::Scope *Scope() const noexcept override { - return scope_; + return HISTORY_GET(scope_); } void SetScope(varbinder::Scope *scope) noexcept { - scope_ = scope; + HISTORY_SET(scope_, scope); } void ClearScope() noexcept override { - scope_ = nullptr; + SetScope(nullptr); } const ArenaVector &Statements() const { - return statements_; + return HISTORY_GET(statements_); } - ArenaVector &Statements() + ArenaVector &StatementsMutable() { - return statements_; + return HISTORY_GET_OR_CREATE(statements_); } void SetStatements(ArenaVector &&statementList) { - statements_ = std::move(statementList); + HISTORY_GET_OR_CREATE(statements_) = std::move(statementList); - for (auto *statement : statements_) { + for (auto *statement : Statements()) { statement->SetParent(this); } } @@ -78,20 +89,26 @@ public: void AddStatement(Statement *stmt) { stmt->SetParent(this); - statements_.emplace_back(stmt); + HISTORY_GET_OR_CREATE(statements_).emplace_back(stmt); } - void AddStatements(ArenaVector &stmts) + void AddStatements(const ArenaVector &stmts) { for (auto *stmt : stmts) { stmt->SetParent(this); } - statements_.insert(statements_.end(), stmts.begin(), stmts.end()); + auto &statements = HISTORY_GET_OR_CREATE(statements_); + statements.insert(statements.end(), stmts.begin(), stmts.end()); + } + + const ArenaUnorderedMap &TrailingBlocks() const + { + return HISTORY_GET(trailingBlocks_); } void AddTrailingBlock(AstNode *stmt, BlockStatement *trailingBlock) { - trailingBlocks_.emplace(stmt, trailingBlock); + HISTORY_GET_OR_CREATE(trailingBlocks_).emplace(stmt, trailingBlock); } void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; diff --git a/ets2panda/ir/statements/classDeclaration.cpp b/ets2panda/ir/statements/classDeclaration.cpp index d459bc5e20c..34dc71ae7f2 100644 --- a/ets2panda/ir/statements/classDeclaration.cpp +++ b/ets2panda/ir/statements/classDeclaration.cpp @@ -26,12 +26,12 @@ namespace ark::es2panda::ir { ClassDeclaration *ClassDeclaration::Construct(ArenaAllocator *allocator) { - return allocator->New(nullptr, allocator); + return allocator->New(nullptr, allocator, history_); } void ClassDeclaration::CopyTo(AstNode *other) const { - auto otherImpl = other->AsClassDeclaration(); + auto otherImpl = static_cast(other); otherImpl->def_ = def_; otherImpl->decorators_ = decorators_; @@ -41,40 +41,46 @@ void ClassDeclaration::CopyTo(AstNode *other) const void ClassDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(decorators_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsDecorator(); + auto &decorators = Decorators(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < decorators.size(); ix++) { + if (auto *transformedNode = cb(decorators[ix]); decorators[ix] != transformedNode) { + decorators[ix]->SetTransformedNode(transformationName, transformedNode); + DecoratorsMutable()[ix] = transformedNode->AsDecorator(); } } - if (auto *transformedNode = cb(def_); def_ != transformedNode) { - def_->SetTransformedNode(transformationName, transformedNode); - def_ = transformedNode->AsClassDefinition(); + auto def = Definition(); + if (auto *transformedNode = cb(def); def != transformedNode) { + def->SetTransformedNode(transformationName, transformedNode); + SetDefinition(transformedNode->AsClassDefinition()); } } void ClassDeclaration::Iterate(const NodeTraverser &cb) const { - for (auto *it : VectorIterationGuard(decorators_)) { + for (auto *it : VectorIterationGuard(Decorators())) { cb(it); } - cb(def_); + auto def = HISTORY_GET(def_); + cb(def); } void ClassDeclaration::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", "ClassDeclaration"}, {"definition", def_}, {"decorators", AstDumper::Optional(decorators_)}}); + dumper->Add({{"type", "ClassDeclaration"}, + {"definition", Definition()}, + {"decorators", AstDumper::Optional(Decorators())}}); } void ClassDeclaration::Dump(ir::SrcDumper *dumper) const { - if (def_ != nullptr) { - def_->Dump(dumper); + if (Definition() != nullptr) { + Definition()->Dump(dumper); } // NOTE(nsizov): support decorators when supported in ArkTS - ES2PANDA_ASSERT(decorators_.empty()); + ES2PANDA_ASSERT(Decorators().empty()); } void ClassDeclaration::Compile(compiler::PandaGen *pg) const diff --git a/ets2panda/ir/statements/classDeclaration.h b/ets2panda/ir/statements/classDeclaration.h index 72a5afe51f3..c3389329ab0 100644 --- a/ets2panda/ir/statements/classDeclaration.h +++ b/ets2panda/ir/statements/classDeclaration.h @@ -24,21 +24,37 @@ public: explicit ClassDeclaration(ClassDefinition *def, ArenaAllocator *allocator) : Statement(AstNodeType::CLASS_DECLARATION), def_(def), decorators_(allocator->Adapter()) { + EnableHistory(); + } + + explicit ClassDeclaration(ClassDefinition *def, ArenaAllocator *allocator, AstNodeHistory *history) + : Statement(AstNodeType::CLASS_DECLARATION), def_(def), decorators_(allocator->Adapter()) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } ClassDefinition *Definition() { - return def_; + return HISTORY_GET(def_); } const ClassDefinition *Definition() const { - return def_; + return HISTORY_GET(def_); } const ArenaVector &Decorators() const { - return decorators_; + return HISTORY_GET(decorators_); + } + + ArenaVector &DecoratorsMutable() + { + return HISTORY_GET_OR_CREATE(decorators_); } const ArenaVector *DecoratorsPtr() const override @@ -48,7 +64,7 @@ public: void AddDecorators(ArenaVector &&decorators) override { - decorators_ = std::move(decorators); + HISTORY_GET_OR_CREATE(decorators_) = std::move(decorators); } bool CanHaveDecorator([[maybe_unused]] bool inTs) const override @@ -75,6 +91,7 @@ protected: explicit ClassDeclaration(AstNodeType type, ClassDefinition *const def, ArenaAllocator *const allocator) : Statement(type), def_(def), decorators_(allocator->Adapter()) { + EnableHistory(); } ClassDeclaration *Construct(ArenaAllocator *allocator) override; @@ -83,6 +100,11 @@ protected: private: friend class SizeOfNodeTest; + void SetDefinition(ClassDefinition *def) + { + HISTORY_SET(def_, def); + } + ClassDefinition *def_; ArenaVector decorators_; }; diff --git a/ets2panda/ir/statements/functionDeclaration.cpp b/ets2panda/ir/statements/functionDeclaration.cpp index 21fb0d5f85e..ff5be2b73ef 100644 --- a/ets2panda/ir/statements/functionDeclaration.cpp +++ b/ets2panda/ir/statements/functionDeclaration.cpp @@ -25,29 +25,27 @@ namespace ark::es2panda::ir { void FunctionDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - for (auto *&it : VectorIterationGuard(decorators_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsDecorator(); + auto &decorators = Decorators(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < decorators.size(); ix++) { + if (auto *transformedNode = cb(decorators[ix]); decorators[ix] != transformedNode) { + decorators[ix]->SetTransformedNode(transformationName, transformedNode); + DecoratorsMutable()[ix] = transformedNode->AsDecorator(); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); - if (auto *transformedNode = cb(func_); func_ != transformedNode) { - func_->SetTransformedNode(transformationName, transformedNode); - func_ = transformedNode->AsScriptFunction(); + auto func = Function(); + if (auto *transformedNode = cb(func); func != transformedNode) { + func->SetTransformedNode(transformationName, transformedNode); + SetFunction(transformedNode->AsScriptFunction()); } } void FunctionDeclaration::Iterate(const NodeTraverser &cb) const { - for (auto *it : VectorIterationGuard(decorators_)) { + for (auto *it : VectorIterationGuard(Decorators())) { cb(it); } @@ -55,15 +53,16 @@ void FunctionDeclaration::Iterate(const NodeTraverser &cb) const cb(it); } - cb(func_); + auto func = HISTORY_GET(func_); + cb(func); } void FunctionDeclaration::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", func_->IsOverload() ? "TSDeclareFunction" : "FunctionDeclaration"}, - {"decorators", AstDumper::Optional(decorators_)}, + dumper->Add({{"type", Function()->IsOverload() ? "TSDeclareFunction" : "FunctionDeclaration"}, + {"decorators", AstDumper::Optional(Decorators())}, {"annotations", AstDumper::Optional(Annotations())}, - {"function", func_}}); + {"function", Function()}}); } void FunctionDeclaration::Dump(ir::SrcDumper *dumper) const @@ -71,19 +70,20 @@ void FunctionDeclaration::Dump(ir::SrcDumper *dumper) const for (auto *anno : Annotations()) { anno->Dump(dumper); } - if (func_->IsNative()) { + auto func = Function(); + if (func->IsNative()) { dumper->Add("native "); } - if (func_->IsDeclare()) { + if (func->IsDeclare()) { dumper->Add("declare "); } - if (func_->IsAsyncFunc()) { + if (func->IsAsyncFunc()) { dumper->Add("async "); } dumper->Add("function "); - func_->Id()->Dump(dumper); - func_->Dump(dumper); + func->Id()->Dump(dumper); + func->Dump(dumper); } void FunctionDeclaration::Compile(compiler::PandaGen *pg) const @@ -108,7 +108,7 @@ checker::VerifiedType FunctionDeclaration::Check(checker::ETSChecker *checker) FunctionDeclaration *FunctionDeclaration::Construct(ArenaAllocator *allocator) { - return allocator->New(allocator, nullptr); + return allocator->New(allocator, nullptr, history_); } void FunctionDeclaration::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/statements/functionDeclaration.h b/ets2panda/ir/statements/functionDeclaration.h index 55a3443f02a..70ad88f9cee 100644 --- a/ets2panda/ir/statements/functionDeclaration.h +++ b/ets2panda/ir/statements/functionDeclaration.h @@ -36,7 +36,10 @@ public: func_(func), isAnonymous_(isAnonymous) { - flags_ = func->Modifiers(); + if (func != nullptr) { + flags_ = func->Modifiers(); + } + EnableHistory(); } explicit FunctionDeclaration(ArenaAllocator *allocator, ScriptFunction *func, bool isAnonymous = false) @@ -45,27 +48,47 @@ public: func_(func), isAnonymous_(isAnonymous) { - flags_ = func->Modifiers(); + if (func != nullptr) { + flags_ = func->Modifiers(); + } + EnableHistory(); + } + + explicit FunctionDeclaration(ArenaAllocator *allocator, ScriptFunction *func, bool isAnonymous, + AstNodeHistory *history) + : JsDocAllowed>(AstNodeType::FUNCTION_DECLARATION, allocator), + decorators_(allocator->Adapter()), + func_(func), + isAnonymous_(isAnonymous) + { + if (func != nullptr) { + flags_ = func->Modifiers(); + } + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } ScriptFunction *Function() { - return func_; + return HISTORY_GET(func_); } bool IsAnonymous() const { - return isAnonymous_; + return HISTORY_GET(isAnonymous_); } const ScriptFunction *Function() const { - return func_; + return HISTORY_GET(func_); } void AddDecorators([[maybe_unused]] ArenaVector &&decorators) override { - decorators_ = std::move(decorators); + HISTORY_GET_OR_CREATE(decorators_) = std::move(decorators); } bool CanHaveDecorator([[maybe_unused]] bool inTs) const override @@ -92,6 +115,21 @@ public: private: friend class SizeOfNodeTest; + void SetFunction(ScriptFunction *func) + { + HISTORY_SET(func_, func); + } + + [[nodiscard]] const ArenaVector &Decorators() const + { + return HISTORY_GET(decorators_); + } + + [[nodiscard]] ArenaVector &DecoratorsMutable() + { + return HISTORY_GET_OR_CREATE(decorators_); + } + ArenaVector decorators_; ScriptFunction *func_; bool isAnonymous_; diff --git a/ets2panda/ir/statements/variableDeclaration.cpp b/ets2panda/ir/statements/variableDeclaration.cpp index 56934876cfc..e81f3660795 100644 --- a/ets2panda/ir/statements/variableDeclaration.cpp +++ b/ets2panda/ir/statements/variableDeclaration.cpp @@ -24,31 +24,30 @@ namespace ark::es2panda::ir { void VariableDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - for (auto *&it : VectorIterationGuard(decorators_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsDecorator(); + auto &decorators = Decorators(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t index = 0; index < decorators.size(); ++index) { + if (auto *transformedNode = cb(decorators[index]); decorators[index] != transformedNode) { + decorators[index]->SetTransformedNode(transformationName, transformedNode); + DecoratorsMutable()[index] = transformedNode->AsDecorator(); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); - for (auto *&it : VectorIterationGuard(declarators_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsVariableDeclarator(); + auto &declarators = Declarators(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t index = 0; index < declarators.size(); ++index) { + if (auto *transformedNode = cb(declarators[index]); declarators[index] != transformedNode) { + declarators[index]->SetTransformedNode(transformationName, transformedNode); + DeclaratorsMutable()[index] = transformedNode->AsVariableDeclarator(); } } } void VariableDeclaration::Iterate(const NodeTraverser &cb) const { - for (auto *it : VectorIterationGuard(decorators_)) { + for (auto *it : VectorIterationGuard(Decorators())) { cb(it); } @@ -56,7 +55,7 @@ void VariableDeclaration::Iterate(const NodeTraverser &cb) const cb(it); } - for (auto *it : VectorIterationGuard(declarators_)) { + for (auto *it : VectorIterationGuard(Declarators())) { cb(it); } } @@ -65,7 +64,7 @@ void VariableDeclaration::Dump(ir::AstDumper *dumper) const { const char *kind = nullptr; - switch (kind_) { + switch (Kind()) { case VariableDeclarationKind::CONST: { kind = "const"; break; @@ -84,9 +83,9 @@ void VariableDeclaration::Dump(ir::AstDumper *dumper) const } dumper->Add({{"type", "VariableDeclaration"}, - {"declarations", declarators_}, + {"declarations", Declarators()}, {"kind", kind}, - {"decorators", AstDumper::Optional(decorators_)}, + {"decorators", AstDumper::Optional(Decorators())}, {"annotations", AstDumper::Optional(Annotations())}, {"declare", AstDumper::Optional(IsDeclare())}}); } @@ -101,7 +100,7 @@ void VariableDeclaration::Dump(ir::SrcDumper *dumper) const dumper->Add("declare "); } - switch (kind_) { + switch (Kind()) { case VariableDeclarationKind::CONST: dumper->Add("const "); break; @@ -115,15 +114,16 @@ void VariableDeclaration::Dump(ir::SrcDumper *dumper) const ES2PANDA_UNREACHABLE(); } - for (auto declarator : declarators_) { + for (auto declarator : Declarators()) { declarator->Dump(dumper); - if (declarator != declarators_.back()) { + if (declarator != Declarators().back()) { dumper->Add(", "); } } - if ((parent_ != nullptr) && - (parent_->IsBlockStatement() || parent_->IsBlockExpression() || parent_->IsSwitchCaseStatement())) { + auto parent = Parent(); + if ((parent != nullptr) && + (parent->IsBlockStatement() || parent->IsBlockExpression() || parent->IsSwitchCaseStatement())) { dumper->Add(";"); } } @@ -145,6 +145,33 @@ VariableDeclaration::VariableDeclaration([[maybe_unused]] Tag const tag, Variabl declarators_.emplace_back(d->Clone(allocator, nullptr)->AsVariableDeclarator()); declarators_.back()->SetParent(this); } + + EnableHistory(); +} + +VariableDeclaration::VariableDeclaration([[maybe_unused]] Tag const tag, VariableDeclaration const &other, + ArenaAllocator *const allocator, AstNodeHistory *history) + : JsDocAllowed>( + static_cast> const &>(other)), + kind_(other.kind_), + decorators_(allocator->Adapter()), + declarators_(allocator->Adapter()) +{ + for (auto const &d : other.decorators_) { + decorators_.emplace_back(d->Clone(allocator, nullptr)); + decorators_.back()->SetParent(this); + } + + for (auto const &d : other.declarators_) { + declarators_.emplace_back(d->Clone(allocator, nullptr)->AsVariableDeclarator()); + declarators_.back()->SetParent(this); + } + + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } VariableDeclaration *VariableDeclaration::Clone(ArenaAllocator *const allocator, AstNode *const parent) @@ -153,7 +180,7 @@ VariableDeclaration *VariableDeclaration::Clone(ArenaAllocator *const allocator, if (parent != nullptr) { clone->SetParent(parent); } - clone->SetRange(range_); + clone->SetRange(Range()); return clone; } @@ -180,7 +207,8 @@ checker::VerifiedType VariableDeclaration::Check([[maybe_unused]] checker::ETSCh VariableDeclaration *VariableDeclaration::Construct(ArenaAllocator *allocator) { ArenaVector declarators(allocator->Adapter()); - return allocator->New(VariableDeclarationKind::LET, allocator, std::move(declarators)); + return allocator->New(VariableDeclarationKind::LET, allocator, std::move(declarators), + history_); } void VariableDeclaration::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/statements/variableDeclaration.h b/ets2panda/ir/statements/variableDeclaration.h index 7b3f8a58040..ab6de4fd411 100644 --- a/ets2panda/ir/statements/variableDeclaration.h +++ b/ets2panda/ir/statements/variableDeclaration.h @@ -40,28 +40,56 @@ public: decorators_(allocator->Adapter()), declarators_(std::move(declarators)) { + EnableHistory(); + } + + explicit VariableDeclaration(VariableDeclarationKind kind, ArenaAllocator *allocator, + ArenaVector &&declarators, AstNodeHistory *history) + : JsDocAllowed>(AstNodeType::VARIABLE_DECLARATION, allocator), + kind_(kind), + decorators_(allocator->Adapter()), + declarators_(std::move(declarators)) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } explicit VariableDeclaration(Tag tag, VariableDeclaration const &other, ArenaAllocator *allocator); + explicit VariableDeclaration(Tag const tag, VariableDeclaration const &other, ArenaAllocator *const allocator, + AstNodeHistory *history); + const ArenaVector &Declarators() const { - return declarators_; + return HISTORY_GET(declarators_); } VariableDeclarationKind Kind() const { - return kind_; + return HISTORY_GET(kind_); } const ArenaVector &Decorators() const { - return decorators_; + return HISTORY_GET(decorators_); + } + + const ArenaVector *DecoratorsPtr() const override + { + return &Decorators(); + } + + [[nodiscard]] ArenaVector &DeclaratorsMutable() + { + return HISTORY_GET_OR_CREATE(declarators_); } VariableDeclarator *GetDeclaratorByName(util::StringView name) const { - for (VariableDeclarator *declarator : declarators_) { + for (VariableDeclarator *declarator : Declarators()) { if (declarator->Id()->AsIdentifier()->Name().Compare(name) == 0) { return declarator; } @@ -69,14 +97,9 @@ public: return nullptr; } - const ArenaVector *DecoratorsPtr() const override - { - return &Decorators(); - } - void AddDecorators([[maybe_unused]] ArenaVector &&decorators) override { - decorators_ = std::move(decorators); + HISTORY_GET_OR_CREATE(decorators_) = std::move(decorators); } bool CanHaveDecorator([[maybe_unused]] bool inTs) const override @@ -105,6 +128,12 @@ public: private: friend class SizeOfNodeTest; + + [[nodiscard]] ArenaVector &DecoratorsMutable() + { + return HISTORY_GET_OR_CREATE(decorators_); + } + VariableDeclarationKind kind_; ArenaVector decorators_; ArenaVector declarators_; diff --git a/ets2panda/ir/ts/tsAnyKeyword.cpp b/ets2panda/ir/ts/tsAnyKeyword.cpp index 99f5e085a28..f8cde5748f2 100644 --- a/ets2panda/ir/ts/tsAnyKeyword.cpp +++ b/ets2panda/ir/ts/tsAnyKeyword.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void TSAnyKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSAnyKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsArrayType.cpp b/ets2panda/ir/ts/tsArrayType.cpp index 8a1e1abd2c4..8ab2361fb90 100644 --- a/ets2panda/ir/ts/tsArrayType.cpp +++ b/ets2panda/ir/ts/tsArrayType.cpp @@ -27,12 +27,8 @@ void TSArrayType::TransformChildren(const NodeTransformer &cb, std::string_view elementType_->SetTransformedNode(transformationName, transformedNode); elementType_ = static_cast(transformedNode); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSArrayType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsBigintKeyword.cpp b/ets2panda/ir/ts/tsBigintKeyword.cpp index 7b42542a7d2..0e6a288d941 100644 --- a/ets2panda/ir/ts/tsBigintKeyword.cpp +++ b/ets2panda/ir/ts/tsBigintKeyword.cpp @@ -26,12 +26,7 @@ namespace ark::es2panda::ir { void TSBigintKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSBigintKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsBooleanKeyword.cpp b/ets2panda/ir/ts/tsBooleanKeyword.cpp index 4d5b6f018a6..bae3ac4ae1e 100644 --- a/ets2panda/ir/ts/tsBooleanKeyword.cpp +++ b/ets2panda/ir/ts/tsBooleanKeyword.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void TSBooleanKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSBooleanKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsConditionalType.cpp b/ets2panda/ir/ts/tsConditionalType.cpp index 6a70708b5c7..6a166ea3f06 100644 --- a/ets2panda/ir/ts/tsConditionalType.cpp +++ b/ets2panda/ir/ts/tsConditionalType.cpp @@ -43,12 +43,8 @@ void TSConditionalType::TransformChildren(const NodeTransformer &cb, std::string falseType_->SetTransformedNode(transformationName, transformedNode); falseType_ = transformedNode->AsExpression(); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSConditionalType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsConstructorType.cpp b/ets2panda/ir/ts/tsConstructorType.cpp index 681161a310c..327034616d3 100644 --- a/ets2panda/ir/ts/tsConstructorType.cpp +++ b/ets2panda/ir/ts/tsConstructorType.cpp @@ -26,12 +26,7 @@ namespace ark::es2panda::ir { void TSConstructorType::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { signature_.TransformChildren(cb, transformationName); - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSConstructorType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsEnumDeclaration.cpp b/ets2panda/ir/ts/tsEnumDeclaration.cpp index 42603eda1e2..08444dfcc62 100644 --- a/ets2panda/ir/ts/tsEnumDeclaration.cpp +++ b/ets2panda/ir/ts/tsEnumDeclaration.cpp @@ -27,35 +27,41 @@ namespace ark::es2panda::ir { void TSEnumDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - for (auto *&it : VectorIterationGuard(decorators_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsDecorator(); + auto &decorators = Decorators(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < decorators.size(); ix++) { + if (auto *transformedNode = cb(decorators[ix]); decorators[ix] != transformedNode) { + decorators[ix]->SetTransformedNode(transformationName, transformedNode); + DecoratorsMutable()[ix] = transformedNode->AsDecorator(); } } - if (auto *transformedNode = cb(key_); key_ != transformedNode) { - key_->SetTransformedNode(transformationName, transformedNode); - key_ = transformedNode->AsIdentifier(); + auto const key = Key(); + if (auto *transformedNode = cb(key); key != transformedNode) { + key->SetTransformedNode(transformationName, transformedNode); + SetKey(transformedNode->AsIdentifier()); } - for (auto *&it : VectorIterationGuard(members_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode; + auto &members = Members(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < members.size(); ix++) { + if (auto *transformedNode = cb(members[ix]); members[ix] != transformedNode) { + members[ix]->SetTransformedNode(transformationName, transformedNode); + MembersMutable()[ix] = transformedNode->AsDecorator(); } } } void TSEnumDeclaration::Iterate(const NodeTraverser &cb) const { - for (auto *it : VectorIterationGuard(decorators_)) { + for (auto *it : VectorIterationGuard(Decorators())) { cb(it); } - cb(key_); + auto key = HISTORY_GET(key_); + cb(key); - for (auto *it : VectorIterationGuard(members_)) { + for (auto *it : VectorIterationGuard(Members())) { cb(it); } } @@ -63,10 +69,10 @@ void TSEnumDeclaration::Iterate(const NodeTraverser &cb) const void TSEnumDeclaration::Dump(ir::AstDumper *dumper) const { dumper->Add({{"type", "TSEnumDeclaration"}, - {"decorators", AstDumper::Optional(decorators_)}, - {"id", key_}, - {"members", members_}, - {"const", isConst_}, + {"decorators", AstDumper::Optional(Decorators())}, + {"id", Key()}, + {"members", Members()}, + {"const", IsConst()}, {"declare", IsDeclare()}}); } @@ -80,39 +86,42 @@ bool TSEnumDeclaration::RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) cons return false; } - if (key_->Parent()->IsDefaultExported() || key_->Parent()->IsExported()) { + auto key = Key(); + if (key->Parent()->IsDefaultExported() || key->Parent()->IsExported()) { return false; } - auto name = key_->AsIdentifier()->Name().Mutf8(); + auto name = key->AsIdentifier()->Name().Mutf8(); dumper->AddNode(name, this); return true; } void TSEnumDeclaration::Dump(ir::SrcDumper *dumper) const { - ES2PANDA_ASSERT(isConst_ == false); - ES2PANDA_ASSERT(key_ != nullptr); + ES2PANDA_ASSERT(IsConst() == false); + ES2PANDA_ASSERT(Key() != nullptr); if (RegisterUnexportedForDeclGen(dumper)) { return; } - if (key_->Parent()->IsExported() && dumper->IsDeclgen()) { + auto key = Key(); + if (key->Parent()->IsExported() && dumper->IsDeclgen()) { dumper->Add("export "); - } else if (key_->Parent()->IsDefaultExported() && dumper->IsDeclgen()) { + } else if (key->Parent()->IsDefaultExported() && dumper->IsDeclgen()) { dumper->Add("export default "); } if (IsDeclare() || dumper->IsDeclgen()) { dumper->Add("declare "); } dumper->Add("enum "); - key_->Dump(dumper); + key->Dump(dumper); dumper->Add(" {"); - if (!members_.empty()) { + auto &members = Members(); + if (!members.empty()) { dumper->IncrIndent(); dumper->Endl(); - for (auto member : members_) { + for (auto member : members) { member->Dump(dumper); - if (member != members_.back()) { + if (member != members.back()) { dumper->Add(","); dumper->Endl(); } @@ -170,7 +179,7 @@ TSEnumDeclaration *TSEnumDeclaration::Construct(ArenaAllocator *allocator) { ArenaVector members(allocator->Adapter()); return allocator->New(allocator, nullptr, std::move(members), - ConstructorFlags {false, false, false}); + ConstructorFlags {false, false, false}, history_); } void TSEnumDeclaration::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ts/tsEnumDeclaration.h b/ets2panda/ir/ts/tsEnumDeclaration.h index ffb58b61536..27651a26308 100644 --- a/ets2panda/ir/ts/tsEnumDeclaration.h +++ b/ets2panda/ir/ts/tsEnumDeclaration.h @@ -52,6 +52,28 @@ public: if (flags.isDeclare) { AddModifier(ModifierFlags::DECLARE); } + EnableHistory(); + } + + explicit TSEnumDeclaration(ArenaAllocator *allocator, Identifier *key, ArenaVector &&members, + ConstructorFlags &&flags, AstNodeHistory *history) + : TypedStatement(AstNodeType::TS_ENUM_DECLARATION), + decorators_(allocator->Adapter()), + key_(key), + members_(std::move(members)), + isConst_(flags.isConst) + { + if (flags.isStatic) { + AddModifier(ModifierFlags::STATIC); + } + if (flags.isDeclare) { + AddModifier(ModifierFlags::DECLARE); + } + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } [[nodiscard]] bool IsScopeBearer() const noexcept override @@ -61,63 +83,73 @@ public: [[nodiscard]] varbinder::LocalScope *Scope() const noexcept override { - return scope_; + return HISTORY_GET(scope_); } void SetScope(varbinder::LocalScope *scope) { - ES2PANDA_ASSERT(scope_ == nullptr); - scope_ = scope; + ES2PANDA_ASSERT(Scope() == nullptr); + HISTORY_SET(scope_, scope); } void ClearScope() noexcept override { - scope_ = nullptr; + HISTORY_SET(scope_, nullptr); } const Identifier *Key() const { - return key_; + return HISTORY_GET(key_); } Identifier *Key() { - return key_; + return HISTORY_GET(key_); } const ArenaVector &Members() const { - return members_; + return HISTORY_GET(members_); + } + + [[nodiscard]] ArenaVector &MembersMutable() + { + return HISTORY_GET_OR_CREATE(members_); } const util::StringView &InternalName() const { - return internalName_; + return HISTORY_GET(internalName_); } void SetInternalName(util::StringView internalName) { - internalName_ = internalName; + HISTORY_SET(internalName_, internalName); } ir::ClassDefinition *BoxedClass() const { - return boxedClass_; + return HISTORY_GET(boxedClass_); } - void SetBoxedClass(ir::ClassDefinition *const wrapperClass) + void SetBoxedClass(ir::ClassDefinition *wrapperClass) { - boxedClass_ = wrapperClass; + HISTORY_SET(boxedClass_, wrapperClass); } bool IsConst() const { - return isConst_; + return HISTORY_GET(isConst_); } const ArenaVector &Decorators() const { - return decorators_; + return HISTORY_GET(decorators_); + } + + [[nodiscard]] ArenaVector &DecoratorsMutable() + { + return HISTORY_GET_OR_CREATE(decorators_); } const ArenaVector *DecoratorsPtr() const override @@ -127,7 +159,7 @@ public: void AddDecorators([[maybe_unused]] ArenaVector &&decorators) override { - decorators_ = std::move(decorators); + HISTORY_GET_OR_CREATE(decorators_) = std::move(decorators); } bool CanHaveDecorator([[maybe_unused]] bool inTs) const override @@ -155,8 +187,14 @@ public: void CopyTo(AstNode *other) const override; private: - bool RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const; friend class SizeOfNodeTest; + bool RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const; + + void SetKey(Identifier *key) + { + HISTORY_SET(key_, key); + } + varbinder::LocalScope *scope_ {nullptr}; ArenaVector decorators_; Identifier *key_; diff --git a/ets2panda/ir/ts/tsFunctionType.cpp b/ets2panda/ir/ts/tsFunctionType.cpp index ed1698e0a2e..89e4751aeb9 100644 --- a/ets2panda/ir/ts/tsFunctionType.cpp +++ b/ets2panda/ir/ts/tsFunctionType.cpp @@ -27,12 +27,7 @@ namespace ark::es2panda::ir { void TSFunctionType::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { signature_.TransformChildren(cb, transformationName); - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSFunctionType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsImportType.cpp b/ets2panda/ir/ts/tsImportType.cpp index 7854c7d3c87..a0f981b892b 100644 --- a/ets2panda/ir/ts/tsImportType.cpp +++ b/ets2panda/ir/ts/tsImportType.cpp @@ -44,12 +44,8 @@ void TSImportType::TransformChildren(const NodeTransformer &cb, std::string_view qualifier_ = transformedNode->AsExpression(); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSImportType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsIndexedAccessType.cpp b/ets2panda/ir/ts/tsIndexedAccessType.cpp index f2d897be6e7..e1e110231a6 100644 --- a/ets2panda/ir/ts/tsIndexedAccessType.cpp +++ b/ets2panda/ir/ts/tsIndexedAccessType.cpp @@ -34,12 +34,8 @@ void TSIndexedAccessType::TransformChildren(const NodeTransformer &cb, std::stri indexType_->SetTransformedNode(transformationName, transformedNode); indexType_ = static_cast(transformedNode); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSIndexedAccessType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsInferType.cpp b/ets2panda/ir/ts/tsInferType.cpp index 5db886b2e48..dd9d1746dcb 100644 --- a/ets2panda/ir/ts/tsInferType.cpp +++ b/ets2panda/ir/ts/tsInferType.cpp @@ -29,12 +29,8 @@ void TSInferType::TransformChildren(const NodeTransformer &cb, std::string_view typeParam_->SetTransformedNode(transformationName, transformedNode); typeParam_ = transformedNode->AsTSTypeParameter(); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSInferType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsInterfaceDeclaration.cpp b/ets2panda/ir/ts/tsInterfaceDeclaration.cpp index bea508e3884..f98f226b6a3 100644 --- a/ets2panda/ir/ts/tsInterfaceDeclaration.cpp +++ b/ets2panda/ir/ts/tsInterfaceDeclaration.cpp @@ -36,48 +36,50 @@ namespace ark::es2panda::ir { void TSInterfaceDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - for (auto *&it : VectorIterationGuard(decorators_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsDecorator(); + auto &decorators = Decorators(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < decorators.size(); ix++) { + if (auto *transformedNode = cb(decorators[ix]); decorators[ix] != transformedNode) { + decorators[ix]->SetTransformedNode(transformationName, transformedNode); + DecoratorsMutable()[ix] = transformedNode->AsDecorator(); } } - for (auto *&it : Annotations()) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); - if (auto *transformedNode = cb(id_); id_ != transformedNode) { - id_->SetTransformedNode(transformationName, transformedNode); - id_ = transformedNode->AsIdentifier(); + auto id = Id(); + if (auto *transformedNode = cb(id); id != transformedNode) { + id->SetTransformedNode(transformationName, transformedNode); + SetId(transformedNode->AsIdentifier()); } - if (typeParams_ != nullptr) { - if (auto *transformedNode = cb(typeParams_); typeParams_ != transformedNode) { - typeParams_->SetTransformedNode(transformationName, transformedNode); - typeParams_ = transformedNode->AsTSTypeParameterDeclaration(); + auto typeParams = TypeParams(); + if (typeParams != nullptr) { + if (auto *transformedNode = cb(typeParams); typeParams != transformedNode) { + typeParams->SetTransformedNode(transformationName, transformedNode); + SetTypeParams(transformedNode->AsTSTypeParameterDeclaration()); } } - for (auto *&it : VectorIterationGuard(extends_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsTSInterfaceHeritage(); + auto &extends = Extends(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < extends.size(); ix++) { + if (auto *transformedNode = cb(extends[ix]); extends[ix] != transformedNode) { + extends[ix]->SetTransformedNode(transformationName, transformedNode); + ExtendsMutable()[ix] = transformedNode->AsTSInterfaceHeritage(); } } - if (auto *transformedNode = cb(body_); body_ != transformedNode) { - body_->SetTransformedNode(transformationName, transformedNode); - body_ = transformedNode->AsTSInterfaceBody(); + auto body = Body(); + if (auto *transformedNode = cb(body); body != transformedNode) { + body->SetTransformedNode(transformationName, transformedNode); + SetBody(transformedNode->AsTSInterfaceBody()); } } void TSInterfaceDeclaration::Iterate(const NodeTraverser &cb) const { - for (auto *it : VectorIterationGuard(decorators_)) { + for (auto *it : VectorIterationGuard(Decorators())) { cb(it); } @@ -85,28 +87,31 @@ void TSInterfaceDeclaration::Iterate(const NodeTraverser &cb) const cb(it); } - cb(id_); + auto id = HISTORY_GET(id_); + cb(id); - if (typeParams_ != nullptr) { - cb(typeParams_); + auto typeParams = HISTORY_GET(typeParams_); + if (typeParams != nullptr) { + cb(typeParams); } - for (auto *it : VectorIterationGuard(extends_)) { + for (auto *it : VectorIterationGuard(Extends())) { cb(it); } - cb(body_); + auto body = HISTORY_GET(body_); + cb(body); } void TSInterfaceDeclaration::Dump(ir::AstDumper *dumper) const { dumper->Add({{"type", "TSInterfaceDeclaration"}, - {"decorators", AstDumper::Optional(decorators_)}, + {"decorators", AstDumper::Optional(Decorators())}, {"annotations", AstDumper::Optional(Annotations())}, - {"body", body_}, - {"id", id_}, - {"extends", extends_}, - {"typeParameters", AstDumper::Optional(typeParams_)}}); + {"body", Body()}, + {"id", Id()}, + {"extends", Extends()}, + {"typeParameters", AstDumper::Optional(TypeParams())}}); } bool TSInterfaceDeclaration::RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const @@ -119,58 +124,64 @@ bool TSInterfaceDeclaration::RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) return false; } - if (id_->Parent()->IsDefaultExported() || id_->Parent()->IsExported()) { + auto id = Id(); + if (id->Parent()->IsDefaultExported() || id->Parent()->IsExported()) { return false; } - auto name = id_->Name().Mutf8(); + auto name = id->Name().Mutf8(); dumper->AddNode(name, this); return true; } void TSInterfaceDeclaration::Dump(ir::SrcDumper *dumper) const { - ES2PANDA_ASSERT(id_); - if (!id_->Parent()->IsDefaultExported() && !id_->Parent()->IsExported() && dumper->IsDeclgen() && + ES2PANDA_ASSERT(Id() != nullptr); + auto id = Id(); + if (!id->Parent()->IsDefaultExported() && !id->Parent()->IsExported() && dumper->IsDeclgen() && !dumper->IsIndirectDepPhase()) { - auto name = id_->Name().Mutf8(); + auto name = id->Name().Mutf8(); dumper->AddNode(name, this); return; } for (auto *anno : Annotations()) { anno->Dump(dumper); } - if (id_->Parent()->IsExported()) { + if (id->Parent()->IsExported()) { dumper->Add("export "); - } else if (id_->Parent()->IsDefaultExported()) { + } else if (id->Parent()->IsDefaultExported()) { dumper->Add("export default "); } if (IsDeclare() || dumper->IsDeclgen()) { dumper->Add("declare "); } dumper->Add("interface "); - id_->Dump(dumper); + id->Dump(dumper); - if (typeParams_ != nullptr) { + auto typeParams = TypeParams(); + if (typeParams != nullptr) { dumper->Add("<"); - typeParams_->Dump(dumper); + typeParams->Dump(dumper); dumper->Add(">"); } - if (!extends_.empty()) { + + auto &extends = Extends(); + if (!extends.empty()) { dumper->Add(" extends "); - for (auto ext : extends_) { + for (auto ext : extends) { ext->Dump(dumper); - if (ext != extends_.back()) { + if (ext != extends.back()) { dumper->Add(", "); } } } + auto body = Body(); dumper->Add(" {"); - if (body_ != nullptr) { + if (body != nullptr) { dumper->IncrIndent(); dumper->Endl(); - body_->Dump(dumper); + body->Dump(dumper); dumper->DecrIndent(); dumper->Endl(); } @@ -202,7 +213,8 @@ TSInterfaceDeclaration *TSInterfaceDeclaration::Construct(ArenaAllocator *alloca { ArenaVector extends(allocator->Adapter()); return allocator->New( - allocator, std::move(extends), ConstructorData {nullptr, nullptr, nullptr, false, false, Language::Id::COUNT}); + allocator, std::move(extends), ConstructorData {nullptr, nullptr, nullptr, false, false, Language::Id::COUNT}, + history_); } void TSInterfaceDeclaration::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ts/tsInterfaceDeclaration.h b/ets2panda/ir/ts/tsInterfaceDeclaration.h index fb338b4c963..6165cccf82d 100644 --- a/ets2panda/ir/ts/tsInterfaceDeclaration.h +++ b/ets2panda/ir/ts/tsInterfaceDeclaration.h @@ -58,6 +58,29 @@ public: if (isStatic_) { AddModifier(ir::ModifierFlags::STATIC); } + EnableHistory(); + } + + explicit TSInterfaceDeclaration(ArenaAllocator *allocator, ArenaVector &&extends, + ConstructorData &&data, AstNodeHistory *history) + : JsDocAllowed>(AstNodeType::TS_INTERFACE_DECLARATION, allocator), + decorators_(allocator->Adapter()), + id_(data.id), + typeParams_(data.typeParams), + body_(data.body), + extends_(std::move(extends)), + isStatic_(data.isStatic), + isExternal_(data.isExternal), + lang_(data.lang) + { + if (isStatic_) { + AddModifier(ir::ModifierFlags::STATIC); + } + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } [[nodiscard]] bool IsScopeBearer() const noexcept override @@ -67,83 +90,88 @@ public: [[nodiscard]] varbinder::LocalScope *Scope() const noexcept override { - return scope_; + return HISTORY_GET(scope_); } void SetScope(varbinder::LocalScope *scope) { - ES2PANDA_ASSERT(scope_ == nullptr); - scope_ = scope; + ES2PANDA_ASSERT(Scope() == nullptr); + HISTORY_SET(scope_, scope); } void ClearScope() noexcept override { - scope_ = nullptr; + HISTORY_SET(scope_, nullptr); } TSInterfaceBody *Body() { - return body_; + return HISTORY_GET(body_); } const TSInterfaceBody *Body() const { - return body_; + return HISTORY_GET(body_); } Identifier *Id() { - return id_; + return HISTORY_GET(id_); } const Identifier *Id() const { - return id_; + return HISTORY_GET(id_); } const util::StringView &InternalName() const { - return internalName_; + return HISTORY_GET(internalName_); } void SetInternalName(util::StringView internalName) { - internalName_ = internalName; + HISTORY_SET(internalName_, internalName); } bool IsStatic() const { - return isStatic_; + return HISTORY_GET(isStatic_); } bool IsFromExternal() const { - return isExternal_; + return HISTORY_GET(isExternal_); } const TSTypeParameterDeclaration *TypeParams() const { - return typeParams_; + return HISTORY_GET(typeParams_); } TSTypeParameterDeclaration *TypeParams() { - return typeParams_; + return HISTORY_GET(typeParams_); } - ArenaVector &Extends() + ArenaVector &ExtendsMutable() { - return extends_; + return HISTORY_GET_OR_CREATE(extends_); } const ArenaVector &Extends() const { - return extends_; + return HISTORY_GET(extends_); } const ArenaVector &Decorators() const { - return decorators_; + return HISTORY_GET(decorators_); + } + + [[nodiscard]] ArenaVector &DecoratorsMutable() + { + return HISTORY_GET_OR_CREATE(decorators_); } const ArenaVector *DecoratorsPtr() const override @@ -153,7 +181,7 @@ public: void AddDecorators([[maybe_unused]] ArenaVector &&decorators) override { - decorators_ = std::move(decorators); + HISTORY_GET_OR_CREATE(decorators_) = std::move(decorators); } bool CanHaveDecorator([[maybe_unused]] bool inTs) const override @@ -165,22 +193,22 @@ public: es2panda::Language Language() const { - return lang_; + return HISTORY_GET(lang_); } ClassDeclaration *GetAnonClass() noexcept { - return anonClass_; + return HISTORY_GET(anonClass_); } ClassDeclaration *GetAnonClass() const noexcept { - return anonClass_; + return HISTORY_GET(anonClass_); } void SetAnonClass(ClassDeclaration *anonClass) noexcept { - anonClass_ = anonClass; + HISTORY_SET(anonClass_, anonClass); } void Iterate(const NodeTraverser &cb) const override; @@ -201,8 +229,24 @@ public: void CopyTo(AstNode *other) const override; private: - bool RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const; friend class SizeOfNodeTest; + bool RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const; + + void SetId(Identifier *id) + { + HISTORY_SET(id_, id); + } + + void SetTypeParams(TSTypeParameterDeclaration *typeParams) + { + HISTORY_SET(typeParams_, typeParams); + } + + void SetBody(TSInterfaceBody *body) + { + HISTORY_SET(body_, body); + } + ArenaVector decorators_; varbinder::LocalScope *scope_ {nullptr}; Identifier *id_; diff --git a/ets2panda/ir/ts/tsIntersectionType.cpp b/ets2panda/ir/ts/tsIntersectionType.cpp index 75cf7834dca..6dc630a18a4 100644 --- a/ets2panda/ir/ts/tsIntersectionType.cpp +++ b/ets2panda/ir/ts/tsIntersectionType.cpp @@ -31,12 +31,8 @@ void TSIntersectionType::TransformChildren(const NodeTransformer &cb, std::strin it = transformedNode->AsExpression(); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSIntersectionType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsLiteralType.cpp b/ets2panda/ir/ts/tsLiteralType.cpp index 25a998cc179..a679912bf4d 100644 --- a/ets2panda/ir/ts/tsLiteralType.cpp +++ b/ets2panda/ir/ts/tsLiteralType.cpp @@ -28,12 +28,8 @@ void TSLiteralType::TransformChildren(const NodeTransformer &cb, std::string_vie literal_->SetTransformedNode(transformationName, transformedNode); literal_ = transformedNode->AsExpression(); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSLiteralType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsMappedType.cpp b/ets2panda/ir/ts/tsMappedType.cpp index fef66f0e8c8..61da853b75b 100644 --- a/ets2panda/ir/ts/tsMappedType.cpp +++ b/ets2panda/ir/ts/tsMappedType.cpp @@ -37,12 +37,8 @@ void TSMappedType::TransformChildren(const NodeTransformer &cb, std::string_view typeAnnotation_ = static_cast(transformedNode); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSMappedType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsNamedTupleMember.cpp b/ets2panda/ir/ts/tsNamedTupleMember.cpp index d07fb3d9826..742f9e6cd4f 100644 --- a/ets2panda/ir/ts/tsNamedTupleMember.cpp +++ b/ets2panda/ir/ts/tsNamedTupleMember.cpp @@ -34,12 +34,8 @@ void TSNamedTupleMember::TransformChildren(const NodeTransformer &cb, std::strin elementType_->SetTransformedNode(transformationName, transformedNode); elementType_ = static_cast(transformedNode); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSNamedTupleMember::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsNeverKeyword.cpp b/ets2panda/ir/ts/tsNeverKeyword.cpp index 9b1386dcad5..a48751933c6 100644 --- a/ets2panda/ir/ts/tsNeverKeyword.cpp +++ b/ets2panda/ir/ts/tsNeverKeyword.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void TSNeverKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSNeverKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsNullKeyword.cpp b/ets2panda/ir/ts/tsNullKeyword.cpp index d7050a9ff3c..6e089e142a4 100644 --- a/ets2panda/ir/ts/tsNullKeyword.cpp +++ b/ets2panda/ir/ts/tsNullKeyword.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void TSNullKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSNullKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsNumberKeyword.cpp b/ets2panda/ir/ts/tsNumberKeyword.cpp index 9c9125def9d..afcee6e7b57 100644 --- a/ets2panda/ir/ts/tsNumberKeyword.cpp +++ b/ets2panda/ir/ts/tsNumberKeyword.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void TSNumberKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSNumberKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsObjectKeyword.cpp b/ets2panda/ir/ts/tsObjectKeyword.cpp index fd807caf030..3b4ea39d6e3 100644 --- a/ets2panda/ir/ts/tsObjectKeyword.cpp +++ b/ets2panda/ir/ts/tsObjectKeyword.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void TSObjectKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSObjectKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsParenthesizedType.cpp b/ets2panda/ir/ts/tsParenthesizedType.cpp index 4ee640455b2..4608efb3947 100644 --- a/ets2panda/ir/ts/tsParenthesizedType.cpp +++ b/ets2panda/ir/ts/tsParenthesizedType.cpp @@ -28,12 +28,8 @@ void TSParenthesizedType::TransformChildren(const NodeTransformer &cb, std::stri type_->SetTransformedNode(transformationName, transformedNode); type_ = static_cast(transformedNode); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSParenthesizedType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsStringKeyword.cpp b/ets2panda/ir/ts/tsStringKeyword.cpp index 825b446bc4b..be62a340044 100644 --- a/ets2panda/ir/ts/tsStringKeyword.cpp +++ b/ets2panda/ir/ts/tsStringKeyword.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void TSStringKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSStringKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsThisType.cpp b/ets2panda/ir/ts/tsThisType.cpp index da5e36ad8ce..9af97be93c8 100644 --- a/ets2panda/ir/ts/tsThisType.cpp +++ b/ets2panda/ir/ts/tsThisType.cpp @@ -24,12 +24,7 @@ namespace ark::es2panda::ir { void TSThisType::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSThisType::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsTupleType.cpp b/ets2panda/ir/ts/tsTupleType.cpp index cb69e8542ca..d98cbd16229 100644 --- a/ets2panda/ir/ts/tsTupleType.cpp +++ b/ets2panda/ir/ts/tsTupleType.cpp @@ -35,12 +35,8 @@ void TSTupleType::TransformChildren(const NodeTransformer &cb, std::string_view it = static_cast(transformedNode); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSTupleType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp b/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp index 26bcca0adb1..29c5de2edad 100644 --- a/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp +++ b/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp @@ -29,29 +29,35 @@ namespace ark::es2panda::ir { void TSTypeAliasDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - for (auto *&it : VectorIterationGuard(decorators_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsDecorator(); + auto &decorators = Decorators(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < decorators.size(); ix++) { + if (auto *transformedNode = cb(decorators[ix]); decorators[ix] != transformedNode) { + decorators[ix]->SetTransformedNode(transformationName, transformedNode); + DecoratorsMutable()[ix] = transformedNode->AsDecorator(); } } - for (auto *&it : Annotations()) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); + auto &annotations = Annotations(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < annotations.size(); ix++) { + if (auto *transformedNode = cb(annotations[ix]); annotations[ix] != transformedNode) { + annotations[ix]->SetTransformedNode(transformationName, transformedNode); + AnnotationsMutable()[ix] = transformedNode->AsAnnotationUsage(); } } - if (auto *transformedNode = cb(id_); id_ != transformedNode) { - id_->SetTransformedNode(transformationName, transformedNode); - id_ = transformedNode->AsIdentifier(); + auto id = Id(); + if (auto *transformedNode = cb(id); id != transformedNode) { + id->SetTransformedNode(transformationName, transformedNode); + SetId(transformedNode->AsIdentifier()); } - if (typeParams_ != nullptr) { - if (auto *transformedNode = cb(typeParams_); typeParams_ != transformedNode) { - typeParams_->SetTransformedNode(transformationName, transformedNode); - typeParams_ = transformedNode->AsTSTypeParameterDeclaration(); + auto typeParams = TypeParams(); + if (typeParams != nullptr) { + if (auto *transformedNode = cb(typeParams); typeParams != transformedNode) { + typeParams->SetTransformedNode(transformationName, transformedNode); + SetTypeParameters(transformedNode->AsTSTypeParameterDeclaration()); } } @@ -65,7 +71,7 @@ void TSTypeAliasDeclaration::TransformChildren(const NodeTransformer &cb, std::s void TSTypeAliasDeclaration::Iterate(const NodeTraverser &cb) const { - for (auto *it : VectorIterationGuard(decorators_)) { + for (auto *it : VectorIterationGuard(Decorators())) { cb(it); } @@ -73,25 +79,28 @@ void TSTypeAliasDeclaration::Iterate(const NodeTraverser &cb) const cb(it); } - cb(id_); + auto id = HISTORY_GET(id_); + cb(id); - if (typeParams_ != nullptr) { - cb(typeParams_); + auto typeParams = HISTORY_GET(typeParams_); + if (typeParams != nullptr) { + cb(typeParams); } - if (TypeAnnotation() != nullptr) { - cb(TypeAnnotation()); + auto typeAnnotation = TypeAnnotation(); + if (typeAnnotation != nullptr) { + cb(typeAnnotation); } } void TSTypeAliasDeclaration::Dump(ir::AstDumper *dumper) const { dumper->Add({{"type", "TSTypeAliasDeclaration"}, - {"decorators", AstDumper::Optional(decorators_)}, + {"decorators", AstDumper::Optional(Decorators())}, {"annotations", AstDumper::Optional(Annotations())}, - {"id", id_}, + {"id", Id()}, {"typeAnnotation", AstDumper::Optional(TypeAnnotation())}, - {"typeParameters", AstDumper::Optional(typeParams_)}}); + {"typeParameters", AstDumper::Optional(TypeParams())}}); } bool TSTypeAliasDeclaration::RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const @@ -104,36 +113,39 @@ bool TSTypeAliasDeclaration::RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) return false; } - if (id_->Parent()->IsExported() || id_->Parent()->IsDefaultExported()) { + auto id = Id(); + if (id->Parent()->IsExported() || id->Parent()->IsDefaultExported()) { return false; } - auto name = id_->Name().Mutf8(); + auto name = id->Name().Mutf8(); dumper->AddNode(name, this); return true; } void TSTypeAliasDeclaration::Dump(ir::SrcDumper *dumper) const { - ES2PANDA_ASSERT(id_); + ES2PANDA_ASSERT(Id() != nullptr); if (RegisterUnexportedForDeclGen(dumper)) { return; } for (auto *anno : Annotations()) { anno->Dump(dumper); } - if (id_->Parent()->IsExported()) { + auto id = Id(); + if (id->Parent()->IsExported()) { dumper->Add("export "); } dumper->Add("type "); - id_->Dump(dumper); - if (typeParams_ != nullptr) { + id->Dump(dumper); + auto typeParams = TypeParams(); + if (typeParams != nullptr) { dumper->Add("<"); - typeParams_->Dump(dumper); + typeParams->Dump(dumper); dumper->Add(">"); } dumper->Add(" = "); - if (id_->IsAnnotatedExpression()) { + if (id->IsAnnotatedExpression()) { auto type = TypeAnnotation(); ES2PANDA_ASSERT(type); type->Dump(dumper); @@ -164,7 +176,7 @@ checker::VerifiedType TSTypeAliasDeclaration::Check([[maybe_unused]] checker::ET TSTypeAliasDeclaration *TSTypeAliasDeclaration::Construct(ArenaAllocator *allocator) { - return allocator->New(allocator, nullptr, nullptr, nullptr); + return allocator->New(allocator, history_); } void TSTypeAliasDeclaration::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ts/tsTypeAliasDeclaration.h b/ets2panda/ir/ts/tsTypeAliasDeclaration.h index 4d44e900213..7f8f063faf4 100644 --- a/ets2panda/ir/ts/tsTypeAliasDeclaration.h +++ b/ets2panda/ir/ts/tsTypeAliasDeclaration.h @@ -40,6 +40,7 @@ public: typeParams_(typeParams), typeParamTypes_(allocator->Adapter()) { + EnableHistory(); } explicit TSTypeAliasDeclaration(ArenaAllocator *allocator, Identifier *id) @@ -50,26 +51,47 @@ public: typeParams_(nullptr), typeParamTypes_(allocator->Adapter()) { + EnableHistory(); + } + + explicit TSTypeAliasDeclaration(ArenaAllocator *allocator, AstNodeHistory *history) + : JsDocAllowed(allocator, AstNodeType::TS_TYPE_ALIAS_DECLARATION), + decorators_(allocator->Adapter()), + annotations_(allocator->Adapter()), + id_(nullptr), + typeParams_(nullptr), + typeParamTypes_(allocator->Adapter()) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } Identifier *Id() { - return id_; + return HISTORY_GET(id_); } const Identifier *Id() const { - return id_; + return HISTORY_GET(id_); } TSTypeParameterDeclaration *TypeParams() const { - return typeParams_; + return HISTORY_GET(typeParams_); } const ArenaVector &Decorators() const { - return decorators_; + return HISTORY_GET(decorators_); + } + + [[nodiscard]] ArenaVector &DecoratorsMutable() + { + return HISTORY_GET_OR_CREATE(decorators_); } const ArenaVector *DecoratorsPtr() const override @@ -79,12 +101,12 @@ public: void SetTypeParameters(ir::TSTypeParameterDeclaration *typeParams) { - typeParams_ = typeParams; + HISTORY_SET(typeParams_, typeParams); } void AddDecorators([[maybe_unused]] ArenaVector &&decorators) override { - decorators_ = std::move(decorators); + HISTORY_GET_OR_CREATE(decorators_) = std::move(decorators); } bool CanHaveDecorator([[maybe_unused]] bool inTs) const override @@ -94,29 +116,34 @@ public: void SetTypeParameterTypes(ArenaVector &&typeParamTypes) { - typeParamTypes_ = std::move(typeParamTypes); + HISTORY_GET_OR_CREATE(typeParamTypes_) = std::move(typeParamTypes); } ArenaVector const &TypeParameterTypes() const { - return typeParamTypes_; + return HISTORY_GET(typeParamTypes_); } - [[nodiscard]] ArenaVector &Annotations() noexcept + [[nodiscard]] ArenaVector &TypeParamterTypesMutable() { - return annotations_; + return HISTORY_GET_OR_CREATE(typeParamTypes_); + } + + [[nodiscard]] ArenaVector &AnnotationsMutable() + { + return HISTORY_GET_OR_CREATE(annotations_); } [[nodiscard]] const ArenaVector &Annotations() const noexcept { - return annotations_; + return HISTORY_GET(annotations_); } void SetAnnotations(ArenaVector &&annotations) { - annotations_ = std::move(annotations); - for (AnnotationUsage *anno : annotations_) { - anno->SetParent(this); + HISTORY_GET_OR_CREATE(annotations_) = std::move(annotations); + for (auto annotation : Annotations()) { + annotation->SetParent(this); } } @@ -137,15 +164,21 @@ public: void CleanUp() override { AstNode::CleanUp(); - typeParamTypes_.clear(); + TypeParamterTypesMutable().clear(); } TSTypeAliasDeclaration *Construct(ArenaAllocator *allocator) override; void CopyTo(AstNode *other) const override; private: - bool RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const; friend class SizeOfNodeTest; + bool RegisterUnexportedForDeclGen(ir::SrcDumper *dumper) const; + + void SetId(Identifier *id) + { + HISTORY_SET(id_, id); + } + ArenaVector decorators_; ArenaVector annotations_; Identifier *id_; diff --git a/ets2panda/ir/ts/tsTypeLiteral.cpp b/ets2panda/ir/ts/tsTypeLiteral.cpp index 418d5aa34da..d13f7662cdb 100644 --- a/ets2panda/ir/ts/tsTypeLiteral.cpp +++ b/ets2panda/ir/ts/tsTypeLiteral.cpp @@ -34,12 +34,8 @@ void TSTypeLiteral::TransformChildren(const NodeTransformer &cb, std::string_vie it = transformedNode; } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSTypeLiteral::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsTypeOperator.cpp b/ets2panda/ir/ts/tsTypeOperator.cpp index 7e66c028434..2fa2ad26adb 100644 --- a/ets2panda/ir/ts/tsTypeOperator.cpp +++ b/ets2panda/ir/ts/tsTypeOperator.cpp @@ -28,12 +28,8 @@ void TSTypeOperator::TransformChildren(const NodeTransformer &cb, std::string_vi type_->SetTransformedNode(transformationName, transformedNode); type_ = static_cast(transformedNode); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSTypeOperator::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsTypeParameter.cpp b/ets2panda/ir/ts/tsTypeParameter.cpp index 88d4b088551..61930184002 100644 --- a/ets2panda/ir/ts/tsTypeParameter.cpp +++ b/ets2panda/ir/ts/tsTypeParameter.cpp @@ -27,42 +27,44 @@ namespace ark::es2panda::ir { void TSTypeParameter::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - if (auto *transformedNode = cb(name_); name_ != transformedNode) { - name_->SetTransformedNode(transformationName, transformedNode); - name_ = transformedNode->AsIdentifier(); + auto name = Name(); + if (auto *transformedNode = cb(name); name != transformedNode) { + name->SetTransformedNode(transformationName, transformedNode); + SetName(transformedNode->AsIdentifier()); } - if (constraint_ != nullptr) { - if (auto *transformedNode = cb(constraint_); constraint_ != transformedNode) { - constraint_->SetTransformedNode(transformationName, transformedNode); - constraint_ = static_cast(transformedNode); + auto constraint = Constraint(); + if (constraint != nullptr) { + if (auto *transformedNode = cb(constraint); constraint != transformedNode) { + constraint->SetTransformedNode(transformationName, transformedNode); + SetConstraint(static_cast(transformedNode)); } } - if (defaultType_ != nullptr) { - if (auto *transformedNode = cb(defaultType_); defaultType_ != transformedNode) { - defaultType_->SetTransformedNode(transformationName, transformedNode); - defaultType_ = static_cast(transformedNode); - } - } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); + auto defaultType = DefaultType(); + if (defaultType != nullptr) { + if (auto *transformedNode = cb(defaultType); defaultType != transformedNode) { + defaultType->SetTransformedNode(transformationName, transformedNode); + SetDefaultType(static_cast(transformedNode)); } } + + TransformAnnotations(cb, transformationName); } void TSTypeParameter::Iterate(const NodeTraverser &cb) const { - cb(name_); + auto name = HISTORY_GET(name_); + cb(name); - if (constraint_ != nullptr) { - cb(constraint_); + auto constraint = HISTORY_GET(constraint_); + if (constraint != nullptr) { + cb(constraint); } - if (defaultType_ != nullptr) { - cb(defaultType_); + auto defaultType = DefaultType(); + if (defaultType != nullptr) { + cb(defaultType); } for (auto *it : VectorIterationGuard(Annotations())) { cb(it); @@ -72,9 +74,9 @@ void TSTypeParameter::Iterate(const NodeTraverser &cb) const void TSTypeParameter::Dump(ir::AstDumper *dumper) const { dumper->Add({{"type", "TSTypeParameter"}, - {"name", name_}, - {"constraint", AstDumper::Optional(constraint_)}, - {"default", AstDumper::Optional(defaultType_)}, + {"name", Name()}, + {"constraint", AstDumper::Optional(Constraint())}, + {"default", AstDumper::Optional(DefaultType())}, {"in", AstDumper::Optional(IsIn())}, {"out", AstDumper::Optional(IsOut())}, {"annotations", AstDumper::Optional(Annotations())}}); @@ -92,15 +94,15 @@ void TSTypeParameter::Dump(ir::SrcDumper *dumper) const dumper->Add("out "); } - name_->Dump(dumper); + Name()->Dump(dumper); - if (defaultType_ != nullptr) { + if (DefaultType() != nullptr) { dumper->Add(" = "); - defaultType_->Dump(dumper); + DefaultType()->Dump(dumper); } - if (constraint_ != nullptr) { + if (Constraint() != nullptr) { dumper->Add(" extends "); - constraint_->Dump(dumper); + Constraint()->Dump(dumper); } } @@ -125,7 +127,7 @@ checker::VerifiedType TSTypeParameter::Check([[maybe_unused]] checker::ETSChecke TSTypeParameter *TSTypeParameter::Construct(ArenaAllocator *allocator) { - return allocator->New(nullptr, nullptr, nullptr, allocator); + return allocator->New(nullptr, nullptr, nullptr, allocator, history_); } void TSTypeParameter::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ts/tsTypeParameter.h b/ets2panda/ir/ts/tsTypeParameter.h index fff183fc3c4..b2a072d3a4d 100644 --- a/ets2panda/ir/ts/tsTypeParameter.h +++ b/ets2panda/ir/ts/tsTypeParameter.h @@ -31,6 +31,7 @@ public: constraint_(constraint), defaultType_(defaultType) { + EnableHistory(); } explicit TSTypeParameter(Identifier *name, TypeNode *constraint, TypeNode *defaultType, ModifierFlags flags, @@ -41,41 +42,56 @@ public: defaultType_(defaultType) { ES2PANDA_ASSERT(flags == ModifierFlags::NONE || flags == ModifierFlags::IN || flags == ModifierFlags::OUT); + EnableHistory(); + } + + explicit TSTypeParameter(Identifier *name, TypeNode *constraint, TypeNode *defaultType, + ArenaAllocator *const allocator, AstNodeHistory *history) + : AnnotationAllowed(AstNodeType::TS_TYPE_PARAMETER, allocator), + name_(name), + constraint_(constraint), + defaultType_(defaultType) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } const Identifier *Name() const { - return name_; + return HISTORY_GET(name_); } Identifier *Name() { - return name_; + return HISTORY_GET(name_); } TypeNode *Constraint() { - return constraint_; + return HISTORY_GET(constraint_); } const TypeNode *Constraint() const { - return constraint_; + return HISTORY_GET(constraint_); } void SetConstraint(TypeNode *constraint) { - constraint_ = constraint; + HISTORY_SET(constraint_, constraint); } TypeNode *DefaultType() const { - return defaultType_; + return HISTORY_GET(defaultType_); } void SetDefaultType(TypeNode *defaultType) { - defaultType_ = defaultType; + HISTORY_SET(defaultType_, defaultType); } void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; @@ -97,6 +113,11 @@ public: private: friend class SizeOfNodeTest; + void SetName(Identifier *name) + { + HISTORY_SET(name_, name); + } + Identifier *name_; TypeNode *constraint_; TypeNode *defaultType_; diff --git a/ets2panda/ir/ts/tsTypeParameterDeclaration.cpp b/ets2panda/ir/ts/tsTypeParameterDeclaration.cpp index a236ed060c7..e3a228103db 100644 --- a/ets2panda/ir/ts/tsTypeParameterDeclaration.cpp +++ b/ets2panda/ir/ts/tsTypeParameterDeclaration.cpp @@ -25,31 +25,33 @@ namespace ark::es2panda::ir { void TSTypeParameterDeclaration::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { - for (auto *&it : VectorIterationGuard(params_)) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsTSTypeParameter(); + auto ¶ms = Params(); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t ix = 0; ix < params.size(); ix++) { + if (auto *transformedNode = cb(params[ix]); params[ix] != transformedNode) { + params[ix]->SetTransformedNode(transformationName, transformedNode); + ParamsMutable()[ix] = transformedNode->AsTSTypeParameter(); } } } void TSTypeParameterDeclaration::Iterate(const NodeTraverser &cb) const { - for (auto *it : VectorIterationGuard(params_)) { + for (auto *it : VectorIterationGuard(Params())) { cb(it); } } void TSTypeParameterDeclaration::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", "TSTypeParameterDeclaration"}, {"params", params_}}); + dumper->Add({{"type", "TSTypeParameterDeclaration"}, {"params", Params()}}); } void TSTypeParameterDeclaration::Dump(ir::SrcDumper *dumper) const { - for (auto param : params_) { + for (auto param : Params()) { param->Dump(dumper); - if (param != params_.back()) { + if (param != Params().back()) { dumper->Add(", "); } } @@ -77,7 +79,7 @@ checker::VerifiedType TSTypeParameterDeclaration::Check([[maybe_unused]] checker TSTypeParameterDeclaration *TSTypeParameterDeclaration::Construct(ArenaAllocator *allocator) { ArenaVector params(allocator->Adapter()); - return allocator->New(std::move(params), 0); + return allocator->New(std::move(params), 0, history_); } void TSTypeParameterDeclaration::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ts/tsTypeParameterDeclaration.h b/ets2panda/ir/ts/tsTypeParameterDeclaration.h index 9fef5c44ff6..c3986013709 100644 --- a/ets2panda/ir/ts/tsTypeParameterDeclaration.h +++ b/ets2panda/ir/ts/tsTypeParameterDeclaration.h @@ -29,6 +29,20 @@ public: params_(std::move(params)), requiredParams_(requiredParams) { + EnableHistory(); + } + + explicit TSTypeParameterDeclaration(ArenaVector &¶ms, size_t requiredParams, + AstNodeHistory *history) + : Expression(AstNodeType::TS_TYPE_PARAMETER_DECLARATION), + params_(std::move(params)), + requiredParams_(requiredParams) + { + if (history != nullptr) { + history_ = history; + } else { + EnableHistory(); + } } [[nodiscard]] bool IsScopeBearer() const noexcept override @@ -38,35 +52,40 @@ public: [[nodiscard]] varbinder::LocalScope *Scope() const noexcept override { - return scope_; + return HISTORY_GET(scope_); } void SetScope(varbinder::LocalScope *scope) { - scope_ = scope; + HISTORY_SET(scope_, scope); } void ClearScope() noexcept override { - scope_ = nullptr; + SetScope(nullptr); } const ArenaVector &Params() const { - return params_; + return HISTORY_GET(params_); + } + + ArenaVector &ParamsMutable() + { + return HISTORY_GET_OR_CREATE(params_); } void AddParam(TSTypeParameter *param) { - if (requiredParams_ == params_.size() && param->DefaultType() == nullptr) { - requiredParams_++; + if (RequiredParams() == Params().size() && param->DefaultType() == nullptr) { + SetRequiredParams(RequiredParams() + 1); } - params_.push_back(param); + HISTORY_GET_OR_CREATE(params_).emplace_back(param); } size_t RequiredParams() const { - return requiredParams_; + return HISTORY_GET(requiredParams_); } void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; @@ -88,6 +107,11 @@ public: private: friend class SizeOfNodeTest; + void SetRequiredParams(size_t requiredParams) + { + HISTORY_SET(requiredParams_, requiredParams); + } + ArenaVector params_; varbinder::LocalScope *scope_ {nullptr}; size_t requiredParams_; diff --git a/ets2panda/ir/ts/tsTypePredicate.cpp b/ets2panda/ir/ts/tsTypePredicate.cpp index a1b253d850f..0ab2158429a 100644 --- a/ets2panda/ir/ts/tsTypePredicate.cpp +++ b/ets2panda/ir/ts/tsTypePredicate.cpp @@ -37,12 +37,8 @@ void TSTypePredicate::TransformChildren(const NodeTransformer &cb, std::string_v typeAnnotation_ = static_cast(transformedNode); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSTypePredicate::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsTypeQuery.cpp b/ets2panda/ir/ts/tsTypeQuery.cpp index 70fe7b63fc1..5fa24495e89 100644 --- a/ets2panda/ir/ts/tsTypeQuery.cpp +++ b/ets2panda/ir/ts/tsTypeQuery.cpp @@ -29,12 +29,8 @@ void TSTypeQuery::TransformChildren(const NodeTransformer &cb, std::string_view exprName_->SetTransformedNode(transformationName, transformedNode); exprName_ = transformedNode->AsExpression(); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSTypeQuery::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsTypeReference.cpp b/ets2panda/ir/ts/tsTypeReference.cpp index 459789b7185..57b8f7d2ae2 100644 --- a/ets2panda/ir/ts/tsTypeReference.cpp +++ b/ets2panda/ir/ts/tsTypeReference.cpp @@ -44,12 +44,8 @@ void TSTypeReference::TransformChildren(const NodeTransformer &cb, std::string_v typeName_->SetTransformedNode(transformationName, transformedNode); typeName_ = transformedNode->AsExpression(); } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSTypeReference::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsUndefinedKeyword.cpp b/ets2panda/ir/ts/tsUndefinedKeyword.cpp index 4070aaf0b20..5053cebca07 100644 --- a/ets2panda/ir/ts/tsUndefinedKeyword.cpp +++ b/ets2panda/ir/ts/tsUndefinedKeyword.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void TSUndefinedKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSUndefinedKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsUnionType.cpp b/ets2panda/ir/ts/tsUnionType.cpp index a25ccceccb5..aca8a8aa899 100644 --- a/ets2panda/ir/ts/tsUnionType.cpp +++ b/ets2panda/ir/ts/tsUnionType.cpp @@ -30,12 +30,8 @@ void TSUnionType::TransformChildren(const NodeTransformer &cb, std::string_view it = static_cast(transformedNode); } } - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + + TransformAnnotations(cb, transformationName); } void TSUnionType::Iterate(const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsUnknownKeyword.cpp b/ets2panda/ir/ts/tsUnknownKeyword.cpp index f1daafebdc2..dd0bc5e848c 100644 --- a/ets2panda/ir/ts/tsUnknownKeyword.cpp +++ b/ets2panda/ir/ts/tsUnknownKeyword.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void TSUnknownKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSUnknownKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/ts/tsVoidKeyword.cpp b/ets2panda/ir/ts/tsVoidKeyword.cpp index d5a4341f2c2..ff09cc56d86 100644 --- a/ets2panda/ir/ts/tsVoidKeyword.cpp +++ b/ets2panda/ir/ts/tsVoidKeyword.cpp @@ -25,12 +25,7 @@ namespace ark::es2panda::ir { void TSVoidKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb, [[maybe_unused]] std::string_view const transformationName) { - for (auto *&it : VectorIterationGuard(Annotations())) { - if (auto *transformedNode = cb(it); it != transformedNode) { - it->SetTransformedNode(transformationName, transformedNode); - it = transformedNode->AsAnnotationUsage(); - } - } + TransformAnnotations(cb, transformationName); } void TSVoidKeyword::Iterate([[maybe_unused]] const NodeTraverser &cb) const diff --git a/ets2panda/ir/typed.h b/ets2panda/ir/typed.h index 0c3f32f3ee4..88ced5bbce4 100644 --- a/ets2panda/ir/typed.h +++ b/ets2panda/ir/typed.h @@ -38,17 +38,18 @@ public: [[nodiscard]] checker::Type const *TsType() const { - return tsType_; + return HISTORY_GET(tsType_); } [[nodiscard]] checker::Type *TsType() { - return tsType_; + return HISTORY_GET(tsType_); } checker::Type *SetTsType(checker::Type *tsType) noexcept { - return (tsType_ = tsType); + HISTORY_SET(tsType_, tsType); + return tsType; } bool IsTyped() const override @@ -129,13 +130,13 @@ public: Typed::CopyTo(other); }; + inline static checker::Type *const CHECKED = reinterpret_cast(0x01); + protected: explicit TypedStatement(AstNodeType type) : Typed(type) {}; explicit TypedStatement(AstNodeType type, ModifierFlags flags) : Typed(type, flags) {}; TypedStatement(TypedStatement const &other) : Typed(static_cast const &>(other)) {} - - inline static checker::Type *const CHECKED = reinterpret_cast(0x01); }; class AnnotatedStatement : public Annotated { diff --git a/ets2panda/lexer/token/sourceLocation.h b/ets2panda/lexer/token/sourceLocation.h index a150a8cfb08..b6557e4d632 100644 --- a/ets2panda/lexer/token/sourceLocation.h +++ b/ets2panda/lexer/token/sourceLocation.h @@ -52,6 +52,11 @@ public: const parser::Program *Program() const; + bool operator!=(const SourcePosition &other) const + { + return index != other.index || line != other.line || program_ != other.program_; + } + private: const parser::Program *program_ {}; }; @@ -68,6 +73,11 @@ public: SourcePosition start {}; SourcePosition end {}; // NOLINTEND(misc-non-private-member-variables-in-classes) + + bool operator!=(const SourceRange &other) const + { + return start != other.start || end != other.end; + } }; class SourceLocation { diff --git a/ets2panda/parser/ETSparserNamespaces.cpp b/ets2panda/parser/ETSparserNamespaces.cpp index ea4a8feb4ba..0bc863658e3 100644 --- a/ets2panda/parser/ETSparserNamespaces.cpp +++ b/ets2panda/parser/ETSparserNamespaces.cpp @@ -82,7 +82,7 @@ ir::ETSModule *ETSParser::ParseNamespaceImp(ir::ModifierFlags flags) if ((flags & ir::ModifierFlags::DECLARE) != 0) { child->AddModifier(ir::ModifierFlags::DECLARE); } - parent->Statements().emplace_back(child); + parent->StatementsMutable().emplace_back(child); parent = child; } ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE); diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index 68c404993fe..20c586a690c 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -1032,7 +1032,7 @@ extern "C" void InsertETSImportDeclarationAndParse(es2panda_Context *context, es auto *importDeclE2p = reinterpret_cast(importDeclaration); importDeclE2p->AddAstNodeFlags(ir::AstNodeFlags::NOCLEANUP); - parserProgram->Ast()->Statements().insert(parserProgram->Ast()->Statements().begin(), importDeclE2p); + parserProgram->Ast()->StatementsMutable().insert(parserProgram->Ast()->StatementsMutable().begin(), importDeclE2p); importDeclE2p->SetParent(parserProgram->Ast()); ctx->parser->AsETSParser()->AddExternalSource(ctx->parser->AsETSParser()->ParseSources()); diff --git a/ets2panda/test/unit/lowerings/node_history.cpp b/ets2panda/test/unit/lowerings/node_history.cpp index c3b982aa63f..6525a1637d0 100644 --- a/ets2panda/test/unit/lowerings/node_history.cpp +++ b/ets2panda/test/unit/lowerings/node_history.cpp @@ -32,7 +32,7 @@ public: NodeHistoryTest() { allocator_ = std::make_unique(SpaceType::SPACE_TYPE_COMPILER); - phaseManager_ = std::make_unique(ScriptExtension::ETS, Allocator()); + phaseManager_ = std::make_unique(ScriptExtension::ETS, Allocator(), true); compiler::SetPhaseManager(phaseManager_.get()); } @@ -168,7 +168,7 @@ TEST_F(NodeHistoryTest, HistoryGet) auto identifier = Allocator()->New(Allocator())->AsIdentifier(); auto history = Allocator()->New(identifier, PhaseManager()->CurrentPhaseId(), Allocator()); - ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), identifier); ASSERT_EQ(history->Get(PHASE_ID_0), identifier); ASSERT_EQ(history->Get(PHASE_ID_1), identifier); ASSERT_EQ(history->Get(PHASE_ID_2), identifier); @@ -196,7 +196,7 @@ TEST_F(NodeHistoryTest, HistorySet) history->Set(nullptr, PhaseManager()->CurrentPhaseId()); // Search forward - ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), identifier0); ASSERT_EQ(history->Get(PHASE_ID_0), identifier0); ASSERT_EQ(history->Get(PHASE_ID_1), identifier1); ASSERT_EQ(history->Get(PHASE_ID_2), identifier2); @@ -211,7 +211,7 @@ TEST_F(NodeHistoryTest, HistorySet) ASSERT_EQ(history->Get(PHASE_ID_2), identifier2); ASSERT_EQ(history->Get(PHASE_ID_1), identifier1); ASSERT_EQ(history->Get(PHASE_ID_0), identifier0); - ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), identifier0); // Search random ASSERT_EQ(history->Get(PHASE_ID_1), identifier1); @@ -219,7 +219,7 @@ TEST_F(NodeHistoryTest, HistorySet) ASSERT_EQ(history->Get(PHASE_ID_2), identifier2); ASSERT_EQ(history->Get(PHASE_ID_4), nullptr); ASSERT_EQ(history->Get(PHASE_ID_0), identifier0); - ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), identifier0); ASSERT_EQ(history->Get(PHASE_ID_3), nullptr); // Search precise @@ -244,7 +244,7 @@ TEST_F(NodeHistoryTest, HistoryReplace) auto identifier1Orig = Allocator()->New(Allocator())->AsIdentifier(); history->Set(identifier1Orig, PhaseManager()->CurrentPhaseId()); - ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), identifier0Orig); ASSERT_EQ(history->Get(PHASE_ID_0), identifier0Orig); ASSERT_EQ(history->Get(PHASE_ID_1), identifier1Orig); ASSERT_EQ(history->Get(PHASE_ID_2), identifier1Orig); @@ -266,7 +266,7 @@ TEST_F(NodeHistoryTest, HistoryReplace) PhaseManager()->SetCurrentPhaseId(PHASE_ID_2); history->Set(nullptr, PhaseManager()->CurrentPhaseId()); - ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(compiler::PARSER_PHASE_ID), identifier0New); ASSERT_EQ(history->Get(PHASE_ID_0), identifier0New); ASSERT_EQ(history->Get(PHASE_ID_1), identifier1New); ASSERT_EQ(history->Get(PHASE_ID_2), nullptr); @@ -287,8 +287,7 @@ ir::ClassDefinition *NewClassDefinition(ArenaAllocator *allocator) ->AsClassDefinition(); } -/// NOTE(mivanov): To be enabled after #24153/#24424 implemented -TEST_F(NodeHistoryTest, DISABLED_UpdateField) +TEST_F(NodeHistoryTest, UpdateField) { ASSERT_EQ(PhaseManager()->CurrentPhaseId(), compiler::PARSER_PHASE_ID); @@ -332,8 +331,7 @@ TEST_F(NodeHistoryTest, DISABLED_UpdateField) ASSERT_FALSE(definition->IsFinal()); } -/// NOTE(mivanov): To be enabled after #24153/#24424 implemented -TEST_F(NodeHistoryTest, DISABLED_UpdateChild) +TEST_F(NodeHistoryTest, UpdateChild) { ASSERT_EQ(PhaseManager()->CurrentPhaseId(), compiler::PARSER_PHASE_ID); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_function_type_ir.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_function_type_ir.cpp index 703a978d794..89c0b5a4366 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_function_type_ir.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_function_type_ir.cpp @@ -27,7 +27,7 @@ es2panda_AstNode *CreateFunctionTypeIr(es2panda_Context *context, es2panda_AstNo { auto impl = GetImpl(); size_t sizeOfStatements = 0; - auto *statements = impl->BlockStatementStatements(context, program, &sizeOfStatements); + auto *statements = impl->BlockStatementStatementsConst(context, program, &sizeOfStatements); es2panda_AstNode **newStatements = static_cast(impl->AllocMemory(context, sizeOfStatements + 1, sizeof(es2panda_AstNode *))); for (size_t i = 0; i < sizeOfStatements; i++) { diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import.cpp index 2efc5c36d56..db97443a64f 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import.cpp @@ -61,11 +61,11 @@ es2panda_AstNode *GetTargetFunc(es2panda_Context *context, es2panda_AstNode *ast static constexpr size_t BLK_STMT_IDX = 3; static constexpr size_t CLASS_DEF_IDX = 2; size_t blockStmtNum = 0; - auto **blockStmt = g_impl->BlockStatementStatements(context, ast, &blockStmtNum); + auto **blockStmt = g_impl->BlockStatementStatementsConst(context, ast, &blockStmtNum); auto *etsGlobal = blockStmt[BLK_STMT_IDX]; auto *classDef = g_impl->ClassDeclarationDefinition(context, etsGlobal); size_t blockStmtNum2 = 0; - auto *classBody = g_impl->ClassDefinitionBody(context, classDef, &blockStmtNum2); + auto *classBody = g_impl->ClassDefinitionBodyConst(context, classDef, &blockStmtNum2); auto *fooMethod = classBody[CLASS_DEF_IDX]; auto *fooFunc = g_impl->MethodDefinitionFunction(context, fooMethod); @@ -133,7 +133,7 @@ bool Find(es2panda_AstNode *ast) { if (g_impl->IsETSImportDeclaration(ast)) { size_t len = 0; - auto specifiers = g_impl->ImportDeclarationSpecifiers(g_ctx, ast, &len); + auto specifiers = g_impl->ImportDeclarationSpecifiersConst(g_ctx, ast, &len); auto source = g_impl->ImportDeclarationSource(g_ctx, ast); auto importDeclaration = g_impl->UpdateETSImportDeclaration(g_ctx, ast, source, specifiers, len, IMPORT_KINDS_ALL); @@ -149,7 +149,7 @@ bool Find(es2panda_AstNode *ast) auto parent = g_impl->AstNodeParent(g_ctx, ast); if (g_impl->AstNodeIsProgramConst(g_ctx, parent)) { size_t sizeOfStatements = 0; - auto *statements = g_impl->BlockStatementStatements(g_ctx, parent, &sizeOfStatements); + auto *statements = g_impl->BlockStatementStatementsConst(g_ctx, parent, &sizeOfStatements); statements[0] = importDeclaration; g_impl->BlockStatementSetStatements(g_ctx, parent, statements, sizeOfStatements); g_impl->AstNodeSetParent(g_ctx, importDeclaration, parent); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import_declaration.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import_declaration.cpp index 2325b13e342..541ae638b47 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import_declaration.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import_declaration.cpp @@ -29,7 +29,7 @@ * - AstNodeDumpJSONConst * - AstNodeSetParent * - BlockStatementSetStatements - * - BlockStatementStatements + * - BlockStatementStatementsConst * - ContextProgram * - ContextState * - CreateConfig @@ -61,7 +61,7 @@ function main() { void CreateImportDeclaration(es2panda_Context *context) { size_t sizeOfStatements = 0; - auto *statements = impl->BlockStatementStatements(context, program, &sizeOfStatements); + auto *statements = impl->BlockStatementStatementsConst(context, program, &sizeOfStatements); const char *sourceName = "std/math"; auto *memForSource = static_cast(impl->AllocMemory(context, strlen(sourceName) + 1, 1)); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_non_null_expression.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_non_null_expression.cpp index 96e217a3b35..b54ca661830 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_non_null_expression.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_non_null_expression.cpp @@ -31,7 +31,7 @@ * - AstNodeRecheck * - AstNodeSetParent * - BlockStatementSetStatements - * - BlockStatementStatements + * - BlockStatementStatementsConst * - ContextProgram * - ContextState * - CreateConfig @@ -85,7 +85,7 @@ void AppendStatement(es2panda_AstNode *blockStatement, es2panda_AstNode *stateme return; } size_t sizeOfStatements = 0; - auto *statements = impl->BlockStatementStatements(context, blockStatement, &sizeOfStatements); + auto *statements = impl->BlockStatementStatementsConst(context, blockStatement, &sizeOfStatements); if (!statements) { return; } diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_dynamic_class_recheck.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_dynamic_class_recheck.cpp index 4355b52e641..509e9c41a1c 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_dynamic_class_recheck.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_dynamic_class_recheck.cpp @@ -90,7 +90,7 @@ int main(int argc, char **argv) return NULLPTR_CONTEXT_ERROR_CODE; } size_t len; - auto **stmts = impl->BlockStatementStatements(context, ast, &len); + auto **stmts = impl->BlockStatementStatementsConst(context, ast, &len); auto *newStmts = static_cast(impl->AllocMemory(context, len + 1, sizeof(es2panda_AstNode *))); for (size_t idx = 0; idx < len; ++idx) { if (stmts[idx] != targetAfterCheck) { diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_import_declaration.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_import_declaration.cpp index 3cbc8d25db1..7d7f575528f 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_import_declaration.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_import_declaration.cpp @@ -35,7 +35,7 @@ void CheckForImportDeclaration(es2panda_AstNode *node, void *arg) return; } size_t n = 0; - auto specifiers = impl->ImportDeclarationSpecifiers(context, node, &n); + auto specifiers = impl->ImportDeclarationSpecifiersConst(context, node, &n); for (size_t i = 0; i < n; i++) { if (!impl->IsImportSpecifier(specifiers[i])) { std::cout << impl->IsImportSpecifier(specifiers[i]) << std::endl; diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_method_decl.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_method_decl.cpp index 5ad346d1bf3..e81a970973d 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_method_decl.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_method_decl.cpp @@ -111,7 +111,7 @@ static bool CheckMethodDecl(es2panda_Context *context, es2panda_AstNode *ident) std::cerr << "CANT FIND SCRIPT FUNC FROM DEF" << std::endl; return false; } - impl->ScriptFunctionParams(context, scriptFunc, &argsFuncSignature); + impl->ScriptFunctionParamsConst(context, scriptFunc, &argsFuncSignature); if (argsCallExpr != argsFuncSignature) { std::cerr << "FOUND INCORRECT METHOD DEFINITION" << std::endl; diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_function_to_arrow.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_function_to_arrow.cpp index 9aafdf4077e..4e06f6a93a4 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_function_to_arrow.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_function_to_arrow.cpp @@ -101,7 +101,7 @@ static es2panda_AstNode *CreateFunctionBody(es2panda_AstNode *scriptFunc) if (impl->IsBlockStatement(body)) { size_t stmtCount = 0; - auto **stmts = impl->BlockStatementStatements(ctx, body, &stmtCount); + auto **stmts = impl->BlockStatementStatementsConst(ctx, body, &stmtCount); if (stmts && stmtCount > 0 && impl->IsReturnStatement(stmts[0])) { auto *returnArg = impl->ReturnStatementArgument(ctx, stmts[0]); impl->ReturnStatementSetArgument(ctx, returnStmt, returnArg); @@ -119,7 +119,7 @@ static es2panda_AstNode *CreateFunctionBody(es2panda_AstNode *scriptFunc) static es2panda_FunctionSignature *CreateFunctionSignature(es2panda_AstNode *scriptFunc) { size_t paramCount = 0; - auto **params = impl->ScriptFunctionParams(ctx, scriptFunc, ¶mCount); + auto **params = impl->ScriptFunctionParamsConst(ctx, scriptFunc, ¶mCount); return impl->CreateFunctionSignature(ctx, nullptr, params, paramCount, nullptr, false); } @@ -173,7 +173,7 @@ es2panda_AstNode *CreateFunctionDeclaration(const char *name) } size_t paramCount = 0; - auto **params = impl->ScriptFunctionParams(ctx, scriptFunc, ¶mCount); + auto **params = impl->ScriptFunctionParamsConst(ctx, scriptFunc, ¶mCount); SetParentRelations(funcDecl, funcId, blockStmt, params, paramCount); return funcDecl; @@ -186,7 +186,7 @@ void ApplyArrowToFunctionTransformations(es2panda_AstNode *programNode) } size_t statementsCount = 0; - auto **statements = impl->BlockStatementStatements(ctx, programNode, &statementsCount); + auto **statements = impl->BlockStatementStatementsConst(ctx, programNode, &statementsCount); size_t newStatementsCount = statementsCount + arrowsToTransform.size(); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_run_verifier.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_run_verifier.cpp index 50ef1f7555e..83cdc3aa0fa 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_run_verifier.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_run_verifier.cpp @@ -111,7 +111,7 @@ static bool CheckVerifierOnChangedAst(es2panda_Context *context, es2panda_AstNod return false; } auto mainFuncBody = impl->ScriptFunctionBody(context, mainScriptFunc); - auto mainStatements = impl->BlockStatementStatements(context, mainFuncBody, &n); + auto mainStatements = impl->BlockStatementStatementsConst(context, mainFuncBody, &n); auto assertStatementTest = AssertStatementTest(context, mainStatements[1]); std::string className = std::string("b"); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_struct_declaration.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_struct_declaration.cpp index d2b534a64e6..e232cbba5f0 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_struct_declaration.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_struct_declaration.cpp @@ -30,7 +30,7 @@ struct A { }; void CreateStructDeclaration(es2panda_AstNode *program) { size_t sizeOfStatements = 0; - auto statements = g_impl->BlockStatementStatements(g_ctx, program, &sizeOfStatements); + auto statements = g_impl->BlockStatementStatementsConst(g_ctx, program, &sizeOfStatements); es2panda_AstNode **newStatements = static_cast(g_impl->AllocMemory(g_ctx, sizeOfStatements + 1, sizeof(es2panda_AstNode *))); for (size_t i = 0; i < sizeOfStatements; i++) { @@ -51,7 +51,7 @@ void CreateStructDeclaration(es2panda_AstNode *program) bool UpdateStructDeclaration(es2panda_AstNode *program) { size_t sizeOfStatements = 0; - auto statements = g_impl->BlockStatementStatements(g_ctx, program, &sizeOfStatements); + auto statements = g_impl->BlockStatementStatementsConst(g_ctx, program, &sizeOfStatements); auto original = statements[sizeOfStatements - 1]; auto *identifier = g_impl->CreateIdentifier1(g_ctx, const_cast("C")); auto *classDefinition = g_impl->CreateClassDefinition1( diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_annotation_change.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_annotation_change.cpp index 31a2e3f7ddb..9b203d7f7c9 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_annotation_change.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_annotation_change.cpp @@ -57,7 +57,7 @@ static void CollectDeclarations(es2panda_AstNode *node) static es2panda_AstNode *GetAnnotationUsage(es2panda_Context *context, es2panda_AstNode *functionDecl) { size_t n; - auto **annotations = impl->ScriptFunctionAnnotations(context, functionDecl, &n); + auto **annotations = impl->ScriptFunctionAnnotationsConst(context, functionDecl, &n); if (n != 1) { return nullptr; } diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_class_decl_annotation.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_class_decl_annotation.cpp index 721f71e54be..7aee6eb9655 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_class_decl_annotation.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_class_decl_annotation.cpp @@ -57,7 +57,7 @@ bool TestClassAnnotation(es2panda_Context *context, es2panda_AstNode *ast) } size_t n; - auto **annotations = impl->ClassDefinitionAnnotations(context, classDef, &n); + auto **annotations = impl->ClassDefinitionAnnotationsConst(context, classDef, &n); if (annotations == nullptr || n != 1) { std::cerr << "ANNOTATION NOT FOUND" << n << std::endl; return false; diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_class.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_class.cpp index 5dccbe707c6..e70c59c8b89 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_class.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_class.cpp @@ -89,7 +89,7 @@ static es2panda_AstNode *FindBarMethod() { es2panda_AstNode *classDef = impl->ClassDeclarationDefinition(context, classDecl); size_t bodySize = 0; - es2panda_AstNode **body = impl->ClassDefinitionBody(context, classDef, &bodySize); + es2panda_AstNode **body = impl->ClassDefinitionBodyConst(context, classDef, &bodySize); for (size_t i = 0; i < bodySize; i++) { es2panda_AstNode *methodDef = body[i]; es2panda_AstNode *key = impl->ClassElementKey(context, methodDef); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_function_declaration.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_function_declaration.cpp index 29507dc4ff0..d6474c2c583 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_function_declaration.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_function_declaration.cpp @@ -38,7 +38,7 @@ void FindFunctionDeclaration(es2panda_AstNode *ast) if (g_impl->IsFunctionDeclaration(ast)) { auto scriptFunc = g_impl->FunctionDeclarationFunction(g_ctx, ast); size_t len = 0; - auto params = g_impl->ScriptFunctionParams(g_ctx, scriptFunc, &len); + auto params = g_impl->ScriptFunctionParamsConst(g_ctx, scriptFunc, &len); auto typeParams = g_impl->ScriptFunctionTypeParams(g_ctx, scriptFunc); auto returnType = g_impl->ScriptFunctionReturnTypeAnnotation(g_ctx, scriptFunc); auto signature = g_impl->CreateFunctionSignature(g_ctx, typeParams, params, len, returnType, false); @@ -48,7 +48,7 @@ void FindFunctionDeclaration(es2panda_AstNode *ast) g_impl->ScriptFunctionSetIdent(g_ctx, newScriptFunc, name); auto funcDeclaration = g_impl->UpdateFunctionDeclaration(g_ctx, ast, newScriptFunc, nullptr, 0, false); auto parent = g_impl->AstNodeParent(g_ctx, ast); - auto statements = g_impl->BlockStatementStatements(g_ctx, parent, &len); + auto statements = g_impl->BlockStatementStatementsConst(g_ctx, parent, &len); const size_t position = 2; statements[position] = funcDeclaration; g_impl->AstNodeSetParent(g_ctx, scriptFunc, body); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_declaration.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_declaration.cpp index ae305d87f8a..ed22a233e00 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_declaration.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_declaration.cpp @@ -29,7 +29,7 @@ * - AstNodeDumpJSONConst * - AstNodeSetParent * - BlockStatementSetStatements - * - BlockStatementStatements + * - BlockStatementStatementsConst * - ContextProgram * - ContextState * - CreateConfig @@ -59,7 +59,7 @@ import { PI as PI } from "std/math" bool UpdateImportDeclaration(es2panda_Context *context) { size_t sizeOfStatements = 0; - auto *statements = impl->BlockStatementStatements(context, program, &sizeOfStatements); + auto *statements = impl->BlockStatementStatementsConst(context, program, &sizeOfStatements); auto *importNode = statements[0]; const char *sourceName = "new/std/math"; diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_specifier.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_specifier.cpp index 5fe297f03c4..6bd5f439242 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_specifier.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_specifier.cpp @@ -29,7 +29,7 @@ * - AstNodeDumpJSONConst * - AstNodeSetParent * - BlockStatementSetStatements - * - BlockStatementStatements + * - BlockStatementStatementsConst * - ContextProgram * - ContextState * - CreateConfig @@ -63,7 +63,7 @@ import { PI as PI } from "std/math" void UpdateImportSpecifier(es2panda_Context *context) { size_t sizeOfStatements = 0; - auto *statements = impl->BlockStatementStatements(context, program, &sizeOfStatements); + auto *statements = impl->BlockStatementStatementsConst(context, program, &sizeOfStatements); auto *importNode = statements[0]; const char *identifierName = "E"; diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_statements.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_statements.cpp index 65437f6c97e..ad402e48a18 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_statements.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_statements.cpp @@ -31,7 +31,7 @@ void createClassDeclaration(es2panda_Context *context, char *className, es2panda { impl = GetImpl(); size_t sizeOfStatements = 0; - auto *statements = impl->BlockStatementStatements(context, program, &sizeOfStatements); + auto *statements = impl->BlockStatementStatementsConst(context, program, &sizeOfStatements); es2panda_AstNode **newStatements = static_cast(impl->AllocMemory(context, sizeOfStatements + 1, sizeof(es2panda_AstNode *))); for (size_t i = 0; i < sizeOfStatements; i++) { diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_statements_lambda.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_statements_lambda.cpp index eaae54580ce..cbe2ab723fc 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_statements_lambda.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_statements_lambda.cpp @@ -62,7 +62,7 @@ int main(int argc, char **argv) std::cout << impl->IsETSModule(programNode) << std::endl; std::size_t n = 0; - es2panda_AstNode **statements = impl->BlockStatementStatements(context, programNode, &n); + es2panda_AstNode **statements = impl->BlockStatementStatementsConst(context, programNode, &n); auto *expression = impl->ExpressionStatementGetExpression(context, statements[1]); diff --git a/ets2panda/test/unit/plugin/util.cpp b/ets2panda/test/unit/plugin/util.cpp index e5709c5b75b..60ab657775c 100644 --- a/ets2panda/test/unit/plugin/util.cpp +++ b/ets2panda/test/unit/plugin/util.cpp @@ -75,7 +75,7 @@ void AppendStatementToProgram(es2panda_Context *context, es2panda_AstNode *progr { auto impl = GetImpl(); size_t sizeOfStatements = 0; - auto *statements = impl->BlockStatementStatements(context, program, &sizeOfStatements); + auto *statements = impl->BlockStatementStatementsConst(context, program, &sizeOfStatements); auto **newStatements = static_cast(impl->AllocMemory(context, sizeOfStatements + 1, sizeof(es2panda_AstNode *))); for (size_t i = 0; i < sizeOfStatements; i++) { @@ -90,7 +90,7 @@ void PrependStatementToProgram(es2panda_Context *context, es2panda_AstNode *prog { auto impl = GetImpl(); size_t sizeOfStatements = 0; - auto *statements = impl->BlockStatementStatements(context, program, &sizeOfStatements); + auto *statements = impl->BlockStatementStatementsConst(context, program, &sizeOfStatements); auto **newStatements = static_cast(impl->AllocMemory(context, sizeOfStatements + 1, sizeof(es2panda_AstNode *))); for (size_t i = 0; i < sizeOfStatements; i++) { diff --git a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp index 35f7374b7b1..afa1b30625e 100644 --- a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp +++ b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp @@ -55,17 +55,18 @@ TEST_F(PluginConversionRuleUnitTest, ArenaVectorInputParameter) EXPECT_TRUE(HasMatched(targetAPIWithNoSpace)); } -/* [[nodiscard]] ArenaVector &Annotations() noexcept */ +/* [[nodiscard]] ArenaVector &AnnotationsMutable() noexcept */ /* ir::AnnotationAllowedPtrMethodCall */ TEST_F(PluginConversionRuleUnitTest, ArenaVectorReturnValue) { std::string targetCAPI {R"( - extern "C" es2panda_AstNode **AnnotationAllowedAnnotations([[maybe_unused]] es2panda_Context *context, + extern "C" es2panda_AstNode **AnnotationAllowedAnnotationsMutable([[maybe_unused]] es2panda_Context *context, es2panda_AstNode *classInstance/*return_args:*/, size_t *returnTypeLen) { auto *ctx = reinterpret_cast(context); auto *ctxAllocator = ctx->allocator; - auto resultVector = ((reinterpret_cast< ir::AnnotationAllowed *>(classInstance))->Annotations()); + auto resultVector = ((reinterpret_cast< ir::AnnotationAllowed *>(classInstance)) + ->AnnotationsMutable()); *returnTypeLen = resultVector.size(); auto apiRes = ctxAllocator->New(*returnTypeLen); for (size_t i = 0; i < *returnTypeLen; ++i) { diff --git a/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp b/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp index b8d0e496049..d70cad49644 100644 --- a/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp @@ -87,7 +87,7 @@ TEST_F(ASTVerifierTest, ValidateGetterHasReturnStatement) auto *const method = child->AsMethodDefinition(); if (method->IsGetter() && method->Value()->IsFunctionExpression()) { auto *const function = method->Value()->AsFunctionExpression()->Function(); - auto &returns = function->ReturnStatements(); + auto &returns = function->ReturnStatementsMutable(); returns.clear(); } } @@ -166,7 +166,7 @@ TEST_F(ASTVerifierTest, ValidateGetterArguments) auto *const method = child->AsMethodDefinition(); if (method->IsGetter() && method->Value()->IsFunctionExpression()) { auto *const function = method->Value()->AsFunctionExpression()->Function(); - auto ¶ms = function->Params(); + auto ¶ms = function->ParamsMutable(); ASSERT_EQ(params.size(), 0); params.push_back(param); } @@ -245,7 +245,7 @@ TEST_F(ASTVerifierTest, ValidateSetterArguments) auto *const method = child->AsMethodDefinition(); if (method->IsSetter() && method->Value()->IsFunctionExpression()) { auto *const function = method->Value()->AsFunctionExpression()->Function(); - auto ¶ms = function->Params(); + auto ¶ms = function->ParamsMutable(); ASSERT_EQ(params.size(), 1); params.clear(); } diff --git a/ets2panda/test/unit/sizeof_node_test.cpp b/ets2panda/test/unit/sizeof_node_test.cpp index 428a6010b7a..a8ef4c98ae9 100644 --- a/ets2panda/test/unit/sizeof_node_test.cpp +++ b/ets2panda/test/unit/sizeof_node_test.cpp @@ -16,8 +16,10 @@ #include "ir/base/classDefinition.h" #include "ir/base/classProperty.h" +#include "ir/base/classStaticBlock.h" #include "ir/base/methodDefinition.h" +#include "ir/ets/etsFunctionType.h" #include "ir/ets/etsModule.h" #include "ir/ets/etsReExportDeclaration.h" #include "ir/ets/etsStructDeclaration.h" @@ -69,6 +71,7 @@ size_t SizeOfNodeTest::SizeOf() sizeof(node->flags_) + sizeof(node->astNodeFlags_) + sizeof(node->boxingUnboxingFlags_) + + sizeof(node->history_) + sizeof(node->variable_) + sizeof(node->originalNode_) + sizeof(node->transformedNode_); @@ -638,6 +641,26 @@ size_t SizeOfNodeTest::SizeOf() // clang-format on } +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ETSFunctionType *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->scope_) + + Align(sizeof(node->signature_)) + + sizeof(node->functionalInterface_) + + Align(sizeof(node->funcFlags_)); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + return SizeOf(); +} + // NOLINTEND(bugprone-sizeof-container) TEST_F(SizeOfNodeTest, DeclNodesBase) @@ -717,5 +740,7 @@ TEST_F(SizeOfNodeTest, DeclNodesDerived) ASSERT_EQ(sizeof(ETSReExportDeclaration), SizeOf()); ASSERT_EQ(sizeof(ETSStructDeclaration), SizeOf()); ASSERT_EQ(sizeof(AnnotationDeclaration), SizeOf()); + ASSERT_EQ(sizeof(ETSFunctionType), SizeOf()); + ASSERT_EQ(sizeof(ClassStaticBlock), SizeOf()); } } // namespace ark::es2panda::ir diff --git a/ets2panda/test/utils/ast_verifier_test.cpp b/ets2panda/test/utils/ast_verifier_test.cpp index 96fc2c38f97..e0c97beff5d 100644 --- a/ets2panda/test/utils/ast_verifier_test.cpp +++ b/ets2panda/test/utils/ast_verifier_test.cpp @@ -14,6 +14,7 @@ */ #include "ast_verifier_test.h" +#include "compiler/lowering/phase.h" namespace test::utils { @@ -24,11 +25,13 @@ AstVerifierTest::AstVerifierTest() std::array argv = {es2pandaPath}; cfg_ = impl_->CreateConfig(argv.size(), argv.data()); allocator_ = new ark::ArenaAllocator(ark::SpaceType::SPACE_TYPE_COMPILER); + phaseManager_ = new ark::es2panda::compiler::PhaseManager(ark::es2panda::ScriptExtension::ETS, allocator_); } AstVerifierTest::~AstVerifierTest() { ASSERT(ctx_ == nullptr); + delete phaseManager_; delete allocator_; impl_->DestroyConfig(cfg_); } diff --git a/ets2panda/test/utils/ast_verifier_test.h b/ets2panda/test/utils/ast_verifier_test.h index 68ccb22ecb1..1d0d567162b 100644 --- a/ets2panda/test/utils/ast_verifier_test.h +++ b/ets2panda/test/utils/ast_verifier_test.h @@ -206,6 +206,7 @@ private: es2panda_Config *cfg_ {}; es2panda_Context *ctx_ {}; ark::ArenaAllocator *allocator_ {}; + ark::es2panda::compiler::PhaseManager *phaseManager_ {}; friend class ::LSPAPITests; }; diff --git a/ets2panda/test/utils/scope_init_test.h b/ets2panda/test/utils/scope_init_test.h index ce8df944bac..949e31eb93a 100644 --- a/ets2panda/test/utils/scope_init_test.h +++ b/ets2panda/test/utils/scope_init_test.h @@ -21,6 +21,7 @@ #include "ir/statements/variableDeclarator.h" #include "ir/statements/variableDeclaration.h" #include "mem/pool_manager.h" +#include "compiler/lowering/phase.h" #include @@ -30,7 +31,12 @@ namespace test::utils { class ScopeInitTest : public testing::Test { public: - ScopeInitTest() : allocator_(std::make_unique(ark::SpaceType::SPACE_TYPE_COMPILER)) {} + ScopeInitTest() : allocator_(std::make_unique(ark::SpaceType::SPACE_TYPE_COMPILER)) + { + phaseManager_ = std::make_unique(ark::es2panda::ScriptExtension::ETS, + allocator_.get()); + ark::es2panda::compiler::SetPhaseManager(phaseManager_.get()); + } /* * Shortcut to convert single elemnt block expression body to it's name @@ -51,6 +57,7 @@ public: private: std::unique_ptr allocator_; + std::unique_ptr phaseManager_; }; } // namespace test::utils diff --git a/ets2panda/util/enumbitops.h b/ets2panda/util/enumbitops.h index 46a95feeb13..f1ee69ab34b 100644 --- a/ets2panda/util/enumbitops.h +++ b/ets2panda/util/enumbitops.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -27,7 +27,9 @@ enumbitops::operator^, \ enumbitops::operator|=, \ enumbitops::operator&=, \ - enumbitops::operator^= + enumbitops::operator^=, \ + enumbitops::All, \ + enumbitops::Any // clang-format on namespace enumbitops { @@ -98,6 +100,20 @@ inline constexpr T &operator^=(T &a, T b) return a = a ^ b; } +template ::value, bool> = true> +inline constexpr bool All(T flags, T test) +{ + using Utype = std::underlying_type_t; + return (flags & test) == static_cast(test); +} + +template ::value, bool> = true> +inline constexpr bool Any(T flags, T test) +{ + using Utype = std::underlying_type_t; + return (flags & test) != static_cast(0); +} + } // namespace enumbitops #endif diff --git a/ets2panda/util/es2pandaMacros.h b/ets2panda/util/es2pandaMacros.h index cc0990c7b57..fa31a7f401f 100644 --- a/ets2panda/util/es2pandaMacros.h +++ b/ets2panda/util/es2pandaMacros.h @@ -18,6 +18,29 @@ #include "macros.h" #include "lexer/token/sourceLocation.h" + +// CC-OFFNXT(G.PRE.06, G.PRE.09) solid logic +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define HISTORY_GET(field) \ + AstNode::GetHistoryNodeAs::type>::type>() \ + ->field + +// CC-OFFNXT(G.PRE.06, G.PRE.09) solid logic +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define HISTORY_GET_OR_CREATE(field) \ + AstNode::GetOrCreateHistoryNodeAs< \ + typename std::remove_const::type>::type>() \ + ->field + +// CC-OFFNXT(G.PRE.06, G.PRE.09) solid logic +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define HISTORY_SET(field, value) \ + do { \ + if (HISTORY_GET(field) != (value)) { \ + HISTORY_GET_OR_CREATE(field) = (value); \ + } \ + } while (0) + namespace ark::es2panda::parser { class Program; } // namespace ark::es2panda::parser diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index 41e971809ed..405516472d5 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -303,8 +303,8 @@ const ir::ScriptFunction *Helpers::GetContainingConstructor(const ir::ClassPrope { for (const auto *parent = node->Parent(); parent != nullptr; parent = parent->Parent()) { if (parent->IsClassDefinition()) { - ES2PANDA_ASSERT(parent->AsClassDefinition()->Ctor() != nullptr); - return parent->AsClassDefinition()->Ctor()->Function(); + ES2PANDA_ASSERT(parent->AsClassDefinition()->CtorValue() != nullptr); + return parent->AsClassDefinition()->CtorValue()->Function(); } } diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 0f9ae6db10e..cf61575e75a 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -1208,7 +1208,7 @@ void ETSBinder::BuildProgram() ValidateReexports(); - auto &stmts = Program()->Ast()->Statements(); + auto &stmts = Program()->Ast()->StatementsMutable(); const auto etsGlobal = std::find_if(stmts.begin(), stmts.end(), [](const ir::Statement *stmt) { return stmt->IsClassDeclaration() && stmt->AsClassDeclaration()->Definition()->IsGlobal(); }); -- Gitee