From 390e7f7f9b5508f0d40bc13bc26cfd43acc320d1 Mon Sep 17 00:00:00 2001 From: muhammethalilsolmaz Date: Sat, 14 Jun 2025 17:01:17 +0300 Subject: [PATCH] fix: Added Variance Control for Interface Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IC7VGJ Reason: Need type error Description: Variance control added for interface Tests: Tests removed from ignore list Signed-off-by: muhammethalilsolmaz --- ets2panda/checker/ETSAnalyzer.cpp | 1 + ets2panda/checker/ETSchecker.h | 1 + ets2panda/checker/checkerContext.h | 5 ++++ ets2panda/checker/ets/helpers.cpp | 27 +++++++++++++++++++ ets2panda/checker/types/ets/etsObjectType.cpp | 10 +++++-- ets2panda/scripts/arkui.properties | 2 +- .../test/runtime/ets/ObjectIterable_3.ets | 4 +-- 7 files changed, 45 insertions(+), 5 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 3aa4109c2e..e7bd6ab941 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -3563,6 +3563,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const for (auto *it : st->Body()->Body()) { it->Check(checker); } + checker->CheckTypeParameterVariance(st); return st->TsType(); } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 7de58a472e..503437df28 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -795,6 +795,7 @@ public: // Covariant and contravariant void CheckTypeParameterVariance(ir::ClassDefinition *classDef); + void CheckTypeParameterVariance(ir::TSInterfaceDeclaration *interfaceDec); checker::Type *CheckArrayElements(ir::ArrayExpression *init); void ResolveReturnStatement(checker::Type *funcReturnType, checker::Type *argumentType, diff --git a/ets2panda/checker/checkerContext.h b/ets2panda/checker/checkerContext.h index aa5e6b26fc..04c276e234 100644 --- a/ets2panda/checker/checkerContext.h +++ b/ets2panda/checker/checkerContext.h @@ -194,6 +194,11 @@ public: smartCasts_.clear(); } + Checker *GetParent() const + { + return parent_; + } + void RemoveSmartCast(varbinder::Variable const *const variable) noexcept { smartCasts_.erase(variable); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 553abd66e2..266d304b30 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -3049,6 +3049,33 @@ ir::CallExpression *ETSChecker::CreateExtensionAccessorCall(ETSChecker *checker, return callExpr->AsCallExpression(); } +void ETSChecker::CheckTypeParameterVariance(ir::TSInterfaceDeclaration *interfaceDec) +{ + if (interfaceDec == nullptr || interfaceDec->TypeParams() == nullptr) { + return; + } + + auto *const checker = Context().GetParent()->AsETSChecker(); + checker->Context().SetContainingClass(interfaceDec->TsType()->AsETSObjectType()); + checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), + checker->Context().ContainingClass()); + + auto checkVariance = [this](VarianceFlag varianceFlag, ir::Expression *expression, Type *type) { + Relation()->Result(RelationResult::TRUE); + Relation()->SetNode(expression); + Relation()->CheckVarianceRecursively(type, varianceFlag); + Relation()->SetNode(nullptr); + }; + + for (auto *it : interfaceDec->Body()->Body()) { + if (!it->IsMethodDefinition() || it->AsMethodDefinition()->IsConstructor()) { + continue; + } + + checkVariance(VarianceFlag::COVARIANT, it->AsMethodDefinition()->Id(), it->Check(this)); + } +} + void ETSChecker::CheckTypeParameterVariance(ir::ClassDefinition *classDef) { if (classDef->TypeParams() == nullptr) { diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index f4626cb22a..c8c38a92db 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -1418,8 +1418,14 @@ void ETSObjectType::CheckVarianceRecursively(TypeRelation *relation, VarianceFla return; } - auto *params = GetDeclNode()->IsClassDefinition() ? GetDeclNode()->AsClassDefinition()->TypeParams() - : GetDeclNode()->AsTSInterfaceDeclaration()->TypeParams(); + auto *declNode = GetDeclNode(); + + if (declNode == nullptr) { + return; + } + + auto *params = declNode->IsClassDefinition() ? GetDeclNode()->AsClassDefinition()->TypeParams() + : GetDeclNode()->AsTSInterfaceDeclaration()->TypeParams(); if (params == nullptr) { return; } diff --git a/ets2panda/scripts/arkui.properties b/ets2panda/scripts/arkui.properties index 54df76e008..4b293c0936 100644 --- a/ets2panda/scripts/arkui.properties +++ b/ets2panda/scripts/arkui.properties @@ -1,3 +1,3 @@ ARKUI_DEV_REPO=https://gitee.com/rri_opensource/koala_projects.git -ARKUI_DEV_BRANCH=panda_rev_8-remove-primitives +ARKUI_DEV_BRANCH=panda_rev_8-array-as-invariant ARKUI_DEST=koala-sig diff --git a/ets2panda/test/runtime/ets/ObjectIterable_3.ets b/ets2panda/test/runtime/ets/ObjectIterable_3.ets index 80f811df62..596d5961de 100644 --- a/ets2panda/test/runtime/ets/ObjectIterable_3.ets +++ b/ets2panda/test/runtime/ets/ObjectIterable_3.ets @@ -13,9 +13,9 @@ * limitations under the License. */ -interface MyIterator1 extends Iterator {} +interface MyIterator1 extends Iterator {} -interface MyIterator2 extends MyIterator1 {} +interface MyIterator2 extends MyIterator1 {} interface MyIter { $_iterator(): Iterator; -- Gitee