diff --git a/es2panda/typescript/types/interfaceType.cpp b/es2panda/typescript/types/interfaceType.cpp index 63383ecfb8a9a6c09570f062ff9e5185b839c00a..b40e51671a3d0c96cc1790e1198b8326e3c1e800 100644 --- a/es2panda/typescript/types/interfaceType.cpp +++ b/es2panda/typescript/types/interfaceType.cpp @@ -43,20 +43,13 @@ void InterfaceType::ToString(std::stringstream &ss) const } } -void InterfaceType::Identical(TypeRelation *relation, Type *other) +bool InterfaceType::IsPropertiesIdentical(TypeRelation *relation, InterfaceType *other) { - if (!other->IsObjectType() || !other->AsObjectType()->IsInterfaceType()) { - return; - } - - InterfaceType *otherInterface = other->AsObjectType()->AsInterfaceType(); - const ArenaVector &targetProperties = Properties(); - const ArenaVector &sourceProperties = otherInterface->Properties(); - + const ArenaVector &sourceProperties = other->Properties(); if (targetProperties.size() != sourceProperties.size()) { relation->Result(false); - return; + return false; } for (auto *targetProp : targetProperties) { @@ -73,13 +66,52 @@ void InterfaceType::Identical(TypeRelation *relation, Type *other) }); if (!foundProp) { relation->Result(false); - return; + return false; + } + } + + return true; +} + +bool InterfaceType::IsIndexInfoIdentical(TypeRelation *relation, InterfaceType *other) +{ + IndexInfo *targetNumberInfo = NumberIndexInfo(); + IndexInfo *sourceNumberInfo = other->NumberIndexInfo(); + if ((targetNumberInfo && !sourceNumberInfo) || (!targetNumberInfo && sourceNumberInfo)) { + relation->Result(false); + return false; + } + + relation->IsIdenticalTo(targetNumberInfo, sourceNumberInfo); + + if (relation->IsTrue()) { + IndexInfo *targetStringInfo = StringIndexInfo(); + IndexInfo *sourceStringInfo = other->StringIndexInfo(); + + if ((targetStringInfo && !sourceStringInfo) || (!targetStringInfo && sourceStringInfo)) { + relation->Result(false); + return false; } + + relation->IsIdenticalTo(targetStringInfo, sourceStringInfo); + } + + return true; +} + +void InterfaceType::Identical(TypeRelation *relation, Type *other) +{ + if (!other->IsObjectType() || !other->AsObjectType()->IsInterfaceType()) { + return; + } + + InterfaceType *otherInterface = other->AsObjectType()->AsInterfaceType(); + if (!IsPropertiesIdentical(relation, otherInterface)) { + return; } const ArenaVector &targetCallSignatures = CallSignatures(); const ArenaVector &sourceCallSignatures = otherInterface->CallSignatures(); - if (targetCallSignatures.size() != sourceCallSignatures.size()) { relation->Result(false); return; @@ -92,7 +124,6 @@ void InterfaceType::Identical(TypeRelation *relation, Type *other) const ArenaVector &targetConstructSignatures = ConstructSignatures(); const ArenaVector &sourceConstructSignatures = otherInterface->ConstructSignatures(); - if (targetConstructSignatures.size() != sourceConstructSignatures.size()) { relation->Result(false); return; @@ -103,27 +134,9 @@ void InterfaceType::Identical(TypeRelation *relation, Type *other) return; } - IndexInfo *targetNumberInfo = NumberIndexInfo(); - IndexInfo *sourceNumberInfo = otherInterface->NumberIndexInfo(); - - if ((targetNumberInfo && !sourceNumberInfo) || (!targetNumberInfo && sourceNumberInfo)) { - relation->Result(false); + if (!IsIndexInfoIdentical(relation, otherInterface)) { return; } - - relation->IsIdenticalTo(targetNumberInfo, sourceNumberInfo); - - if (relation->IsTrue()) { - IndexInfo *targetStringInfo = StringIndexInfo(); - IndexInfo *sourceStringInfo = otherInterface->StringIndexInfo(); - - if ((targetStringInfo && !sourceStringInfo) || (!targetStringInfo && sourceStringInfo)) { - relation->Result(false); - return; - } - - relation->IsIdenticalTo(targetStringInfo, sourceStringInfo); - } } Type *InterfaceType::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) diff --git a/es2panda/typescript/types/interfaceType.h b/es2panda/typescript/types/interfaceType.h index 96cd88b5a8faa73cb2f3a6a0f252032ae5ae8a68..ebcad0bd7954986a0b73f09192ba06b88c644765 100644 --- a/es2panda/typescript/types/interfaceType.h +++ b/es2panda/typescript/types/interfaceType.h @@ -144,6 +144,9 @@ private: ArenaAllocator *allocator_; std::pair, size_t> mergedTypeParams_ {}; std::vector typeParamTypes_ {}; + + bool IsPropertiesIdentical(TypeRelation *relation, InterfaceType *other); + bool IsIndexInfoIdentical(TypeRelation *relation, InterfaceType *other); }; } // namespace panda::es2panda::checker diff --git a/es2panda/typescript/types/objectType.cpp b/es2panda/typescript/types/objectType.cpp index 7eb4d6d43f840bb110769a51b3dbbb6b5b8d91f2..f496b0c39c6fe3b1f9453d011327a6063acc303f 100644 --- a/es2panda/typescript/types/objectType.cpp +++ b/es2panda/typescript/types/objectType.cpp @@ -48,6 +48,42 @@ bool ObjectType::SignatureRelatedToSomeSignature(TypeRelation *relation, Signatu return false; } +bool ObjectType::IsPropertiesIdentical(TypeRelation *relation, ObjectType *otherObj) +{ + for (auto *it : desc_->properties) { + binder::LocalVariable *found = otherObj->Desc()->FindProperty(it->Name()); + if (!found) { + relation->Result(false); + return false; + } + + relation->IsIdenticalTo(it->TsType(), found->TsType()); + + if (!relation->IsTrue()) { + return false; + } + + if (it->Flags() != found->Flags()) { + relation->Result(false); + return false; + } + } + + return true; +} + +bool ObjectType::IsIndexInfosIdentical(TypeRelation *relation, IndexInfo *descIndexInfo, IndexInfo *otherIndexInfo) +{ + if (descIndexInfo) { + relation->IsIdenticalTo(descIndexInfo, otherIndexInfo); + if (!relation->IsTrue()) { + return false; + } + } + + return true; +} + void ObjectType::Identical(TypeRelation *relation, Type *other) { if (!other->IsObjectType() || kind_ != other->AsObjectType()->Kind()) { @@ -55,7 +91,6 @@ void ObjectType::Identical(TypeRelation *relation, Type *other) } ObjectType *otherObj = other->AsObjectType(); - if (desc_->properties.size() != otherObj->Properties().size() || CallSignatures().size() != otherObj->CallSignatures().size() || ConstructSignatures().size() != otherObj->ConstructSignatures().size() || @@ -67,23 +102,8 @@ void ObjectType::Identical(TypeRelation *relation, Type *other) return; } - for (auto *it : desc_->properties) { - binder::LocalVariable *found = otherObj->Desc()->FindProperty(it->Name()); - if (!found) { - relation->Result(false); - return; - } - - relation->IsIdenticalTo(it->TsType(), found->TsType()); - - if (!relation->IsTrue()) { - return; - } - - if (it->Flags() != found->Flags()) { - relation->Result(false); - return; - } + if (!IsPropertiesIdentical(relation, otherObj)) { + return; } if (!EachSignatureRelatedToSomeSignature(relation, CallSignatures(), otherObj->CallSignatures()) || @@ -96,18 +116,9 @@ void ObjectType::Identical(TypeRelation *relation, Type *other) return; } - if (desc_->numberIndexInfo) { - relation->IsIdenticalTo(desc_->numberIndexInfo, otherObj->NumberIndexInfo()); - if (!relation->IsTrue()) { - return; - } - } - - if (desc_->stringIndexInfo) { - relation->IsIdenticalTo(desc_->stringIndexInfo, otherObj->StringIndexInfo()); - if (!relation->IsTrue()) { - return; - } + if (!IsIndexInfosIdentical(relation, desc_->numberIndexInfo, otherObj->NumberIndexInfo())|| + !IsIndexInfosIdentical(relation, desc_->stringIndexInfo, otherObj->StringIndexInfo())) { + return; } } diff --git a/es2panda/typescript/types/objectType.h b/es2panda/typescript/types/objectType.h index e28454270005cc81bc9dc886db67743631985fc6..16375252882d7691c770663387a170035f5af702 100644 --- a/es2panda/typescript/types/objectType.h +++ b/es2panda/typescript/types/objectType.h @@ -199,6 +199,10 @@ protected: ObjectTypeKind kind_; ObjectDescriptor *desc_; ObjectFlags objFlag_; + +private: + bool IsPropertiesIdentical(TypeRelation *relation, ObjectType *otherObj); + bool IsIndexInfosIdentical(TypeRelation *relation, IndexInfo *descIndexInfo, IndexInfo *otherIndexInfo); }; } // namespace panda::es2panda::checker