diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index e565c6ed..9fb24a6c 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -10025,6 +10025,8 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene skipCheckBaseType = mContext->mCurTypeState->mType->ToTypeInstance(); } + BfProject* useProject = useTypeDef->mProject; + BfTypeDefLookupContext lookupCtx; bool allowPrivate = true; @@ -10036,6 +10038,13 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene BfTypeDef* foundInnerType = NULL; + if ((resolveFlags & BfResolveTypeRefFlag_SpecializedProject) != 0) + { + if (typeInstance->mGenericTypeInfo->mProjectsReferenced.empty()) + typeInstance->GenerateProjectsReferenced(); + lookupCtx.mCheckProjects = &typeInstance->mGenericTypeInfo->mProjectsReferenced; + } + if ((lookupResultCtx != NULL) && (lookupResultCtx->mIsVerify)) { if (lookupResultCtx->mResult->mFoundInnerType) @@ -10053,7 +10062,7 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene { if (!checkTypeInst->mTypeDef->mNestedTypes.IsEmpty()) { - if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx)) + if (mSystem->FindTypeDef(findName, numGenericArgs, useProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx)) { foundInnerType = lookupCtx.mBestTypeDef; @@ -10101,14 +10110,14 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene if (!lookupCtx.HasValidMatch()) { if (mSystem->mTypeDefs.TryGet(findName, NULL)) - mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, BfAtomComposite(), allowPrivate, &lookupCtx); + mSystem->FindTypeDef(findName, numGenericArgs, useProject, BfAtomComposite(), allowPrivate, &lookupCtx); for (auto& checkNamespace : useTypeDef->mNamespaceSearch) { BfAtom* atom = findName.mParts[0]; BfAtom* prevAtom = checkNamespace.mParts[checkNamespace.mSize - 1]; if (atom->mPrevNamesMap.ContainsKey(prevAtom)) - mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkNamespace, allowPrivate, &lookupCtx); + mSystem->FindTypeDef(findName, numGenericArgs, useProject, checkNamespace, allowPrivate, &lookupCtx); } } @@ -10119,7 +10128,7 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene { for (auto staticTypeInstance : staticSearch->mStaticTypes) { - if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, staticTypeInstance->mTypeDef->mFullNameEx, false, &lookupCtx)) + if (mSystem->FindTypeDef(findName, numGenericArgs, useProject, staticTypeInstance->mTypeDef->mFullNameEx, false, &lookupCtx)) { if (lookupCtx.HasValidMatch()) break; @@ -10232,6 +10241,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric BfTypeLookupEntry typeLookupEntry; typeLookupEntry.mName.Reference(findName); typeLookupEntry.mNumGenericParams = numGenericArgs; + typeLookupEntry.mFlags = ((resolveFlags & BfResolveTypeRefFlag_SpecializedProject) != 0) ? BfTypeLookupEntry::Flags_SpecializedProject : BfTypeLookupEntry::Flags_None; typeLookupEntry.mUseTypeDef = useTypeDef; BfTypeLookupEntry* typeLookupEntryPtr = NULL; @@ -10799,10 +10809,27 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } BfTypeDef* curTypeDef = NULL; + Array* checkProjects = NULL; + if (contextTypeInstance != NULL) { curTypeDef = contextTypeInstance->mTypeDef; + if ((curTypeDef->IsEmitted()) && (!typeRef->IsTemporary())) + { + auto parser = typeRef->GetParser(); + if ((parser != NULL) && (parser->mIsEmitted)) + { + if (contextTypeInstance->IsGenericTypeInstance()) + { + resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_SpecializedProject); + if (contextTypeInstance->mGenericTypeInfo->mProjectsReferenced.empty()) + contextTypeInstance->GenerateProjectsReferenced(); + checkProjects = &contextTypeInstance->mGenericTypeInfo->mProjectsReferenced; + } + } + } + // Check generics first auto namedTypeRef = BfNodeDynCastExact(typeRef); auto directStrTypeRef = BfNodeDynCastExact(typeRef); @@ -11166,7 +11193,24 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula if (activeTypeDef != NULL) bfProject = activeTypeDef->mProject; + bool leftIsNamespace = false; if (mSystem->ContainsNamespace(leftComposite, bfProject)) + { + leftIsNamespace = true; + } + else if (checkProjects != NULL) + { + for (auto checkProject : *checkProjects) + { + if (mSystem->ContainsNamespace(leftComposite, checkProject)) + { + leftIsNamespace = true; + break; + } + } + } + + if (leftIsNamespace) { qualifiedTypeRef->mLeft->ToString(findName); findName.Append('.'); @@ -11496,7 +11540,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula (BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_DisallowComptime | BfResolveTypeRefFlag_AllowInferredSizedArray | BfResolveTypeRefFlag_Attribute | BfResolveTypeRefFlag_AllowUnboundGeneric | BfResolveTypeRefFlag_ForceUnboundGeneric | BfResolveTypeRefFlag_AllowGenericParamConstValue | - BfResolveTypeRefFlag_AllowImplicitConstExpr)); + BfResolveTypeRefFlag_AllowImplicitConstExpr | BfResolveTypeRefFlag_SpecializedProject)); lookupCtx.mRootTypeRef = typeRef; lookupCtx.mRootTypeDef = typeDef; lookupCtx.mModule = this; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 98c054c0..3b35a4f3 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -41,7 +41,8 @@ enum BfResolveTypeRefFlags BfResolveTypeRefFlag_AllowImplicitConstExpr = 0x20000, BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000, BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000, - BfResolveTypeRefFlag_IgnoreProtection = 0x100000 + BfResolveTypeRefFlag_IgnoreProtection = 0x100000, + BfResolveTypeRefFlag_SpecializedProject = 0x200000 }; enum BfTypeNameFlags : uint16 @@ -1721,8 +1722,15 @@ public: struct BfTypeLookupEntry { + enum Flags : uint8 + { + Flags_None, + Flags_SpecializedProject + }; + BfAtomComposite mName; - int mNumGenericParams; + int16 mNumGenericParams; + Flags mFlags; uint32 mAtomUpdateIdx; BfTypeDef* mUseTypeDef; @@ -1730,6 +1738,7 @@ struct BfTypeLookupEntry { return (mName == rhs.mName) && (mNumGenericParams == rhs.mNumGenericParams) && + (mFlags == rhs.mFlags) && (mUseTypeDef == rhs.mUseTypeDef); } }; diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index b5b4c65a..09ccca04 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -2663,34 +2663,54 @@ bool BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, continue; } - if ((typeDef->mFullName == *qualifiedFindNamePtr) && (CheckTypeDefReference(typeDef, project))) + if (typeDef->mFullName == *qualifiedFindNamePtr) { - int curPri = 0; - if (typeDef->mProtection < minProtection) - curPri -= 1; - if (typeDef->IsGlobalsContainer()) - curPri -= 2; - if (typeDef->mGenericParamDefs.size() != numGenericArgs) + bool isProjectValid = false; + if (CheckTypeDefReference(typeDef, project)) { - // Still allow SOME match even if we put in the wrong number of generic args - curPri -= 4; + isProjectValid = true; } - if ((typeDef->mPartials.mSize > 0) && (typeDef->mPartials[0]->IsExtension())) + else if ((ctx != NULL) && (ctx->mCheckProjects != NULL)) { - // Is a failed extension - curPri -= 8; + for (auto checkProject : *ctx->mCheckProjects) + { + if (CheckTypeDefReference(typeDef, checkProject)) + { + isProjectValid = true; + break; + } + } } - if ((curPri > ctx->mBestPri) || (ctx->mBestTypeDef == NULL)) + if (isProjectValid) { - ctx->mBestTypeDef = typeDef; - ctx->mAmbiguousTypeDef = NULL; - ctx->mBestPri = curPri; - hadMatch = true; - } - else if (curPri == ctx->mBestPri) - { - ctx->mAmbiguousTypeDef = typeDef; + int curPri = 0; + if (typeDef->mProtection < minProtection) + curPri -= 1; + if (typeDef->IsGlobalsContainer()) + curPri -= 2; + if (typeDef->mGenericParamDefs.size() != numGenericArgs) + { + // Still allow SOME match even if we put in the wrong number of generic args + curPri -= 4; + } + if ((typeDef->mPartials.mSize > 0) && (typeDef->mPartials[0]->IsExtension())) + { + // Is a failed extension + curPri -= 8; + } + + if ((curPri > ctx->mBestPri) || (ctx->mBestTypeDef == NULL)) + { + ctx->mBestTypeDef = typeDef; + ctx->mAmbiguousTypeDef = NULL; + ctx->mBestPri = curPri; + hadMatch = true; + } + else if (curPri == ctx->mBestPri) + { + ctx->mAmbiguousTypeDef = typeDef; + } } } itr.MoveToNextHashMatch(); diff --git a/IDEHelper/Compiler/BfSystem.h b/IDEHelper/Compiler/BfSystem.h index 356612af..271e0996 100644 --- a/IDEHelper/Compiler/BfSystem.h +++ b/IDEHelper/Compiler/BfSystem.h @@ -1001,6 +1001,7 @@ public: int mBestPri; BfTypeDef* mBestTypeDef; BfTypeDef* mAmbiguousTypeDef; + Array* mCheckProjects; public: BfTypeDefLookupContext() @@ -1008,6 +1009,7 @@ public: mBestPri = (int)0x80000000; mBestTypeDef = NULL; mAmbiguousTypeDef = NULL; + mCheckProjects = NULL; } bool HasValidMatch()