浏览代码

File-scoped namespaces

Brian Fiete 3 年之前
父节点
当前提交
f3f2f4c6ec

+ 1 - 1
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

+ 1 - 1
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);
 		}

+ 42 - 8
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<BfBlock>(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)

+ 16 - 0
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<BfTypeReference*> mInternalAccessSet;
 	HashContext* mFullHashCtx;
 	HashContext* mSignatureHashCtx;
+	
+	Array<NamespaceState> mFileLevelNamespaceState;
+	int mNamespaceBlockDepth;	
 
 public:
 	void ParseGenericParams(BfGenericParamsDeclaration* genericParamsDecl, BfGenericConstraintsDeclaration* genericConstraints, Array<BfGenericParamDef*>& genericParams, Array<BfExternalConstraintDef>* 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);

+ 1 - 1
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)

+ 1 - 1
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;
 }
 

+ 1 - 1
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)

+ 13 - 5
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<BfTokenNode>(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;
 	}