diff --git a/IDEHelper/Compiler/BfAst.h b/IDEHelper/Compiler/BfAst.h index 5b38594c..ef7567c5 100644 --- a/IDEHelper/Compiler/BfAst.h +++ b/IDEHelper/Compiler/BfAst.h @@ -2065,7 +2065,7 @@ public: BfTokenNode* mNamespaceNode; BfIdentifierNode* mNameNode; - BfBlock* mBlock; + BfAstNode* mBody; }; BF_AST_DECL(BfNamespaceDeclaration, BfAstNode); class BfBinaryOperatorExpression : public BfExpression diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 38a5a1f9..213c023f 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -9548,7 +9548,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration) override { - Add(namespaceDeclaration->mNamespaceNode, namespaceDeclaration->mBlock, 'N'); + Add(namespaceDeclaration->mNamespaceNode, namespaceDeclaration->mBody, 'N'); BfElementVisitor::Visit(namespaceDeclaration); } diff --git a/IDEHelper/Compiler/BfDefBuilder.cpp b/IDEHelper/Compiler/BfDefBuilder.cpp index ad8179c7..2c5c8068 100644 --- a/IDEHelper/Compiler/BfDefBuilder.cpp +++ b/IDEHelper/Compiler/BfDefBuilder.cpp @@ -68,6 +68,7 @@ BfDefBuilder::BfDefBuilder(BfSystem* bfSystem) mFullHashCtx = NULL; mSignatureHashCtx = NULL; + mNamespaceBlockDepth = 0; } BfDefBuilder::~BfDefBuilder() @@ -2493,11 +2494,43 @@ void BfDefBuilder::Visit(BfUsingModDirective* usingDirective) mStaticSearch.Add(usingDirective->mTypeRef); } +void BfDefBuilder::SetNamespaceState(const NamespaceState& namespaceState) +{ + while ((int)mNamespaceSearch.size() > namespaceState.mNamespaceSearchCount) + { + BfAtomComposite& atomComposite = mNamespaceSearch[0]; + mSystem->ReleaseAtomComposite(atomComposite); + mNamespaceSearch.RemoveAt(0); + } + mNamespace = namespaceState.mNamespace; +} + void BfDefBuilder::Visit(BfNamespaceDeclaration* namespaceDeclaration) { - BfAtomComposite prevNamespace = mNamespace; - int prevNamespaceSearchCount = (int)mNamespaceSearch.size(); + auto blockNode = BfNodeDynCast(namespaceDeclaration->mBody); + bool isFileLevel = (blockNode == NULL) && (namespaceDeclaration->mBody != NULL); + if (mNamespaceBlockDepth < mFileLevelNamespaceState.mSize) + { + auto& prevNamespaceState = mFileLevelNamespaceState[mNamespaceBlockDepth]; + if (prevNamespaceState.mNamespaceSearchCount != -1) + { + SetNamespaceState(prevNamespaceState); + prevNamespaceState.mNamespaceSearchCount = -1; + } + } + + NamespaceState namespaceState; + namespaceState.mNamespace = mNamespace; + namespaceState.mNamespaceSearchCount = (int)mNamespaceSearch.size(); + + if (isFileLevel) + { + while (mNamespaceBlockDepth >= mFileLevelNamespaceState.mSize) + mFileLevelNamespaceState.Add(NamespaceState()); + mFileLevelNamespaceState[mNamespaceBlockDepth] = namespaceState; + } + if (namespaceDeclaration->mNameNode == NULL) return; @@ -2531,14 +2564,15 @@ void BfDefBuilder::Visit(BfNamespaceDeclaration* namespaceDeclaration) mSystem->ReleaseAtom(namespaceAtom); } - VisitChild(namespaceDeclaration->mBlock); - while ((int)mNamespaceSearch.size() > prevNamespaceSearchCount) + if (blockNode != NULL) { - BfAtomComposite& atomComposite = mNamespaceSearch[0]; - mSystem->ReleaseAtomComposite(atomComposite); - mNamespaceSearch.RemoveAt(0); + mNamespaceBlockDepth++; + VisitChild(blockNode); + mNamespaceBlockDepth--; } - mNamespace = prevNamespace; + + if (!isFileLevel) + SetNamespaceState(namespaceState); } void BfDefBuilder::Visit(BfBlock* block) diff --git a/IDEHelper/Compiler/BfDefBuilder.h b/IDEHelper/Compiler/BfDefBuilder.h index 3aa8d454..39fc134f 100644 --- a/IDEHelper/Compiler/BfDefBuilder.h +++ b/IDEHelper/Compiler/BfDefBuilder.h @@ -11,6 +11,18 @@ class BfResolvePassData; class BfDefBuilder : public BfStructuralVisitor { +public: + struct NamespaceState + { + BfAtomComposite mNamespace; + int mNamespaceSearchCount; + + NamespaceState() + { + mNamespaceSearchCount = -1; + } + }; + public: BfSource* mCurSource; BfSystem* mSystem; @@ -27,6 +39,9 @@ public: Array mInternalAccessSet; HashContext* mFullHashCtx; HashContext* mSignatureHashCtx; + + Array mFileLevelNamespaceState; + int mNamespaceBlockDepth; public: void ParseGenericParams(BfGenericParamsDeclaration* genericParamsDecl, BfGenericConstraintsDeclaration* genericConstraints, Array& genericParams, Array* externConstraintDefs, int outerGenericSize, bool isInGeneric); @@ -45,6 +60,7 @@ public: void ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* typeDef); BfMethodDef* CreateMethodDef(BfMethodDeclaration* methodDecl, BfMethodDef* outerMethodDef = NULL); BfError* Fail(const StringImpl& errorStr, BfAstNode* refNode); + void SetNamespaceState(const NamespaceState& namespaceState); public: BfDefBuilder(BfSystem* bfSystem); diff --git a/IDEHelper/Compiler/BfElementVisitor.cpp b/IDEHelper/Compiler/BfElementVisitor.cpp index cc97d5b0..a405415b 100644 --- a/IDEHelper/Compiler/BfElementVisitor.cpp +++ b/IDEHelper/Compiler/BfElementVisitor.cpp @@ -1225,7 +1225,7 @@ void BfElementVisitor::Visit(BfNamespaceDeclaration* namespaceDeclaration) VisitChild(namespaceDeclaration->mNamespaceNode); VisitChild(namespaceDeclaration->mNameNode); - VisitChild(namespaceDeclaration->mBlock); + VisitChild(namespaceDeclaration->mBody); } void BfElementVisitor::Visit(BfBlock* block) diff --git a/IDEHelper/Compiler/BfNamespaceVisitor.cpp b/IDEHelper/Compiler/BfNamespaceVisitor.cpp index a9ea2766..6741c58f 100644 --- a/IDEHelper/Compiler/BfNamespaceVisitor.cpp +++ b/IDEHelper/Compiler/BfNamespaceVisitor.cpp @@ -76,7 +76,7 @@ void BfNamespaceVisitor::Visit(BfNamespaceDeclaration* namespaceDeclaration) if (mResolvePassData->mAutoComplete != NULL) mResolvePassData->mAutoComplete->CheckNamespace(namespaceDeclaration->mNameNode, mNamespace); mResolvePassData->HandleNamespaceReference(namespaceDeclaration->mNameNode, mNamespace); - VisitChild(namespaceDeclaration->mBlock); + VisitChild(namespaceDeclaration->mBody); mNamespace = prevNamespace; } diff --git a/IDEHelper/Compiler/BfPrinter.cpp b/IDEHelper/Compiler/BfPrinter.cpp index 839eb634..c90d0952 100644 --- a/IDEHelper/Compiler/BfPrinter.cpp +++ b/IDEHelper/Compiler/BfPrinter.cpp @@ -3008,7 +3008,7 @@ void BfPrinter::Visit(BfNamespaceDeclaration* namespaceDeclaration) VisitChild(namespaceDeclaration->mNamespaceNode); ExpectSpace(); VisitChild(namespaceDeclaration->mNameNode); - VisitChild(namespaceDeclaration->mBlock); + VisitChild(namespaceDeclaration->mBody); } void BfPrinter::DoBlockOpen(BfAstNode* prevNode, BfTokenNode* blockOpen, BfTokenNode* blockClose, bool queue, BlockState& blockState) diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index ab58cc18..9b2a685f 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -8537,14 +8537,22 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi ReplaceNode(tokenNode, namespaceDeclaration); MoveNode(identifierNode, namespaceDeclaration); - auto blockNode = ExpectBlockAfter(namespaceDeclaration); - if (blockNode == NULL) + BfAstNode* bodyNode = NULL; + BfBlock* blockNode = NULL; + + if (auto nextToken = BfNodeDynCast(mVisitorPos.GetNext())) + bodyNode = ExpectTokenAfter(namespaceDeclaration, BfToken_Semicolon); + else + bodyNode = blockNode = ExpectBlockAfter(namespaceDeclaration); + + if (bodyNode == NULL) return namespaceDeclaration; - MoveNode(blockNode, namespaceDeclaration); - namespaceDeclaration->mBlock = blockNode; + MoveNode(bodyNode, namespaceDeclaration); + namespaceDeclaration->mBody = bodyNode; mCurNamespaceStack.Add(namespaceDeclaration); - HandleTopLevel(namespaceDeclaration->mBlock); + if (blockNode != NULL) + HandleTopLevel(blockNode); mCurNamespaceStack.pop_back(); return namespaceDeclaration; }