From 0154b75923d07a773704501e18b4ee343c72421d Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 23 Jun 2020 11:54:28 -0700 Subject: [PATCH] Fixed generic inner type alias with type extensions --- IDEHelper/Compiler/BfModule.h | 2 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 30 +++++++++++++++++------ IDEHelper/Tests/LibA/src/LibA0.bf | 7 ++++++ IDEHelper/Tests/src/Extensions.bf | 31 ++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index b2655aa3..c77355e0 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1704,7 +1704,7 @@ public: BfTypeInstance* GetOuterType(BfType* type); bool IsInnerType(BfType* checkInnerType, BfType* checkOuterType); bool IsInnerType(BfTypeDef* checkInnerType, BfTypeDef* checkOuterType); - bool TypeHasParent(BfTypeDef* checkChildTypeDef, BfTypeDef* checkParentTypeDef); + bool TypeHasParentOrEquals(BfTypeDef* checkChildTypeDef, BfTypeDef* checkParentTypeDef); BfTypeDef* FindCommonOuterType(BfTypeDef* type, BfTypeDef* type2); bool TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType, bool checkAccessibility = true); int GetTypeDistance(BfType* fromType, BfType* toType); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 3db4d58e..8a9f61ce 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -215,7 +215,10 @@ bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstan { auto underlyingType = genericTypeInst->GetUnderlyingType(); if ((underlyingType != NULL) && (underlyingType->IsGenericTypeInstance())) + { + PopulateType(underlyingType, BfPopulateType_Declaration); return ValidateGenericConstraints(typeRef, (BfTypeInstance*)underlyingType, ignoreErrors); + } return true; } @@ -5278,7 +5281,7 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfTypeReference* typeRef, { bool isFailurePass = pass == 1; bool allowPrivate = (mCurTypeInstance != NULL) && - ((mCurTypeInstance == outerTypeInstance) || TypeHasParent(mCurTypeInstance->mTypeDef, outerTypeInstance->mTypeDef)); + ((mCurTypeInstance == outerTypeInstance) || TypeHasParentOrEquals(mCurTypeInstance->mTypeDef, outerTypeInstance->mTypeDef)); bool allowProtected = allowPrivate;/*(mCurTypeInstance != NULL) && (allowPrivate || (mCurTypeInstance->mSkipTypeProtectionChecks) || TypeIsSubTypeOf(mCurTypeInstance, outerTypeInstance));*/ @@ -7771,7 +7774,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula BfTypeDef* outerType = mSystem->GetCombinedPartial(typeDef->mOuterType); BF_ASSERT(!outerType->mIsPartial); - if (TypeHasParent(mCurTypeInstance->mTypeDef, outerType)) + if (TypeHasParentOrEquals(mCurTypeInstance->mTypeDef, outerType)) { BfType* checkCurType = mCurTypeInstance; if (checkCurType->IsBoxed()) @@ -10482,15 +10485,28 @@ BfTypedValue BfModule::GetIntCoercible(const BfTypedValue& typedValue) return BfTypedValue(val, intType); } -bool BfModule::TypeHasParent(BfTypeDef* checkChildTypeDef, BfTypeDef* checkParentTypeDef) +bool BfModule::TypeHasParentOrEquals(BfTypeDef* checkChildTypeDef, BfTypeDef* checkParentTypeDef) { BfTypeDef* checkType = checkChildTypeDef; - while (checkType != NULL) - { - if (checkType == checkParentTypeDef) - return true; + + if (checkType->mNestDepth < checkParentTypeDef->mNestDepth) + return false; + + while (checkType->mNestDepth > checkParentTypeDef->mNestDepth) checkType = checkType->mOuterType; + + if (checkType == checkParentTypeDef) + return true; + if (checkType->mNameEx != checkParentTypeDef->mNameEx) + return false; + + if (checkType->mIsPartial) + { + for (auto partial : checkParentTypeDef->mPartials) + if (partial == checkType) + return true; } + return false; } diff --git a/IDEHelper/Tests/LibA/src/LibA0.bf b/IDEHelper/Tests/LibA/src/LibA0.bf index 5d7f2ad5..95adad85 100644 --- a/IDEHelper/Tests/LibA/src/LibA0.bf +++ b/IDEHelper/Tests/LibA/src/LibA0.bf @@ -1,4 +1,6 @@ using System; +using System.Collections; + namespace LibA { interface IVal @@ -26,6 +28,11 @@ namespace LibA let t = new T(); delete t; } + + public static bool DictEquals(Dictionary lhs, Dictionary rhs) + { + return lhs == rhs; + } } } diff --git a/IDEHelper/Tests/src/Extensions.bf b/IDEHelper/Tests/src/Extensions.bf index 0da69dbd..e43b5a6a 100644 --- a/IDEHelper/Tests/src/Extensions.bf +++ b/IDEHelper/Tests/src/Extensions.bf @@ -1,6 +1,7 @@ #pragma warning disable 168 using System; +using System.Collections; namespace System.Collections { @@ -16,6 +17,26 @@ namespace System.Collections return total; } } + + extension Dictionary + { + public static bool operator==(Self lhs, Self rhs) where K : IOpEquals where V : IOpEquals + { + if (lhs.mCount != rhs.mCount) + return false; + for (var kv in ref lhs) + { + if (rhs.TryGetValue(kv.key, var rhsVal)) + { + if (*kv.valueRef != rhsVal) + return false; + } + else + return false; + } + return true; + } + } } namespace System.Collections @@ -161,6 +182,16 @@ namespace Tests Test.Assert(val == 110); } + [Test] + public static void TestDictionary() + { + Dictionary dictLhs = scope .() {("Abc", 123), ("Def", 234) }; + Dictionary dictrhs = scope .() {(scope:: String("Abc"), 123), ("Def", 234) }; + + Test.Assert(dictLhs == dictrhs); + Test.Assert(!LibA.LibA0.DictEquals(dictLhs, dictrhs)); + } + [Test] public static void TestSharedData() {