From b3be7886abf50cca86aa3326b746a5ceaa350ac7 Mon Sep 17 00:00:00 2001 From: berktiryakiler Date: Wed, 4 Jun 2025 09:17:24 +0300 Subject: [PATCH] Support 6.5.13 Constant to Enumeration Conversions Issue: [ArkTS] Support 6.5.13 Constant to Enumeration Conversions https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICA2A9 Signed-off-by: berktiryakiler --- ets2panda/checker/ETSchecker.h | 1 + ets2panda/checker/ets/arithmetic.cpp | 47 +++++++++ ets2panda/checker/ets/object.cpp | 69 +++++++++++++ ets2panda/checker/ets/typeCheckingHelpers.cpp | 9 +- ets2panda/checker/ets/typeCreation.cpp | 3 + ets2panda/checker/types/ets/etsEnumType.cpp | 98 ++++++++++++++++++- ets2panda/checker/types/ets/etsEnumType.h | 22 ++++- ets2panda/checker/types/ets/etsObjectType.h | 44 ++++++++- ets2panda/compiler/core/ETSGen.cpp | 2 + .../lowering/ets/enumPostCheckLowering.cpp | 70 +++++++++++++ .../lowering/ets/enumPostCheckLowering.h | 2 + ets2panda/ir/base/classProperty.cpp | 7 ++ 12 files changed, 366 insertions(+), 8 deletions(-) diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index bf9cd81c5f..92a96cfecd 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -207,6 +207,7 @@ public: Type *BuildBasicClassProperties(ir::ClassDefinition *classDef); ETSObjectType *BuildAnonymousClassProperties(ir::ClassDefinition *classDef, ETSObjectType *superType); Type *BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl); + Type *BuildBasicEnumProperties(ir::TSEnumDeclaration *enumDecl); ETSObjectType *GetSuperType(ETSObjectType *type); ArenaVector GetInterfaces(ETSObjectType *type); void GetInterfacesOfClass(ETSObjectType *type); diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index b0b3e32efd..57f91d6ca2 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -290,9 +290,56 @@ checker::Type *ETSChecker::CheckBinaryOperatorMulDivMod( return (tsType != nullptr) ? tsType : promotedType; } +static checker::Type *ResolveETSBuiltinTypeForIntEnums(ETSChecker *checker, const ETSObjectType *boxedType) +{ + if (boxedType->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE)) { + return checker->GlobalDoubleType(); + } + + if (boxedType->HasObjectFlag(ETSObjectFlags::BUILTIN_FLOAT)) { + return checker->GlobalFloatType(); + } + + if (boxedType->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG)) { + return checker->GlobalLongType(); + } + + if (boxedType->HasObjectFlag(ETSObjectFlags::BUILTIN_BIGINT)) { + return checker->GlobalETSBigIntType(); + } + + // Note: this rest numeric type need handled as int. + if (boxedType->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC) || + boxedType->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)) { + return checker->GlobalIntType(); + } + + if (boxedType->HasObjectFlag(ETSObjectFlags::BUILTIN_STRING) || + boxedType->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN)) { + return checker->CreateETSUnionType({checker->GlobalIntType(), const_cast(boxedType)}); + } + + if (boxedType->IsGlobalETSObjectType()) { + return const_cast(boxedType); + } + return nullptr; +} + checker::Type *ETSChecker::CheckBinaryOperatorForIntEnums(const checker::Type *const leftType, const checker::Type *const rightType) { + if (!leftType->IsETSEnumType() && !rightType->IsETSEnumType()) { + return nullptr; + } + + if (leftType->IsETSIntEnumType() && rightType->IsETSIntEnumType()) { + return GlobalIntType(); + } + + auto nonEnumType = rightType->IsETSEnumType() ? leftType : rightType; + if (nonEnumType->IsETSObjectType()) { + return ResolveETSBuiltinTypeForIntEnums(this, nonEnumType->AsETSObjectType()); + } if (leftType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && rightType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { if (leftType->IsETSIntEnumType() && rightType->IsETSIntEnumType()) { diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index cbf729d09f..74b319ae2b 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -425,6 +425,75 @@ void ETSChecker::CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type type->AddObjectFlag(ETSObjectFlags::INCOMPLETE_INSTANTIATION); } +Type *ETSChecker::BuildBasicEnumProperties(ir::TSEnumDeclaration *enumDecl) +{ + auto *var = enumDecl->Key()->Variable(); + if (var == nullptr) { + ES2PANDA_ASSERT(IsAnyError()); + return GlobalTypeError(); + } + + checker::ETSObjectType *enumType {}; + if (var->TsType() == nullptr) { + enumType = CreateETSObjectTypeOrBuiltin(enumDecl, + checker::ETSObjectFlags::ENUM | checker::ETSObjectFlags::VALUE_TYPED); + enumType->SetVariable(var); + var->SetTsType(enumType); + } else { + enumType = var->TsType()->AsETSObjectType(); + } + + enumDecl->SetTsType(enumType); + if (enumDecl->Members().empty()) { + return enumType; + } + + int64_t currentValue = 0; + for (auto *member : enumDecl->Members()) { + + // Ensure member has a variable + if (member->Variable() == nullptr) { + auto *memberVar = ProgramAllocator()->New(member->AsTSEnumMember()->Key()->AsIdentifier()->Name()); + memberVar->BindNode(member); + auto *localVar = ProgramAllocator()->New(memberVar, varbinder::VariableFlags::ENUM_LITERAL); + member->SetVariable(localVar); + } + + Type *memberType = nullptr; + if (member->AsTSEnumMember()->Init() != nullptr) { + auto initType = member->AsTSEnumMember()->Init()->Check(this); + if (!initType->IsTypeError()) { + memberType = initType; + // Update currentValue based on the initialization + if (initType->HasTypeFlag(TypeFlag::CONSTANT)) { + currentValue = ExtractNumericValue(initType).GetInt(); + } + } + } else { + memberType = CreateIntType(currentValue); + } + + if (memberType != nullptr) { + member->Variable()->SetTsType(memberType); + enumType->AddProperty(member->Variable()->AsLocalVariable()); + + // Set the enum type as a numeric type + enumType->AddTypeFlag(TypeFlag::ETS_INT_ENUM); + enumType->AddObjectFlag(ETSObjectFlags::ENUM_OBJECT); + enumType->AddTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); + + // Set the member type as numeric + memberType->AddTypeFlag(TypeFlag::ETS_NUMERIC); + memberType->AddTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); + + } + + currentValue++; + } + + return enumType; +} + Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl) { auto *var = interfaceDecl->Id()->Variable(); diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 1fa0493279..2059ef0f6c 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -513,26 +513,25 @@ Type *ETSChecker::GetTypeFromVariableDeclaration(varbinder::Variable *const var) variableType = GetTypeFromVarLikeVariableDeclaration(this, var); break; } - case varbinder::DeclType::FUNC: [[fallthrough]]; case varbinder::DeclType::IMPORT: variableType = var->Declaration()->Node()->Check(this); break; - case varbinder::DeclType::TYPE_ALIAS: variableType = GetTypeFromTypeAliasReference(var); break; - case varbinder::DeclType::INTERFACE: variableType = BuildBasicInterfaceProperties(var->Declaration()->Node()->AsTSInterfaceDeclaration()); break; - + case varbinder::DeclType::ENUM_LITERAL: { + variableType = BuildBasicEnumProperties(var->Declaration()->Node()->AsTSEnumDeclaration()); + break; + } case varbinder::DeclType::ANNOTATIONUSAGE: [[fallthrough]]; case varbinder::DeclType::ANNOTATIONDECL: break; - default: ES2PANDA_ASSERT(IsAnyError()); break; diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index 53b6838523..f2fa360e54 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -281,6 +281,9 @@ static std::pair GetObjectTypeDeclNames(ir:: if (node->IsTSInterfaceDeclaration()) { return {node->AsTSInterfaceDeclaration()->Id()->Name(), node->AsTSInterfaceDeclaration()->InternalName()}; } + if (node->IsTSEnumDeclaration()) { + return {node->AsTSEnumDeclaration()->Key()->Name(), node->AsTSEnumDeclaration()->InternalName()}; + } return {node->AsAnnotationDeclaration()->GetBaseName()->Name(), node->AsAnnotationDeclaration()->InternalName()}; } diff --git a/ets2panda/checker/types/ets/etsEnumType.cpp b/ets2panda/checker/types/ets/etsEnumType.cpp index 61d23b7cbf..ba688a0ba0 100644 --- a/ets2panda/checker/types/ets/etsEnumType.cpp +++ b/ets2panda/checker/types/ets/etsEnumType.cpp @@ -17,6 +17,14 @@ #include "checker/ets/conversion.h" #include "checker/types/ets/etsUnionType.h" +#include "checker/types/ets/types.h" +#include "checker/ETSchecker.h" +#include "ir/expressions/literals/numberLiteral.h" +#include "ir/expressions/literals/stringLiteral.h" +#include "ir/ts/tsEnumMember.h" +#include "varbinder/declaration.h" +#include "varbinder/variable.h" +#include "util/helpers.h" namespace ark::es2panda::checker { @@ -45,6 +53,21 @@ bool ETSStringEnumType::AssignmentSource(TypeRelation *relation, Type *target) void ETSStringEnumType::AssignmentTarget(TypeRelation *relation, Type *source) { + // Supporting Constant to enumeration conversion + if (source->IsStringType()) { + relation->GetNode()->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_ENUM); + // For later lowering purpose. + auto variable = relation->GetNode()->Variable(); + if (variable) { + variable->SetTsType(this->Variable()->TsType()); + } else { + variable = this->Variable(); + } + relation->GetNode()->SetVariable(variable); + relation->Result(true); + return; + } + relation->IsIdenticalTo(this, source) ? relation->Result(true) : relation->Result(false); } @@ -70,12 +93,27 @@ void ETSStringEnumType::CastTarget(TypeRelation *relation, Type *source) conversion::Forbidden(relation); } +ir::TSEnumMember *ETSStringEnumType::LookupConstant(Type *type) +{ + if (!type->IsETSStringType()) { + return nullptr; + } + const auto &members = EnumDecl()->Members(); + auto memberIt = std::find_if(members.begin(), members.end(), [type](const ir::AstNode *const node) { + return node->AsTSEnumMember()->Init()->AsStringLiteral()->Str() == type->AsETSStringType()->GetValue(); + }); + if (memberIt != members.end()) { + return (*memberIt)->AsTSEnumMember(); + } + return nullptr; +} + bool ETSIntEnumType::AssignmentSource(TypeRelation *relation, Type *target) { bool result = false; if (target->IsETSObjectType()) { if (target->AsETSObjectType()->IsGlobalETSObjectType() || - target->AsETSObjectType()->Name() == compiler::Signatures::NUMERIC) { + target->HasTypeFlag(TypeFlag::ETS_NUMERIC)) { result = true; } else if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC)) { result = true; @@ -99,6 +137,49 @@ bool ETSIntEnumType::AssignmentSource(TypeRelation *relation, Type *target) void ETSIntEnumType::AssignmentTarget(TypeRelation *relation, Type *source) { + // Supporting Constant to enumeration conversion + if (source->IsIntType()) { + relation->GetNode()->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_ENUM); + + // Lookup the enum member for this integer value + auto *member = LookupConstant(source); + if (member != nullptr) { + + // Get the member's type + auto *memberVar = member->Variable(); + if (memberVar == nullptr) { + // Create a new variable for the member if it doesn't exist + auto *newVar = relation->GetChecker()->ProgramAllocator()->New( + relation->GetChecker()->ProgramAllocator()->New(member->Key()->AsIdentifier()->Name()), + varbinder::VariableFlags::ENUM_LITERAL); + newVar->SetTsType(this); + member->SetVariable(newVar); + memberVar = newVar; + } + + // Set the variable type to the member's type + auto variable = relation->GetNode()->Variable(); + if (variable) { + variable->SetTsType(this); + relation->GetNode()->SetVariable(memberVar); + } + + // Add object flags instead of numeric flags + this->AddObjectFlag(ETSObjectFlags::ENUM_OBJECT); + + // Set the type of the node to this enum type + relation->GetNode()->SetTsType(this); + + // Set the type of the member variable to this enum type + memberVar->SetTsType(this); + + // Set the type of the member's key to this enum type + if (member->Key() != nullptr) { + member->Key()->SetTsType(this); + } + } + } + relation->IsIdenticalTo(this, source) ? relation->Result(true) : relation->Result(false); } @@ -129,4 +210,19 @@ void ETSIntEnumType::CastTarget(TypeRelation *relation, Type *source) conversion::Forbidden(relation); } +ir::TSEnumMember *ETSIntEnumType::LookupConstant(Type *type) +{ + if (!type->IsIntType()) { + return nullptr; + } + const auto &members = EnumDecl()->Members(); + auto memberIt = std::find_if(members.begin(), members.end(), [type](const ir::AstNode *const node) { + return node->AsTSEnumMember()->Init()->AsNumberLiteral()->Number().GetInt() == type->AsIntType()->GetValue(); + }); + if (memberIt != members.end()) { + return (*memberIt)->AsTSEnumMember(); + } + return nullptr; +} + } // namespace ark::es2panda::checker \ No newline at end of file diff --git a/ets2panda/checker/types/ets/etsEnumType.h b/ets2panda/checker/types/ets/etsEnumType.h index 99e5b34528..60227673c0 100644 --- a/ets2panda/checker/types/ets/etsEnumType.h +++ b/ets2panda/checker/types/ets/etsEnumType.h @@ -19,6 +19,10 @@ #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/etsObjectTypeConstants.h" #include "checker/types/typeFlag.h" +#include "ir/expressions/memberExpression.h" +#include "ir/ts/tsEnumDeclaration.h" +#include "ir/ts/tsEnumMember.h" +#include "util/ustring.h" namespace ark::es2panda::checker { @@ -27,7 +31,8 @@ public: explicit ETSEnumType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView internalName, ir::AstNode *declNode, TypeRelation *relation) : ETSObjectType(allocator, name, internalName, - std::make_tuple(declNode, ETSObjectFlags::CLASS | ETSObjectFlags::ENUM_OBJECT, relation)) + std::make_tuple(declNode, ETSObjectFlags::CLASS | ETSObjectFlags::ENUM_OBJECT, relation)), + decl_(declNode->AsClassDefinition()->OrigEnumDecl()) { } @@ -45,6 +50,19 @@ public: static constexpr std::string_view const VALUES_METHOD_NAME {"values"}; static constexpr std::string_view const GET_ORDINAL_METHOD_NAME {"getOrdinal"}; static constexpr std::string_view const DOLLAR_GET_METHOD_NAME {"$_get"}; + + const ir::TSEnumDeclaration *EnumDecl() const + { + return decl_; + } + + virtual ir::TSEnumMember *LookupConstant([[maybe_unused]] Type *type) + { + return nullptr; + }; + +private: + const ir::TSEnumDeclaration *decl_; }; class ETSIntEnumType : public ETSEnumType { @@ -66,6 +84,7 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; void Cast(TypeRelation *relation, Type *target) override; void CastTarget(TypeRelation *relation, Type *source) override; + ir::TSEnumMember *LookupConstant(Type *type) override; }; class ETSStringEnumType : public ETSEnumType { @@ -87,6 +106,7 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; void Cast(TypeRelation *relation, Type *target) override; void CastTarget(TypeRelation *relation, Type *source) override; + ir::TSEnumMember *LookupConstant(Type *type) override; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 20e5811f3d..d8b00526e6 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -40,6 +40,7 @@ public: using InstantiationMap = ArenaUnorderedMap; using PropertyTraverser = std::function; using PropertyHolder = std::array(PropertyType::COUNT)>; + using EnumValueMap = ArenaUnorderedMap; explicit ETSObjectType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView internalName, ir::AstNode *declNode, ETSObjectFlags flags) @@ -271,6 +272,11 @@ public: return (flags_ & flag) != 0; } + void AddTypeFlag(TypeFlag flag) + { + Type::AddTypeFlag(flag); + } + ETSFunctionType *GetFunctionalInterfaceInvokeType() const; ETSObjectFlags BuiltInKind() const @@ -405,10 +411,42 @@ public: return propertiesInstantiated_; } + void SetEnumValueMap(EnumValueMap &&map) + { + enumValueMap_ = std::move(map); + } + + const EnumValueMap &GetEnumValueMap() const + { + return enumValueMap_; + } + protected: virtual ETSFunctionType *CreateMethodTypeForProp(const util::StringView &name) const; private: + ArenaAllocator *const allocator_; + util::StringView const name_; + util::StringView const internalName_; + ir::AstNode *const declNode_; + ArenaVector interfaces_; + ArenaVector reExports_; + ArenaMap reExportAlias_; + ETSObjectFlags flags_; + InstantiationMap instantiationMap_; + ArenaVector typeArguments_; + ETSObjectType *superType_ {}; + ETSObjectType *enclosingType_ {}; + ETSObjectType *baseType_ {}; + + // for lazy properties instantiation + TypeRelation *relation_ = nullptr; + const Substitution *effectiveSubstitution_ = nullptr; + mutable bool propertiesInstantiated_ = false; + mutable ArenaVector constructSignatures_; + mutable PropertyHolder properties_; + mutable EnumValueMap enumValueMap_; + template explicit ETSObjectType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView assemblerName, std::tuple info, @@ -425,7 +463,8 @@ private: typeArguments_(allocator->Adapter()), relation_(std::get(info)), constructSignatures_(allocator->Adapter()), - properties_ {(void(IS), PropertyMap {allocator->Adapter()})...} + properties_ {(void(IS), PropertyMap {allocator->Adapter()})...}, + enumValueMap_(allocator->Adapter()) { } @@ -458,6 +497,7 @@ private: bool TryCastUnboxable(TypeRelation *const relation, Type *const target); ir::TSTypeParameterDeclaration *GetTypeParams() const; +<<<<<<< Updated upstream ThreadSafeArenaAllocator *const allocator_; util::StringView const name_; @@ -478,6 +518,8 @@ private: mutable bool propertiesInstantiated_ = false; mutable ArenaVector constructSignatures_; mutable PropertyHolder properties_; +======= +>>>>>>> Stashed changes }; } // namespace ark::es2panda::checker diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 004427936c..e7801fe00d 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -1265,6 +1265,8 @@ void ETSGen::EmitBoxingConversion(ir::BoxingUnboxingFlags boxingFlag, const ir:: case ir::BoxingUnboxingFlags::BOX_TO_DOUBLE: callBox(Signatures::BUILTIN_DOUBLE_VALUE_OF, Checker()->GlobalDoubleType()); return; + case ir::BoxingUnboxingFlags::BOX_TO_ENUM: + return; default: ES2PANDA_UNREACHABLE(); } diff --git a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp index a46a63ea5e..e0640ebd38 100644 --- a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp @@ -362,6 +362,73 @@ ir::SwitchStatement *EnumPostCheckLoweringPhase::GenerateGetOrdinalCallForSwitch return node; } +ir::AstNode *EnumPostCheckLoweringPhase::TryBoxConstantToEnum(ir::AstNode *const node) +{ + + node->RemoveBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_ENUM); + + // Check if node has a variable + if (node->Variable() == nullptr) { + return node; + } + + // Check if variable has a type + if (node->Variable()->TsType() == nullptr) { + return node; + } + + + // Check if type is an enum type + if (!node->Variable()->TsType()->IsETSEnumType()) { + return node; + } + + checker::ETSEnumType *enumType = node->Variable()->TsType()->AsETSEnumType(); + + // Check if node is an expression and has a type + if (!node->IsExpression() || node->AsExpression()->TsType() == nullptr) { + return node; + } + + + ir::TSEnumMember *member = enumType->LookupConstant(node->AsExpression()->TsType()); + + if (member == nullptr) { + return node; + } + + // Check if member has a parent and key + if (member->Parent() == nullptr || member->Key() == nullptr) { + return node; + } + + auto *enumIdent = member->Parent()->AsTSEnumDeclaration()->Key()->Clone(checker_->Allocator(), nullptr); + auto *memberIdent = member->Key()->AsIdentifier()->Clone(checker_->Allocator(), nullptr); + + // Set parent for enumIdent and memberIdent + enumIdent->SetParent(node->Parent()); + memberIdent->SetParent(node->Parent()); + + auto *loweringResult = checker_->AllocNode( + enumIdent, memberIdent, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + + // Set parent and range for loweringResult + loweringResult->SetParent(node->Parent()); + loweringResult->SetRange(node->Range()); + + // Set original node and transformed node + loweringResult->SetOriginalNode(node); + node->SetTransformedNode("enum_boxing", loweringResult); + + // Set variable and type for loweringResult + loweringResult->SetVariable(node->Variable()); + loweringResult->SetTsType(node->Variable()->TsType()); + + CheckLoweredNode(varbinder_, checker_, loweringResult); + + return loweringResult; +} + bool EnumPostCheckLoweringPhase::PerformForModule(public_lib::Context *ctx, parser::Program *program) { if (program->Extension() != ScriptExtension::ETS) { @@ -392,6 +459,9 @@ bool EnumPostCheckLoweringPhase::PerformForModule(public_lib::Context *ctx, pars node->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); } } + if (node->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_ENUM)) { + return TryBoxConstantToEnum(node); + } if (node->HasAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF)) { return GenerateValueOfCall(node); } diff --git a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h index 35fbb2c8b9..54f5816135 100644 --- a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h +++ b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h @@ -17,6 +17,7 @@ #define ES2PANDA_COMPILER_ENUM_POST_CHECK_LOWERING_H #include "compiler/lowering/phase.h" +#include "ir/astNode.h" #include "ir/ts/tsAsExpression.h" namespace ark::es2panda::compiler { @@ -49,6 +50,7 @@ private: ir::Expression *HandleEnumTypeCasting(checker::Type *type, ir::Expression *expr, ir::TSAsExpression *tsAsExpr); ir::Expression *HandleUnionTypeForCalls(checker::ETSUnionType *unionType, ir::Expression *expr, ir::TSAsExpression *tsAsExpr, EnumCastType castType); + ir::AstNode *TryBoxConstantToEnum(ir::AstNode *const node); public_lib::Context *context_ {nullptr}; parser::ETSParser *parser_ {nullptr}; diff --git a/ets2panda/ir/base/classProperty.cpp b/ets2panda/ir/base/classProperty.cpp index 2bacec57d1..d85eac400a 100644 --- a/ets2panda/ir/base/classProperty.cpp +++ b/ets2panda/ir/base/classProperty.cpp @@ -44,11 +44,18 @@ void ClassProperty::TransformChildren(const NodeTransformer &cb, std::string_vie } } +<<<<<<< Updated upstream auto *value = Value(); if (value != nullptr) { if (auto *transformedNode = cb(value); value != transformedNode) { value->SetTransformedNode(transformationName, transformedNode); SetValue(transformedNode->AsExpression()); +======= + if (value_ != nullptr) { + if (auto *transformedNode = cb(value_); transformedNode && value_ != transformedNode) { + value_->SetTransformedNode(transformationName, transformedNode); + value_ = transformedNode->AsExpression(); +>>>>>>> Stashed changes } } -- Gitee