/** * Copyright (c) 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "ir/base/classDefinition.h" #include "ir/base/classProperty.h" #include "ir/base/methodDefinition.h" #include "ir/ets/etsModule.h" #include "ir/ets/etsReExportDeclaration.h" #include "ir/ets/etsStructDeclaration.h" #include "ir/ets/etsTypeReference.h" #include "ir/ets/etsTypeReferencePart.h" #include "ir/expressions/functionExpression.h" #include "ir/module/importDeclaration.h" #include "ir/statements/annotationDeclaration.h" #include "ir/statements/classDeclaration.h" #include "ir/statements/functionDeclaration.h" #include "ir/statements/variableDeclaration.h" #include "ir/ts/tsEnumDeclaration.h" #include "ir/ts/tsInterfaceDeclaration.h" #include "ir/ts/tsTypeAliasDeclaration.h" #include "ir/ts/tsTypeParameter.h" #include "ir/ts/tsTypeParameterDeclaration.h" namespace ark::es2panda::ir { class SizeOfNodeTest : public testing::Test { public: template size_t SizeOf(); static size_t Align(size_t value) { constexpr size_t FIELD_ALIGNMENT = 8; return AlignUp(value, FIELD_ALIGNMENT); } }; // NOLINTBEGIN(bugprone-sizeof-container) template <> size_t SizeOfNodeTest::SizeOf() { constexpr size_t SIZE_OF_VTABLE = sizeof(void *); AstNode *node = nullptr; // clang-format off return SIZE_OF_VTABLE + sizeof(node->parent_) + sizeof(node->range_) + sizeof(node->type_) + sizeof(node->flags_) + sizeof(node->astNodeFlags_) + sizeof(node->boxingUnboxingFlags_) + sizeof(node->variable_) + sizeof(node->originalNode_) + sizeof(node->transformedNode_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>() { Typed *node = nullptr; // clang-format off return SizeOf() + sizeof(node->tsType_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { return SizeOf>(); } template <> size_t SizeOfNodeTest::SizeOf>() { AnnotationAllowed *node = nullptr; // clang-format off return SizeOf() + sizeof(node->annotations_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>>() { JsDocAllowed> *node = nullptr; // clang-format off return SizeOf>() + sizeof(node->jsDocInformation_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { ClassDefinition *node = nullptr; // clang-format off return SizeOf>>() + sizeof(node->scope_) + sizeof(node->internalName_) + sizeof(node->ident_) + sizeof(node->typeParams_) + sizeof(node->superTypeParams_) + sizeof(node->implements_) + sizeof(node->ctor_) + sizeof(node->superClass_) + sizeof(node->body_) + sizeof(node->modifiers_) + sizeof(node->lang_) + sizeof(node->capturedVars_) + sizeof(node->localVariableIsNeeded_) + sizeof(node->origEnumDecl_) + sizeof(node->anonClass_) + Align(sizeof(node->localIndex_)) + sizeof(node->localPrefix_) + sizeof(node->functionalReferenceReferencedMethod_) + sizeof(node->exportedClasses_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { return SizeOf(); } template <> size_t SizeOfNodeTest::SizeOf() { ClassDeclaration *node = nullptr; // clang-format off return SizeOf() + sizeof(node->def_) + sizeof(node->decorators_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>() { Typed *node = nullptr; // clang-format off return SizeOf() + sizeof(node->tsType_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { return SizeOf>(); } template <> size_t SizeOfNodeTest::SizeOf() { ClassElement *node = nullptr; // clang-format off return SizeOf() + sizeof(node->key_) + sizeof(node->value_) + sizeof(node->decorators_) + Align(sizeof(node->isComputed_)) + sizeof(node->enumMember_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>() { AnnotationAllowed *node = nullptr; // clang-format off return SizeOf() + sizeof(node->annotations_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>>() { JsDocAllowed> *node = nullptr; // clang-format off return SizeOf>() + sizeof(node->jsDocInformation_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { ClassProperty *node = nullptr; // clang-format off return SizeOf>>() + sizeof(node->typeAnnotation_) + Align(sizeof(node->isDefault_) + sizeof(node->needInitInStaticBlock_)); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { MethodDefinition *node = nullptr; // clang-format off return SizeOf() + Align(sizeof(node->isDefault_) + sizeof(node->kind_)) + sizeof(node->overloads_) + sizeof(node->baseOverloadMethod_) + sizeof(node->asyncPairMethod_) + sizeof(node->overloadInfo_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>() { AnnotationAllowed *node = nullptr; // clang-format off return SizeOf() + sizeof(node->annotations_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>>() { JsDocAllowed> *node = nullptr; // clang-format off return SizeOf>() + sizeof(node->jsDocInformation_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { ScriptFunction *node = nullptr; // clang-format off return SizeOf>>() + sizeof(node->id_) + Align(sizeof(node->irSignature_)) + sizeof(node->body_) + sizeof(node->scope_) + Align(sizeof(node->funcFlags_)) + sizeof(node->signature_) + sizeof(node->preferredReturnType_) + Align(sizeof(node->lang_)) + sizeof(node->returnStatements_) + sizeof(node->isolatedDeclGenInferType_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { ImportDeclaration *node = nullptr; // clang-format off return SizeOf() + sizeof(node->source_) + sizeof(node->specifiers_) + Align(sizeof(node->importKinds_)); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>() { AnnotationAllowed *node = nullptr; // clang-format off return SizeOf() + sizeof(node->annotations_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>>() { JsDocAllowed> *node = nullptr; // clang-format off return SizeOf>() + sizeof(node->jsDocInformation_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { FunctionDeclaration *node = nullptr; // clang-format off return SizeOf>>() + sizeof(node->decorators_) + sizeof(node->func_) + Align(sizeof(node->isAnonymous_)); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { TSEnumDeclaration *node = nullptr; // clang-format off return SizeOf() + sizeof(node->scope_) + sizeof(node->decorators_) + sizeof(node->key_) + sizeof(node->members_) + sizeof(node->internalName_) + sizeof(node->boxedClass_) + Align(sizeof(node->isConst_)); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>() { AnnotationAllowed *node = nullptr; // clang-format off return SizeOf() + sizeof(node->annotations_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>>() { JsDocAllowed> *node = nullptr; // clang-format off return SizeOf>() + sizeof(node->jsDocInformation_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { TSInterfaceDeclaration *node = nullptr; // clang-format off return SizeOf>>() + sizeof(node->decorators_) + sizeof(node->scope_) + sizeof(node->id_) + sizeof(node->typeParams_) + sizeof(node->body_) + sizeof(node->extends_) + sizeof(node->internalName_) + Align(sizeof(node->isStatic_) + sizeof(node->isExternal_) + sizeof(node->lang_)) + sizeof(node->anonClass_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>() { Annotated *node = nullptr; // clang-format off return SizeOf() + sizeof(node->typeAnnotation_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { return SizeOf>(); } template <> size_t SizeOfNodeTest::SizeOf>() { JsDocAllowed *node = nullptr; // clang-format off return SizeOf() + sizeof(node->jsDocInformation_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { TSTypeAliasDeclaration *node = nullptr; // clang-format off return SizeOf>() + sizeof(node->decorators_) + sizeof(node->annotations_) + sizeof(node->id_) + sizeof(node->typeParams_) + sizeof(node->typeParamTypes_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { Expression *node = nullptr; // clang-format off return SizeOf() + Align(sizeof(node->grouped_)); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>() { AnnotationAllowed *node = nullptr; // clang-format off return SizeOf() + sizeof(node->annotations_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { VariableDeclaration *node = nullptr; // clang-format off return SizeOf>>() + Align(sizeof(node->kind_) + sizeof(node->decorators_) + sizeof(node->declarators_)); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { ETSParameterExpression *node = nullptr; // clang-format off return SizeOf>() + sizeof(node->ident_) + sizeof(node->initializer_) + sizeof(node->spread_) + sizeof(node->savedLexer_) + sizeof(node->extraValue_) + Align(sizeof(node->isOptional_)); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { TSTypeParameter *node = nullptr; // clang-format off return SizeOf>() + sizeof(node->name_) + sizeof(node->constraint_) + sizeof(node->defaultType_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { TSTypeParameterDeclaration *node = nullptr; // clang-format off return SizeOf() + sizeof(node->params_) + sizeof(node->scope_) + sizeof(node->requiredParams_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { return SizeOf>(); } template <> size_t SizeOfNodeTest::SizeOf() { ETSTypeReference *node = nullptr; // clang-format off return SizeOf() + sizeof(node->part_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { ETSTypeReferencePart *node = nullptr; // clang-format off return SizeOf() + sizeof(node->name_) + sizeof(node->typeParams_) + sizeof(node->prev_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { BlockStatement *node = nullptr; // clang-format off return SizeOf() + sizeof(node->scope_) + sizeof(node->statements_) + sizeof(node->trailingBlocks_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>() { AnnotationAllowed *node = nullptr; // clang-format off return SizeOf() + sizeof(node->annotations_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf>>() { JsDocAllowed> *node = nullptr; // clang-format off return SizeOf>() + sizeof(node->jsDocInformation_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { ETSModule *node = nullptr; // clang-format off return SizeOf>>() + sizeof(node->ident_) + Align(sizeof(node->flag_)) + sizeof(node->program_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { FunctionExpression *node = nullptr; // clang-format off return SizeOf() + sizeof(node->func_) + sizeof(node->exprName_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { ETSReExportDeclaration *node = nullptr; // clang-format off return SizeOf() + sizeof(node->etsImportDeclarations_) + sizeof(node->userPaths_) + sizeof(node->programPath_); // clang-format on } template <> size_t SizeOfNodeTest::SizeOf() { return SizeOf(); } template <> size_t SizeOfNodeTest::SizeOf() { AnnotationDeclaration *node = nullptr; // clang-format off return SizeOf>() + sizeof(node->internalName_) + sizeof(node->scope_) + sizeof(node->expr_) + sizeof(node->properties_) + Align(sizeof(node->policy_)); // clang-format on } // NOLINTEND(bugprone-sizeof-container) TEST_F(SizeOfNodeTest, DeclNodesBase) { // IMPORTANT NOTICE: This test purpose is to warn a developer who modified fields of specific node classes. // Classes listed below implements CopyTo/Clone methods. // When you add a new field to a class, make sure you updated corresponding method. // Example: if you added new field to a ClassDefinition class, handle it in ClassDefinition::CopyTo/Clone. ASSERT_EQ(sizeof(AstNode), SizeOf()); ASSERT_EQ(sizeof(Typed), SizeOf>()); ASSERT_EQ(sizeof(TypedAstNode), SizeOf()); ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); ASSERT_EQ(sizeof(JsDocAllowed>), SizeOf>>()); ASSERT_EQ(sizeof(Statement), SizeOf()); ASSERT_EQ(sizeof(Typed), SizeOf>()); ASSERT_EQ(sizeof(TypedStatement), SizeOf()); ASSERT_EQ(sizeof(ClassElement), SizeOf()); ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); ASSERT_EQ(sizeof(JsDocAllowed>), SizeOf>>()); ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); ASSERT_EQ(sizeof(JsDocAllowed>), SizeOf>>()); ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); ASSERT_EQ(sizeof(JsDocAllowed>), SizeOf>>()); ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); ASSERT_EQ(sizeof(JsDocAllowed>), SizeOf>>()); // IMPORTANT NOTICE: This test purpose is to warn a developer who modified fields of specific node classes. // Classes listed below implements CopyTo/Clone methods. // When you add a new field to a class, make sure you updated corresponding method. // Example: if you added new field to a ClassDefinition class, handle it in ClassDefinition::CopyTo/Clone. ASSERT_EQ(sizeof(Annotated), SizeOf>()); ASSERT_EQ(sizeof(AnnotatedStatement), SizeOf()); ASSERT_EQ(sizeof(JsDocAllowed), SizeOf>()); ASSERT_EQ(sizeof(Expression), SizeOf()); ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); ASSERT_EQ(sizeof(TypeNode), SizeOf()); ASSERT_EQ(sizeof(BlockStatement), SizeOf()); ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); } TEST_F(SizeOfNodeTest, DeclNodesDerived) { // IMPORTANT NOTICE: This test purpose is to warn a developer who modified fields of specific node classes. // Classes listed below implements CopyTo/Clone methods. // When you add a new field to a class, make sure you updated corresponding method. // Example: if you added new field to a ClassDefinition class, handle it in ClassDefinition::CopyTo/Clone. ASSERT_EQ(sizeof(ClassDefinition), SizeOf()); ASSERT_EQ(sizeof(ClassDeclaration), SizeOf()); ASSERT_EQ(sizeof(ClassProperty), SizeOf()); ASSERT_EQ(sizeof(MethodDefinition), SizeOf()); ASSERT_EQ(sizeof(ScriptFunction), SizeOf()); ASSERT_EQ(sizeof(ImportDeclaration), SizeOf()); ASSERT_EQ(sizeof(FunctionDeclaration), SizeOf()); ASSERT_EQ(sizeof(TSEnumDeclaration), SizeOf()); ASSERT_EQ(sizeof(TSInterfaceDeclaration), SizeOf()); ASSERT_EQ(sizeof(TSTypeAliasDeclaration), SizeOf()); ASSERT_EQ(sizeof(VariableDeclaration), SizeOf()); // IMPORTANT NOTICE: This test purpose is to warn a developer who modified fields of specific node classes. // Classes listed below implements CopyTo/Clone methods. // When you add a new field to a class, make sure you updated corresponding method. // Example: if you added new field to a ClassDefinition class, handle it in ClassDefinition::CopyTo/Clone. ASSERT_EQ(sizeof(ETSParameterExpression), SizeOf()); ASSERT_EQ(sizeof(TSTypeParameter), SizeOf()); ASSERT_EQ(sizeof(TSTypeParameterDeclaration), SizeOf()); ASSERT_EQ(sizeof(ETSTypeReference), SizeOf()); ASSERT_EQ(sizeof(ETSTypeReferencePart), SizeOf()); ASSERT_EQ(sizeof(ETSModule), SizeOf()); ASSERT_EQ(sizeof(FunctionExpression), SizeOf()); ASSERT_EQ(sizeof(ETSReExportDeclaration), SizeOf()); ASSERT_EQ(sizeof(ETSStructDeclaration), SizeOf()); ASSERT_EQ(sizeof(AnnotationDeclaration), SizeOf()); } } // namespace ark::es2panda::ir