diff --git a/IDEHelper/Compiler/BfAst.h b/IDEHelper/Compiler/BfAst.h index 2146039c..ce8b7093 100644 --- a/IDEHelper/Compiler/BfAst.h +++ b/IDEHelper/Compiler/BfAst.h @@ -1528,6 +1528,12 @@ T* BfNodeDynCastExact(BfAstNode* node) return canCast ? (T*)node : NULL; } +struct BfExteriorNode +{ + BfSizedArray mNamespaceNodes; + BfAstNode* mNode; +}; + BfIdentifierNode* BfIdentifierCast(BfAstNode* node); BfAstNode* BfNodeToNonTemporary(BfAstNode* node); diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 6c3719b8..12b5662d 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -3808,16 +3808,20 @@ void BfCompiler::VisitSourceExteriorNodes() return; bool failed = false; - for (auto node : parser->mParserData->mExteriorNodes) - { - if (auto usingDirective = BfNodeDynCast(node)) + for (auto& node : parser->mParserData->mExteriorNodes) + { + SetAndRestoreValue*> prevCurNamespaceNodes(mContext->mCurNamespaceNodes, &node.mNamespaceNodes); + + auto exteriorAstNode = node.mNode; + + if (auto usingDirective = BfNodeDynCast(exteriorAstNode)) { srcNodes.Clear(); namespaceParts.Clear(); bool success = _AddName(usingDirective->mNamespace, true); _CheckNamespace(parser, true, failed); } - else if (auto usingDirective = BfNodeDynCast(node)) + else if (auto usingDirective = BfNodeDynCast(exteriorAstNode)) { if (usingDirective->mTypeRef != NULL) { diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index c741da06..17af0431 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -50,6 +50,7 @@ BfContext::BfContext(BfCompiler* compiler) : mAllowLockYield = true; mCurTypeState = NULL; + mCurNamespaceNodes = NULL; mCurConstraintState = NULL; mResolvingVarField = false; mAssertOnPopulateType = false; diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index 560ef7d4..9a5765e6 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -352,8 +352,9 @@ class BfContext public: CritSect mCritSect; bool mDeleting; - + BfTypeState* mCurTypeState; + BfSizedArray* mCurNamespaceNodes; BfConstraintState* mCurConstraintState; bool mResolvingVarField; int mMappedObjectRevision; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 5a4efca1..77e3b539 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -8967,9 +8967,31 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mParser != NULL)) project = mCompiler->mResolvePassData->mParser->mProject; - BP_ZONE("System.FindTypeDef_2"); + BP_ZONE("System.FindTypeDef_2"); + Array namespaceSearch; + if (mContext->mCurNamespaceNodes != NULL) + { + String checkNamespace; + for (auto namespaceNode : *mContext->mCurNamespaceNodes) + { + if (namespaceNode->mNameNode != NULL) + { + if (!checkNamespace.IsEmpty()) + checkNamespace += "."; + namespaceNode->mNameNode->ToString(checkNamespace); + } + } + + if (!checkNamespace.IsEmpty()) + { + BfAtomComposite atomComposite; + if (mSystem->ParseAtomComposite(checkNamespace, atomComposite)) + namespaceSearch.Add(atomComposite); + } + } + BfTypeDef* ambiguousTypeDef = NULL; - BfTypeDef *result = mSystem->FindTypeDef(findName, numGenericArgs, project, Array(), &ambiguousTypeDef); + BfTypeDef *result = mSystem->FindTypeDef(findName, numGenericArgs, project, namespaceSearch, &ambiguousTypeDef); if ((ambiguousTypeDef != NULL) && (error != NULL)) { error->mErrorKind = BfTypeLookupError::BfErrorKind_Ambiguous; diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index 9c408b1c..5dc1ae3d 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -8252,7 +8252,10 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi if (tokenNode != NULL) MEMBER_SET(usingDirective, mTrailingSemicolon, tokenNode); - mExteriorNodes.Add(usingDirective); + BfExteriorNode exteriorNode; + exteriorNode.mNode = usingDirective; + BfSizedArrayInitIndirect(exteriorNode.mNamespaceNodes, mCurNamespaceStack, mAlloc); + mExteriorNodes.Add(exteriorNode); return usingDirective; } } @@ -8292,7 +8295,9 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi } } - mExteriorNodes.Add(usingDirective); + BfExteriorNode exteriorNode; + exteriorNode.mNode = usingDirective; + mExteriorNodes.Add(exteriorNode); return usingDirective; } break; @@ -8316,7 +8321,9 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi MoveNode(blockNode, namespaceDeclaration); namespaceDeclaration->mBlock = blockNode; + mCurNamespaceStack.Add(namespaceDeclaration); HandleTopLevel(namespaceDeclaration->mBlock); + mCurNamespaceStack.pop_back(); return namespaceDeclaration; } break; diff --git a/IDEHelper/Compiler/BfReducer.h b/IDEHelper/Compiler/BfReducer.h index 176536ba..5a63c622 100644 --- a/IDEHelper/Compiler/BfReducer.h +++ b/IDEHelper/Compiler/BfReducer.h @@ -149,7 +149,8 @@ public: bool mSkipCurrentNodeAssert; BfVisitorPos mVisitorPos; int mDocumentCheckIdx; - SizedArray mExteriorNodes; + SizedArray mCurNamespaceStack; + SizedArray mExteriorNodes; int mAssertCurrentNodeIdx; diff --git a/IDEHelper/Compiler/BfSource.h b/IDEHelper/Compiler/BfSource.h index b88fac39..8588adc6 100644 --- a/IDEHelper/Compiler/BfSource.h +++ b/IDEHelper/Compiler/BfSource.h @@ -31,7 +31,7 @@ public: BfRootNode* mRootNode; BfRootNode* mErrorRootNode; - BfSizedArray mExteriorNodes; + BfSizedArray mExteriorNodes; int mExteriorNodesCheckIdx; // 0 = unchecked, -1 = failed, >0 means success and equals the BfSystem.mTypesIdx BfSourceData()