Browse Source

Better fix for VerifyTypeLookups

Brian Fiete 4 years ago
parent
commit
c598944f52

+ 12 - 2
IDEHelper/Compiler/BfContext.cpp

@@ -2276,8 +2276,18 @@ void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst)
 					//  so the mNextRevision will be ignored
 					//  so the mNextRevision will be ignored
 					auto useTypeDef = lookupEntry.mUseTypeDef;
 					auto useTypeDef = lookupEntry.mUseTypeDef;
 					BfTypeDef* ambiguousTypeDef = NULL;
 					BfTypeDef* ambiguousTypeDef = NULL;
-					BfTypeDef* result = typeInst->mModule->FindTypeDefRaw(lookupEntry.mName, lookupEntry.mNumGenericParams, typeInst, useTypeDef, NULL);
-					if (result != lookupEntryPair.mValue.mTypeDef)
+					BfTypeLookupResult* lookupResult = &lookupEntryPair.mValue;
+
+					BfTypeLookupResultCtx lookupResultCtx;
+					lookupResultCtx.mResult = lookupResult;
+					lookupResultCtx.mIsVerify = true;
+
+					BfTypeDef* result = typeInst->mModule->FindTypeDefRaw(lookupEntry.mName, lookupEntry.mNumGenericParams, typeInst, useTypeDef, NULL, &lookupResultCtx);
+					if ((result == NULL) && (lookupResult->mFoundInnerType))
+					{
+						// Allow this- if there were new types added then the types would be rebuilt already
+					}
+					else if (result != lookupResult->mTypeDef)
 					{
 					{
 						isDirty = true;
 						isDirty = true;
 					}
 					}

+ 1 - 1
IDEHelper/Compiler/BfModule.h

@@ -1823,7 +1823,7 @@ public:
 	void ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef);
 	void ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef);
 	void ShowGenericArgCountError(BfAstNode* typeRef, int wantedGenericParams);	
 	void ShowGenericArgCountError(BfAstNode* typeRef, int wantedGenericParams);	
 	BfTypeDef* GetActiveTypeDef(BfTypeInstance* typeInstanceOverride = NULL, bool useMixinDecl = false); // useMixinDecl is useful for type lookup, but we don't want the decl project to limit what methods the user can call	
 	BfTypeDef* GetActiveTypeDef(BfTypeInstance* typeInstanceOverride = NULL, bool useMixinDecl = false); // useMixinDecl is useful for type lookup, but we don't want the decl project to limit what methods the user can call	
-	BfTypeDef* FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error);
+	BfTypeDef* FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error, BfTypeLookupResultCtx* lookupResultCtx = NULL);
 	BfTypeDef* FindTypeDef(const BfAtomComposite& findName, int numGenericArgs = 0, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL);
 	BfTypeDef* FindTypeDef(const BfAtomComposite& findName, int numGenericArgs = 0, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL);
 	BfTypeDef* FindTypeDef(const StringImpl& typeName, int numGenericArgs = 0, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL);
 	BfTypeDef* FindTypeDef(const StringImpl& typeName, int numGenericArgs = 0, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL);
 	BfTypeDef* FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL, int numGenericParams = 0, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
 	BfTypeDef* FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL, int numGenericParams = 0, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);

+ 56 - 38
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -8382,7 +8382,7 @@ BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool
 	return useTypeDef;
 	return useTypeDef;
 }
 }
 
 
-BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error)
+BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error, BfTypeLookupResultCtx* lookupResultCtx)
 {
 {
 	if ((findName.mSize == 1) && (findName.mParts[0]->mIsSystemType))
 	if ((findName.mSize == 1) && (findName.mParts[0]->mIsSystemType))
 	{
 	{
@@ -8408,56 +8408,68 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
 	BfTypeDef* protErrorTypeDef = NULL;
 	BfTypeDef* protErrorTypeDef = NULL;
 	BfTypeInstance* protErrorOuterType = NULL;
 	BfTypeInstance* protErrorOuterType = NULL;
 	
 	
-	if ((!lookupCtx.HasValidMatch()) && (typeInstance != NULL))
+	BfTypeDef* foundInnerType = NULL;
+
+	if ((lookupResultCtx != NULL) && (lookupResultCtx->mIsVerify))
+	{
+		if (lookupResultCtx->mResult->mFoundInnerType)
+			return lookupCtx.mBestTypeDef;
+	}
+	else
 	{
 	{
-		std::function<bool(BfTypeInstance*)> _CheckType = [&](BfTypeInstance* typeInstance)
+		if ((!lookupCtx.HasValidMatch()) && (typeInstance != NULL))
 		{
 		{
-			auto checkTypeInst = typeInstance;
-			allowPrivate = true;
-			while (checkTypeInst != NULL)
+			std::function<bool(BfTypeInstance*)> _CheckType = [&](BfTypeInstance* typeInstance)
 			{
 			{
-				if (!checkTypeInst->mTypeDef->mNestedTypes.IsEmpty())
+				auto checkTypeInst = typeInstance;
+				allowPrivate = true;
+				while (checkTypeInst != NULL)
 				{
 				{
-					if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx))
+					if (!checkTypeInst->mTypeDef->mNestedTypes.IsEmpty())
 					{
 					{
-						if (lookupCtx.HasValidMatch())
-							return true;
-
-						if ((lookupCtx.mBestTypeDef->mProtection == BfProtection_Private) && (!allowPrivate))
+						if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx))
 						{
 						{
-							protErrorTypeDef = lookupCtx.mBestTypeDef;
-							protErrorOuterType = checkTypeInst;
+							foundInnerType = lookupCtx.mBestTypeDef;
+
+							if (lookupCtx.HasValidMatch())
+								return true;
+
+							if ((lookupCtx.mBestTypeDef->mProtection == BfProtection_Private) && (!allowPrivate))
+							{
+								protErrorTypeDef = lookupCtx.mBestTypeDef;
+								protErrorOuterType = checkTypeInst;
+							}
 						}
 						}
 					}
 					}
-				}
-				if (checkTypeInst == skipCheckBaseType)
-					break;
+					if (checkTypeInst == skipCheckBaseType)
+						break;
 
 
-				checkTypeInst = GetBaseType(checkTypeInst);
-				allowPrivate = false;
-			}			
+					checkTypeInst = GetBaseType(checkTypeInst);
+					allowPrivate = false;
+				}
 
 
-			checkTypeInst = typeInstance;
-			allowPrivate = true;
-			while (checkTypeInst != NULL)
-			{
-				auto outerTypeInst = GetOuterType(checkTypeInst);
-				if (outerTypeInst != NULL)
+				checkTypeInst = typeInstance;
+				allowPrivate = true;
+				while (checkTypeInst != NULL)
 				{
 				{
-					if (_CheckType(outerTypeInst))
-						return true;
+					auto outerTypeInst = GetOuterType(checkTypeInst);
+					if (outerTypeInst != NULL)
+					{
+						if (_CheckType(outerTypeInst))
+							return true;
+					}
+					if (checkTypeInst == skipCheckBaseType)
+						break;
+
+					checkTypeInst = GetBaseType(checkTypeInst);
+					allowPrivate = false;
 				}
 				}
-				if (checkTypeInst == skipCheckBaseType)
-					break;
-				
-				checkTypeInst = GetBaseType(checkTypeInst);
-				allowPrivate = false;
-			}
 
 
-			return false;
-		};
+				return false;
+			};
 
 
-		_CheckType(typeInstance);
+			_CheckType(typeInstance);
+		}
 	}
 	}
 
 
 	if (!lookupCtx.HasValidMatch())
 	if (!lookupCtx.HasValidMatch())
@@ -8515,6 +8527,9 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
 	if ((protErrorTypeDef != NULL) && (lookupCtx.mBestTypeDef == protErrorTypeDef) && (error != NULL) && (error->mRefNode != NULL))
 	if ((protErrorTypeDef != NULL) && (lookupCtx.mBestTypeDef == protErrorTypeDef) && (error != NULL) && (error->mRefNode != NULL))
 		Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", TypeToString(protErrorOuterType).c_str(), findName.ToString().c_str()), error->mRefNode); // CS0122
 		Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", TypeToString(protErrorOuterType).c_str(), findName.ToString().c_str()), error->mRefNode); // CS0122
 
 
+	if ((lookupResultCtx != NULL) && (lookupResultCtx->mResult != NULL) && (!lookupResultCtx->mIsVerify) && (foundInnerType != NULL) && (foundInnerType == lookupCtx.mBestTypeDef))
+		lookupResultCtx->mResult->mFoundInnerType = true;
+
 	return lookupCtx.mBestTypeDef;
 	return lookupCtx.mBestTypeDef;
 }
 }
 
 
@@ -8569,7 +8584,10 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric
 
 
 		BfTypeLookupError localError;
 		BfTypeLookupError localError;
 		BfTypeLookupError* errorPtr = (error != NULL) ? error : &localError;
 		BfTypeLookupError* errorPtr = (error != NULL) ? error : &localError;
-		auto typeDef = FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, errorPtr);
+
+		BfTypeLookupResultCtx lookupResultCtx;
+		lookupResultCtx.mResult = resultPtr;
+		auto typeDef = FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, errorPtr, &lookupResultCtx);
 
 
 		if (prevAllocSize != typeInstance->mLookupResults.size())
 		if (prevAllocSize != typeInstance->mLookupResults.size())
 		{
 		{

+ 14 - 0
IDEHelper/Compiler/BfResolvedTypeUtils.h

@@ -1668,11 +1668,25 @@ struct BfTypeLookupResult
 {
 {
 	BfTypeDef* mTypeDef;
 	BfTypeDef* mTypeDef;
 	bool mForceLookup;
 	bool mForceLookup;
+	bool mFoundInnerType;
 
 
 	BfTypeLookupResult()
 	BfTypeLookupResult()
 	{
 	{
 		mTypeDef = NULL;
 		mTypeDef = NULL;
 		mForceLookup = false;
 		mForceLookup = false;
+		mFoundInnerType = false;
+	}
+};
+
+struct BfTypeLookupResultCtx
+{
+	BfTypeLookupResult* mResult;
+	bool mIsVerify;
+
+	BfTypeLookupResultCtx()
+	{
+		mResult = NULL;
+		mIsVerify = false;
 	}
 	}
 };
 };