diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index 4ae9e1ced1713825df96021752e24d3edf3a1c15..94208024b13e021811361735181458a6aad36e7d 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -1223,6 +1223,7 @@ static varbinder::Variable *ResolveMemberExpressionProperty(ir::MemberExpression } auto decl = var->Declaration(); + varbinder::LocalScope *scope = nullptr; if (decl->IsClassDecl()) { // NOTE(gogabr) : for some reason, ETSGLOBAL points to class declaration instead of definition. auto *declNode = decl->AsClassDecl()->Node(); @@ -1232,15 +1233,16 @@ static varbinder::Variable *ResolveMemberExpressionProperty(ir::MemberExpression ES2PANDA_ASSERT(classDef != nullptr); // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - auto scope = classDef->Scope(); - auto option = var->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE_OR_ENUM) - ? varbinder::ResolveBindingOptions::STATIC_DECLARATION | - varbinder::ResolveBindingOptions::STATIC_VARIABLES - : varbinder::ResolveBindingOptions::DECLARATION | varbinder::ResolveBindingOptions::VARIABLES; - return scope->FindLocal(me->Property()->AsIdentifier()->Name(), option); + scope = classDef->Scope(); + } else if (decl->IsEnumDecl()) { + scope = decl->AsEnumDecl()->Node()->AsTSEnumDeclaration()->Scope(); + } else { + return nullptr; } - return nullptr; + auto option = + varbinder::ResolveBindingOptions::STATIC_DECLARATION | varbinder::ResolveBindingOptions::STATIC_VARIABLES; + return scope->FindLocal(me->Property()->AsIdentifier()->Name(), option); } static bool IsConstantExpression(ir::AstNode *expr) @@ -1281,6 +1283,18 @@ static bool IsConstantExpression(ir::AstNode *expr) !expr->IsAnyChild(isNotConstantExpression); } +static bool IsInTSEnumMemberInit(const ir::AstNode *n) +{ + auto enumMember = util::Helpers::FindAncestorGivenByType(n, ir::AstNodeType::TS_ENUM_MEMBER); + + if (enumMember == nullptr) { + return false; + } + + auto init = enumMember->AsTSEnumMember()->Init(); + return (init == n) || (init->FindChild([n](auto *child) { return child == n; }) != nullptr); +} + ir::AstNode *ConstantExpressionLowering::UnfoldResolvedReference(ir::AstNode *resolved, ir::AstNode *node) { ir::AstNode *resNode = nullptr; @@ -1296,6 +1310,12 @@ ir::AstNode *ConstantExpressionLowering::UnfoldResolvedReference(ir::AstNode *re resNode = init->Clone(context_->allocator, node->Parent()); resNode->SetRange(node->Range()); } + } else if (resolved->IsTSEnumMember() && IsInTSEnumMemberInit(node)) { + auto init = resolved->AsTSEnumMember()->Init(); + if (init != nullptr && IsConstantExpression(init)) { + resNode = init->Clone(context_->allocator, node->Parent()); + resNode->SetRange(node->Range()); + } } if (resNode != nullptr) { @@ -1325,12 +1345,6 @@ ir::AstNode *ConstantExpressionLowering::MaybeUnfoldMemberExpression(ir::MemberE return node; } - if (auto *const property = node->Property(); property->IsLiteral()) { - property->SetParent(node->Parent()); - property->SetRange(node->Range()); - return property; - } - auto resolved = ResolveMemberExpressionProperty(node); if (resolved == nullptr || !resolved->Declaration()->IsReadonlyDecl()) { return node; @@ -1341,7 +1355,8 @@ ir::AstNode *ConstantExpressionLowering::MaybeUnfoldMemberExpression(ir::MemberE ir::AstNode *ConstantExpressionLowering::MaybeUnfold(ir::AstNode *node) { ir::NodeTransformer handleMaybeUnfold = [this](ir::AstNode *const n) { - if (n->IsIdentifier()) { + if (n->IsIdentifier() && (!n->Parent()->IsMemberExpression() || n->Parent()->AsMemberExpression()->Kind() == + ir::MemberExpressionKind::ELEMENT_ACCESS)) { return MaybeUnfoldIdentifier(n->AsIdentifier()); } @@ -1397,7 +1412,6 @@ ir::AstNode *ConstantExpressionLowering::Fold(ir::AstNode *constantNode) } return node; }; - constantNode->TransformChildrenRecursivelyPostorder(handleFoldConstant, Name()); return TryToCorrectNumberOrCharLiteral(handleFoldConstant(constantNode), context_); }