Browse Source

Added ability to rename namespaces

Brian Fiete 5 years ago
parent
commit
014263c3a7

+ 1 - 0
IDE/src/Compiler/BfParser.bf

@@ -53,6 +53,7 @@ namespace IDE.Compiler
         public int32 mLocalId = -1;
         public String mReplaceStr ~ delete _;
         public String mTypeDef ~ delete _;
+		public String mNamespace ~ delete _;
         public int32 mFieldIdx = -1;
         public int32 mMethodIdx = -1;
         public int32 mPropertyIdx = -1;

+ 9 - 1
IDE/src/Compiler/BfResolvePassData.bf

@@ -20,7 +20,10 @@ namespace IDE.Compiler
 		static extern void BfResolvePassData_SetMethodGenericParamIdx(void* resolvePassData, int typeGenericParamIdx);
 
         [CallingConvention(.Stdcall), CLink]
-        static extern void BfResolvePassData_SetSymbolReferenceTypeDef(void* bfResolvePassData, char8* replaceStr);
+        static extern void BfResolvePassData_SetSymbolReferenceTypeDef(void* bfResolvePassData, char8* typeDefName);
+
+		[CallingConvention(.Stdcall), CLink]
+		static extern void BfResolvePassData_SetSymbolReferenceNamespace(void* bfResolvePassData, char8* namespaceName);
 
         [CallingConvention(.Stdcall), CLink]
         static extern void BfResolvePassData_SetSymbolReferenceFieldIdx(void* bfResolvePassData, int32 fieldIdx);
@@ -66,6 +69,11 @@ namespace IDE.Compiler
             BfResolvePassData_SetSymbolReferenceTypeDef(mNativeResolvePassData, typeDefName);
         }
 
+		public void SetSymbolReferenceNamespace(String namespaceName)
+		{
+		    BfResolvePassData_SetSymbolReferenceNamespace(mNativeResolvePassData, namespaceName);
+		}
+
         public void SetSymbolReferenceFieldIdx(int32 fieldIdx)
         {
             BfResolvePassData_SetSymbolReferenceFieldIdx(mNativeResolvePassData, fieldIdx);

+ 5 - 0
IDE/src/ui/RenameSymbolDialog.bf

@@ -227,6 +227,9 @@ namespace IDE.ui
 				    mResolveParams.mTypeGenericParamIdx = int32.Parse(lineDataItr.GetNext().Get());
 				case "methodGenericParam":
 				    mResolveParams.mMethodGenericParamIdx = int32.Parse(lineDataItr.GetNext().Get());
+				case "namespaceRef":
+					mResolveParams.mNamespace = new String(lineDataItr.GetNext().Get());
+					foundSymbol = true;
 				case "defLoc":
 					if (mKind == .Rename)
 					{
@@ -421,6 +424,8 @@ namespace IDE.ui
 					mResolvePassData.SetTypeGenericParamIdx(resolveParams.mTypeGenericParamIdx);
 				if (resolveParams.mMethodGenericParamIdx != -1)
 					mResolvePassData.SetMethodGenericParamIdx(resolveParams.mMethodGenericParamIdx);
+				if (resolveParams.mNamespace != null)
+					mResolvePassData.SetSymbolReferenceNamespace(resolveParams.mNamespace);
             }
 
 			mDoLock = mKind == Kind.Rename;

+ 37 - 0
IDEHelper/Compiler/BfAutoComplete.cpp

@@ -2564,6 +2564,43 @@ void BfAutoComplete::CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* pre
 	}
 }
 
+void BfAutoComplete::CheckNamespace(BfAstNode* node, const BfAtomComposite& namespaceName)
+{
+	if (mResolveType == BfResolveType_GetSymbolInfo)
+	{		
+		if (IsAutocompleteNode(node))
+		{			
+			int namespaceCount = namespaceName.mSize;
+			auto checkNode = node;
+			
+			while (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkNode))
+			{
+				if (!IsAutocompleteNode(qualifiedTypeRef->mLeft))
+					break;
+				namespaceCount--;
+				checkNode = qualifiedTypeRef->mLeft;
+			}
+			while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkNode))
+			{
+				if (!IsAutocompleteNode(qualifiedNameNode->mLeft))
+					break;
+				namespaceCount--;
+				checkNode = qualifiedNameNode->mLeft;
+			}
+			
+			while (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkNode))			
+				checkNode = qualifiedTypeRef->mRight;			
+			while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkNode))
+				checkNode = qualifiedNameNode->mRight;
+
+			mInsertStartIdx = checkNode->GetSrcStart();
+			mInsertEndIdx = checkNode->GetSrcEnd();
+			
+			mDefNamespace.Set(namespaceName.mParts, namespaceCount, NULL, 0);
+		}
+	}	
+}
+
 void BfAutoComplete::AddTypeInstanceEntry(BfTypeInstance* typeInst)
 {	
 	String bestTypeName = mModule->TypeToString(typeInst, BfTypeNameFlag_ReduceName);

+ 3 - 4
IDEHelper/Compiler/BfAutoComplete.h

@@ -182,14 +182,12 @@ public:
 	int mCursorLineStart;
 	int mCursorLineEnd;
 	
-	//BfMethodInstance* mReplaceMethodInstance;
-	
-	int mReplaceLocalId;
-	//int mDefMethodIdx;
+	int mReplaceLocalId;	
 	BfMethodDef* mDefMethod;
 	BfTypeDef* mDefType;
 	BfFieldDef* mDefField;
 	BfPropertyDef* mDefProp;
+	BfAtomComposite mDefNamespace;
 	int mDefMethodGenericParamIdx;
 	int mDefTypeGenericParamIdx;
 
@@ -248,6 +246,7 @@ public:
 	void CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* varDecl);
 	void CheckFieldRef(BfAstNode* identifierNode, BfFieldInstance* fieldInst);	
 	void CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode, BfScopeData* scopeData);
+	void CheckNamespace(BfAstNode* node, const BfAtomComposite& namespaceName);
 	void CheckEmptyStart(BfAstNode* prevNode, BfType* type);	
 	bool CheckFixit(BfAstNode* node);	
 	void CheckInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode* node);

+ 74 - 24
IDEHelper/Compiler/BfCompiler.cpp

@@ -28,6 +28,7 @@
 #include "BfResolvePass.h"
 #include "BeefySysLib/util/BeefPerf.h"
 #include "../LLVMUtils.h"
+#include "BfNamespaceVisitor.h"
 
 #pragma warning(pop)
 
@@ -3503,7 +3504,7 @@ void BfCompiler::VisitSourceExteriorNodes()
 					BF_ASSERT(mContext->mScratchModule->mCurTypeInstance == NULL);
 
 					SetAndRestoreValue<BfTypeInstance*> prevCurTypeInstance(mContext->mScratchModule->mCurTypeInstance, NULL);
-					mContext->mScratchModule->ResolveTypeRef(usingDirective->mTypeRef, NULL);
+					mContext->mScratchModule->ResolveTypeRef(usingDirective->mTypeRef, BfPopulateType_Identity);
 					if ((mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL))
 						mResolvePassData->mAutoComplete->CheckTypeRef(usingDirective->mTypeRef, false, false);
 					return;
@@ -3541,10 +3542,11 @@ void BfCompiler::ProcessAutocompleteTempType()
 
 	auto autoComplete = mResolvePassData->mAutoComplete;
 	BfLogSysM("ProcessAutocompleteTempType %d\n", autoComplete->mResolveType);
-
+	
 	SetAndRestoreValue<bool> prevCanceling(mCanceling, false);
 
 	BF_ASSERT(mResolvePassData->mAutoComplete->mDefMethod == NULL);
+
 	if (autoComplete->mResolveType == BfResolveType_GetNavigationData)
 	{
 		for (auto node : mResolvePassData->mParser->mSidechannelRootNode->mChildArr)
@@ -3692,6 +3694,14 @@ void BfCompiler::ProcessAutocompleteTempType()
 	}	
 	VisitSourceExteriorNodes();
 
+	if (autoComplete->mResolveType == BfResolveType_GetSymbolInfo)
+	{
+		BfNamespaceVisitor namespaceVisitor;
+		namespaceVisitor.mResolvePassData = mResolvePassData;
+		namespaceVisitor.mSystem = mSystem;
+		namespaceVisitor.Visit(mResolvePassData->mParser->mRootNode);
+	}
+
 	BfTypeDef* tempTypeDef = NULL;
 	for (auto checkTempType : mResolvePassData->mAutoCompleteTempTypes)
 	{
@@ -4248,32 +4258,66 @@ void BfCompiler::GetSymbolReferences()
 	if (mResolvePassData->mAutoComplete != NULL)
 		mResolvePassData->mAutoComplete->SetModule(module);
 	
-	const char* strPtr = mResolvePassData->mQueuedReplaceTypeDef.c_str();	
-	BfTypeDef* typeDef = mSystem->FindTypeDefEx(strPtr);
-	if ((typeDef == NULL) || (typeDef->mTypeDeclaration == NULL))
-		return;
-	mResolvePassData->mSymbolReferenceTypeDef = typeDef;
-	auto replaceType = module->ResolveTypeDef(typeDef, BfPopulateType_IdentityNoRemapAlias);
-	module->PopulateType(replaceType);
-	auto replaceTypeInst = replaceType->ToTypeInstance();
-
+	BfTypeDef* typeDef = NULL;
 	HashSet<BfTypeInstance*> rebuildTypeInstList;
-	if (mResolvePassData->mGetSymbolReferenceKind != BfGetSymbolReferenceKind_Local)	
+	if (!mResolvePassData->mQueuedSymbolReferenceNamespace.IsEmpty())
 	{
-		AddDepsToRebuildTypeList(replaceTypeInst, rebuildTypeInstList);
-		// For generic types, add all references from all specialized versions
-		if (replaceTypeInst->IsGenericTypeInstance())
+		if (!mSystem->ParseAtomComposite(mResolvePassData->mQueuedSymbolReferenceNamespace, mResolvePassData->mSymbolReferenceNamespace))
+			return;
+
+		for (auto type : mContext->mResolvedTypes)
 		{
-			for (auto type : mContext->mResolvedTypes)
+			auto typeInst = type->ToTypeInstance();
+			if (typeInst == NULL)
+				continue;				
+
+			for (auto& lookupKV : typeInst->mLookupResults)
 			{				
-				auto typeInst = type->ToTypeInstance();
-				if ((typeInst != replaceTypeInst) && (typeInst != NULL) && (typeInst->mTypeDef == typeDef))
-					AddDepsToRebuildTypeList(typeInst, rebuildTypeInstList);
-			}			
+				auto typeDef = lookupKV.mValue.mTypeDef;
+				if (typeDef->mNamespace.StartsWith(mResolvePassData->mSymbolReferenceNamespace))
+				{
+					rebuildTypeInstList.Add(typeInst);
+				}
+			}
+		}
+
+		for (auto parser : mSystem->mParsers)
+		{
+			BfNamespaceVisitor namespaceVisitor;
+			namespaceVisitor.mResolvePassData = mResolvePassData;
+			namespaceVisitor.mSystem = mSystem;
+			namespaceVisitor.Visit(parser->mRootNode);
 		}
 	}
-	
-	AddToRebuildTypeList(replaceTypeInst, rebuildTypeInstList);
+	else
+	{
+		const char* strPtr = mResolvePassData->mQueuedReplaceTypeDef.c_str();
+		typeDef = mSystem->FindTypeDefEx(strPtr);
+		if ((typeDef == NULL) || (typeDef->mTypeDeclaration == NULL))
+			return;
+
+		mResolvePassData->mSymbolReferenceTypeDef = typeDef;
+		auto replaceType = module->ResolveTypeDef(typeDef, BfPopulateType_IdentityNoRemapAlias);
+		module->PopulateType(replaceType);
+		auto replaceTypeInst = replaceType->ToTypeInstance();
+		
+		if (mResolvePassData->mGetSymbolReferenceKind != BfGetSymbolReferenceKind_Local)
+		{
+			AddDepsToRebuildTypeList(replaceTypeInst, rebuildTypeInstList);
+			// For generic types, add all references from all specialized versions
+			if (replaceTypeInst->IsGenericTypeInstance())
+			{
+				for (auto type : mContext->mResolvedTypes)
+				{
+					auto typeInst = type->ToTypeInstance();
+					if ((typeInst != replaceTypeInst) && (typeInst != NULL) && (typeInst->mTypeDef == typeDef))
+						AddDepsToRebuildTypeList(typeInst, rebuildTypeInstList);
+				}
+			}
+		}
+
+		AddToRebuildTypeList(replaceTypeInst, rebuildTypeInstList);
+	}
 
 	//TODO: Did we need this to be rebuildTypeInst->mModule???  Why?
 	//auto rebuildModule = rebuildTypeInst->mModule;
@@ -6100,6 +6144,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
 	}
 		
 	mSystem->CheckLockYield();
+
+	mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef);
 	VisitSourceExteriorNodes();
 
 	//BF_ASSERT(hasRequiredTypes);
@@ -6918,7 +6964,7 @@ void BfCompiler::GenerateAutocompleteInfo()
 		};
 
 		if (autoComplete->mResolveType == BfResolveType_GetSymbolInfo)
-		{
+		{			
 			if (autoComplete->mDefTypeGenericParamIdx != -1)
 			{
 				autoCompleteResultString += StrFormat("typeGenericParam\t%d\n", autoComplete->mDefTypeGenericParamIdx);
@@ -6953,7 +6999,11 @@ void BfCompiler::GenerateAutocompleteInfo()
 			{
 				autoCompleteResultString += StrFormat("typeRef\t%s\n", _EncodeTypeDef(autoComplete->mDefType).c_str());
 			}
-			
+			else if (!autoComplete->mDefNamespace.IsEmpty())
+			{
+				autoCompleteResultString += StrFormat("namespaceRef\t%s\n", autoComplete->mDefNamespace.ToString().c_str());
+			}
+
 			if (autoComplete->mInsertEndIdx > 0)
 			{
 				if (mResolvePassData->mParser->mSrc[autoComplete->mInsertEndIdx - 1] == '!')

+ 0 - 1
IDEHelper/Compiler/BfDefBuilder.h

@@ -1,4 +1,3 @@
-
 #include "BeefySysLib/Common.h"
 #include "BfAst.h"
 #include "BfSystem.h"

+ 36 - 14
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -6051,7 +6051,10 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
 		bool isGetDefinition = false;
 		BfAutoComplete* autoComplete = NULL;
 		if (mCompiler->IsAutocomplete())
+		{
 			autoComplete = mCompiler->mResolvePassData->mAutoComplete;
+			isGetDefinition = autoComplete->mIsGetDefinition || (autoComplete->mResolveType == BfResolveType_GetResultString);
+		}
 
 		BfSourceData* typeRefSource = NULL;
 		if (typeRef->IsTemporary())
@@ -6064,8 +6067,14 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
 		}
 		else
 			typeRefSource = typeRef->GetSourceData();
-		if ((mCompiler->mResolvePassData->mSourceClassifier != NULL) && (typeRefSource != NULL) && (mCompiler->mResolvePassData->mParser != NULL) && 
-			(typeRefSource == mCompiler->mResolvePassData->mParser->mSourceData))
+
+		bool wantsFileNamespaceInfo = (((mCompiler->mResolvePassData->mSourceClassifier != NULL) || (isGetDefinition) || (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace)) &&
+			(typeRefSource != NULL) && (mCompiler->mResolvePassData->mParser != NULL) &&
+			(typeRefSource == mCompiler->mResolvePassData->mParser->mSourceData));
+
+		bool wantsAllNamespaceInfo = (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace) && (mCompiler->mResolvePassData->mParser == NULL);
+
+		if (wantsFileNamespaceInfo || wantsAllNamespaceInfo)
 		{
 			//TODO: By only breaking out for "mIgnoreErrors", we classified elements (below) even when a resolvedTypeRef was not found!
 			//Why did we have this mIgnoreErrors check in there?
@@ -6102,7 +6111,8 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
 				StringView leftString = qualifiedTypeRef->mLeft->ToStringView();
 				BfSizedAtomComposite leftComposite;
 				bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite);
-				mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedTypeRef->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_TypeRef);
+				if (mCompiler->mResolvePassData->mSourceClassifier != NULL)
+					mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedTypeRef->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_TypeRef);
 				if (resolvedTypeInstance == NULL)
 				{
 					if ((isValid) && (mCompiler->mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject)))
@@ -6110,8 +6120,14 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
 				}
 				else if ((isValid) && (resolvedTypeInstance->mTypeDef->mNamespace.EndsWith(leftComposite)))
 				{
-					if ((autoComplete != NULL) && (autoComplete->CheckFixit(typeRef)))
-						autoComplete->FixitCheckNamespace(GetActiveTypeDef(), qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot);
+					if (autoComplete != NULL)
+					{
+						if (autoComplete->CheckFixit(typeRef))
+							autoComplete->FixitCheckNamespace(GetActiveTypeDef(), qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot);
+						autoComplete->CheckNamespace(qualifiedTypeRef->mLeft, resolvedTypeInstance->mTypeDef->mNamespace);
+					}
+					mCompiler->mResolvePassData->HandleNamespaceReference(qualifiedTypeRef->mLeft, resolvedTypeInstance->mTypeDef->mNamespace);
+					
 					isNamespace = true;
 				}
 				checkTypeRef = qualifiedTypeRef->mLeft;
@@ -6126,7 +6142,8 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
 					StringView leftString =  qualifiedNameNode->mLeft->ToStringView();
 					BfSizedAtomComposite leftComposite;
 					bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite);
-					mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedNameNode->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_TypeRef);
+					if (mCompiler->mResolvePassData->mSourceClassifier != NULL)
+						mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedNameNode->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_TypeRef);
 					if (resolvedTypeInstance == NULL)
 					{
 						if ((isValid) && (mCompiler->mSystem->ContainsNamespace(leftComposite, mCurTypeInstance->mTypeDef->mProject)))
@@ -6135,15 +6152,11 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
 					else if ((isValid) && (resolvedTypeInstance->mTypeDef->mNamespace.EndsWith(leftComposite)))
 						isNamespace = true;
 					checkNameNode = qualifiedNameNode->mLeft;
-				}				
-				mCompiler->mResolvePassData->mSourceClassifier->SetElementType(checkNameNode, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_TypeRef);
+				}
+				if (mCompiler->mResolvePassData->mSourceClassifier != NULL)
+					mCompiler->mResolvePassData->mSourceClassifier->SetElementType(checkNameNode, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_TypeRef);
 			}
 		}
-		
-		if (autoComplete != NULL)
-		{
-			isGetDefinition = autoComplete->mIsGetDefinition || (autoComplete->mResolveType == BfResolveType_GetResultString);
-		}
 
 		if (((mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Type) || (isGetDefinition)) &&
 			((resolveFlags & BfResolveTypeRefFlag_FromIndirectSource) == 0) && (resolvedTypeRef != NULL) && (typeRefSource != NULL))
@@ -6490,6 +6503,11 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric
 			return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, error);
 	}
 
+	if (typeInstance->mTypeDef->mName->ToString() == "ClassA")
+	{
+		NOP;
+	}
+
 	BfTypeLookupEntry typeLookupEntry;
 	typeLookupEntry.mName = findName;
 	typeLookupEntry.mNumGenericParams = numGenericArgs;
@@ -7282,7 +7300,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
 
 				BfTypeDef* ambiguousTypeDef = NULL;
 
-				auto typeDef = mSystem->FindTypeDef(findName, wantNumGenericArgs, bfProject, {}, &ambiguousTypeDef);
+				//auto typeDef = mSystem->FindTypeDef(findName, wantNumGenericArgs, bfProject, {}, &ambiguousTypeDef);
+
+				//auto typeDef = mSystem->FindTypeDef(findName, wantNumGenericArgs, bfProject, {}, &ambiguousTypeDef);
+				BfTypeLookupError lookupError;
+				auto typeDef = FindTypeDef(findName, wantNumGenericArgs, NULL, &lookupError);
 				if (typeDef != NULL)
 				{
 					if (ambiguousTypeDef != NULL)

+ 96 - 0
IDEHelper/Compiler/BfNamespaceVisitor.cpp

@@ -0,0 +1,96 @@
+#include "BfNamespaceVisitor.h"
+#include "BfResolvePass.h"
+#include "BfAutoComplete.h"
+
+USING_NS_BF;
+
+//////////////////////////////////////////////////////////////////////////
+
+
+void BfNamespaceVisitor::Visit(BfUsingDirective* usingDirective)
+{
+	if (usingDirective->mNamespace == NULL)
+	{		
+		return;
+	}
+	
+	String usingString = usingDirective->mNamespace->ToString();
+	BfAtomComposite usingComposite;
+	mSystem->ParseAtomComposite(usingString, usingComposite, true);
+
+	if (mResolvePassData->mAutoComplete != NULL)
+		mResolvePassData->mAutoComplete->CheckNamespace(usingDirective->mNamespace, usingComposite);
+	mResolvePassData->HandleNamespaceReference(usingDirective->mNamespace, usingComposite);
+}
+
+void BfNamespaceVisitor::Visit(BfUsingStaticDirective* usingDirective)
+{	
+	BfAstNode* useNode = usingDirective->mTypeRef;
+	BfAstNode* checkNode = usingDirective->mTypeRef;
+	while (true)
+	{		
+		if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkNode))
+			checkNode = qualifiedTypeRef->mLeft;
+		else if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(checkNode))
+		{
+			checkNode = elementedTypeRef->mElementType;
+			useNode = checkNode;
+		}
+		else
+			break;
+	}
+	
+	String usingString = useNode->ToString();
+	
+	BfAtomComposite usingComposite;
+	if (mSystem->ParseAtomComposite(usingString, usingComposite, true))
+		mResolvePassData->HandleNamespaceReference(useNode, usingComposite);
+}
+
+void BfNamespaceVisitor::Visit(BfNamespaceDeclaration* namespaceDeclaration)
+{
+	BfAtomComposite prevNamespace = mNamespace;
+	
+	if (namespaceDeclaration->mNameNode == NULL)
+		return;
+
+	Array<BfAtom*> derefAtoms;
+
+	String namespaceLeft = namespaceDeclaration->mNameNode->ToString();
+	while (true)
+	{
+		int dotIdx = (int)namespaceLeft.IndexOf('.');
+		if (dotIdx == -1)
+		{
+			BfAtom* namespaceAtom = mSystem->GetAtom(namespaceLeft);
+			mNamespace.Set(mNamespace.mParts, mNamespace.mSize, &namespaceAtom, 1);			
+			derefAtoms.Add(namespaceAtom);
+			break;
+		}
+
+		BfAtom* namespaceAtom = mSystem->GetAtom(namespaceLeft.Substring(0, dotIdx));
+		mNamespace.Set(mNamespace.mParts, mNamespace.mSize, &namespaceAtom, 1);
+		namespaceLeft = namespaceLeft.Substring(dotIdx + 1);
+
+		derefAtoms.Add(namespaceAtom);		
+	}
+
+	if (mResolvePassData->mAutoComplete != NULL)
+		mResolvePassData->mAutoComplete->CheckNamespace(namespaceDeclaration->mNameNode, mNamespace);
+	mResolvePassData->HandleNamespaceReference(namespaceDeclaration->mNameNode, mNamespace);
+	VisitChild(namespaceDeclaration->mBlock);	
+	mNamespace = prevNamespace;
+
+	for (auto atom : derefAtoms)
+		mSystem->ReleaseAtom(atom);
+}
+
+void BfNamespaceVisitor::Visit(BfBlock* block)
+{
+	VisitMembers(block);
+}
+
+void BfNamespaceVisitor::Visit(BfRootNode* rootNode)
+{
+	VisitMembers(rootNode);
+}

+ 31 - 0
IDEHelper/Compiler/BfNamespaceVisitor.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include "BfElementVisitor.h"
+#include "BfSystem.h"
+
+NS_BF_BEGIN
+
+class BfResolvePassData;
+
+class BfNamespaceVisitor : public BfStructuralVisitor
+{
+public:	
+	BfSystem* mSystem;
+	BfResolvePassData* mResolvePassData;
+	BfAtomComposite mNamespace;
+
+public:
+	BfNamespaceVisitor()
+	{
+		mSystem = NULL;
+		mResolvePassData = NULL;
+	}
+	
+	virtual void Visit(BfUsingDirective* usingDirective) override;
+	virtual void Visit(BfUsingStaticDirective* usingDirective) override;
+	virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration) override;
+	virtual void Visit(BfBlock* block) override;
+	virtual void Visit(BfRootNode* rootNode) override;
+};
+
+NS_BF_END

+ 57 - 25
IDEHelper/Compiler/BfResolvePass.cpp

@@ -105,38 +105,70 @@ void BfResolvePassData::HandleLocalReference(BfIdentifierNode* identifier, BfIde
 	}
 }
 
+BfAstNode* BfResolvePassData::FindBaseNode(BfAstNode* node)
+{
+	BfAstNode* baseNode = node;
+	while (true)
+	{
+		if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(baseNode))
+		{
+			baseNode = qualifiedTypeRef->mRight;
+		}
+		else if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(baseNode))
+		{
+			baseNode = elementedTypeRef->mElementType;
+		}
+		else if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(baseNode))
+		{
+			baseNode = namedTypeRef->mNameNode;
+		}
+		else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(baseNode))
+		{
+			baseNode = qualifiedNameNode->mRight;
+		}
+		else if (auto declTypeRef = BfNodeDynCast<BfDeclTypeRef>(baseNode))
+		{
+			baseNode = NULL;
+			break;
+		}
+		else
+			break;
+	}
+	return baseNode;
+}
+
 void BfResolvePassData::HandleTypeReference(BfAstNode* node, BfTypeDef* typeDef)
 {
 	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Type) && (mSymbolReferenceTypeDef == typeDef))
 	{
-		BfAstNode* baseNode = node;
-		while (true)
+		auto baseNode = FindBaseNode(node);
+		if (baseNode != NULL)
+			RecordReplaceNode(baseNode);
+	}
+}
+
+void BfResolvePassData::HandleNamespaceReference(BfAstNode* node, const BfAtomComposite& namespaceName)
+{
+	if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Namespace) && (namespaceName.StartsWith(mSymbolReferenceNamespace)))
+	{
+		BfAstNode* recordNode = node;
+
+		int leftCount = namespaceName.mSize - mSymbolReferenceNamespace.mSize;
+		for (int i = 0; i < leftCount; i++)
 		{
-		 	if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(baseNode))
-		 	{
-				baseNode = qualifiedTypeRef->mRight;
-		 	}
-		 	else if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(baseNode))
-		 	{
-				baseNode = elementedTypeRef->mElementType;
-		 	}
-		 	else if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(baseNode))
-		 	{
-				baseNode = namedTypeRef->mNameNode;
-		 	}
-		 	else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(baseNode))
-		 	{
-				baseNode = qualifiedNameNode->mRight;
-		 	}
-		 	else if (auto declTypeRef = BfNodeDynCast<BfDeclTypeRef>(baseNode))
-		 	{
-				baseNode = NULL;
-		 		break;
-		 	}
-		 	else
-		 		break;
+			if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(recordNode))
+			{
+				recordNode = qualifiedTypeRef->mLeft;
+			}
+			else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(recordNode))
+			{
+				recordNode = qualifiedNameNode->mLeft;
+			}
+			else
+				return;
 		}
 
+		auto baseNode = FindBaseNode(recordNode);
 		if (baseNode != NULL)
 			RecordReplaceNode(baseNode);
 	}

+ 7 - 3
IDEHelper/Compiler/BfResolvePass.h

@@ -34,7 +34,8 @@ enum BfGetSymbolReferenceKind
 	BfGetSymbolReferenceKind_Property,
 	BfGetSymbolReferenceKind_Type,
 	BfGetSymbolReferenceKind_TypeGenericParam,
-	BfGetSymbolReferenceKind_MethodGenericParam
+	BfGetSymbolReferenceKind_MethodGenericParam,
+	BfGetSymbolReferenceKind_Namespace
 };
 
 class BfResolvePassData
@@ -49,9 +50,10 @@ public:
 	Array<BfAstNode*> mExteriorAutocompleteCheckNodes;
 
 	BfGetSymbolReferenceKind mGetSymbolReferenceKind;	
-	BfTypeDef* mSymbolReferenceTypeDef;
-	
 	String mQueuedReplaceTypeDef;
+	BfTypeDef* mSymbolReferenceTypeDef;
+	String mQueuedSymbolReferenceNamespace;
+	BfAtomComposite mSymbolReferenceNamespace;		
 	int mSymbolReferenceLocalIdx;
 	int mSymbolReferenceFieldIdx;
 	int mSymbolReferenceMethodIdx;
@@ -66,6 +68,7 @@ public:
 public:
 	void RecordReplaceNode(BfParserData* parser, int srcStart, int srcLen);
 	void RecordReplaceNode(BfAstNode* node);	
+	BfAstNode* FindBaseNode(BfAstNode* node);
 
 public:
 	BfResolvePassData();
@@ -78,6 +81,7 @@ public:
 	void HandleFieldReference(BfAstNode* node, BfTypeDef* typeDef, BfFieldDef* fieldDef);
 	void HandlePropertyReference(BfAstNode* node, BfTypeDef* typeDef, BfPropertyDef* propDef);
 	void HandleTypeReference(BfAstNode* node, BfTypeDef* typeDef);	
+	void HandleNamespaceReference(BfAstNode* node, const BfAtomComposite& namespaceName);
 
 	//void ReplaceIdentifiers();
 };

+ 6 - 0
IDEHelper/Compiler/BfSystem.cpp

@@ -3341,6 +3341,12 @@ BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetSymbolReferenceTypeDef(BfResolve
 	resolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_Type;
 }
 
+BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetSymbolReferenceNamespace(BfResolvePassData* resolvePassData, const char* namespaceName)
+{
+	resolvePassData->mQueuedSymbolReferenceNamespace = namespaceName;
+	resolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_Namespace;
+}
+
 BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetSymbolReferenceFieldIdx(BfResolvePassData* resolvePassData, int fieldIdx)
 {
 	resolvePassData->mSymbolReferenceFieldIdx = fieldIdx;

+ 2 - 3
IDEHelper/DebugManager.cpp

@@ -1451,14 +1451,13 @@ BF_EXPORT void BF_CALLTYPE Debugger_ReadMemory(uintptr address, uintptr size, un
 {
 	if (gDebugger == NULL)
 		return;
-
-	//CDH TODO internally clamps to 32-bit here, need to make this more obvious in IDE memory panel etc.
 	gDebugger->ReadMemory(address, size, data);
 }
 
 BF_EXPORT void BF_CALLTYPE Debugger_WriteMemory(uintptr address, uintptr size, unsigned char* data)
 {
-	//CDH TODO internally clamps to 32-bit here, need to make this more obvious in IDE memory panel etc.
+	if (gDebugger == NULL)
+		return;
 	gDebugger->WriteMemory(address, data, size);
 }
 

+ 2 - 0
IDEHelper/IDEHelper.vcxproj

@@ -309,6 +309,7 @@
     <ClCompile Include="Compiler\BfIRBuilder.cpp" />
     <ClCompile Include="Compiler\BfIRCodeGen.cpp" />
     <ClCompile Include="Compiler\BfModuleTypeUtils.cpp" />
+    <ClCompile Include="Compiler\BfNamespaceVisitor.cpp" />
     <ClCompile Include="Compiler\BfResolvePass.cpp" />
     <ClCompile Include="Compiler\BfSource.cpp" />
     <ClCompile Include="Compiler\BfConstResolver.cpp" />
@@ -375,6 +376,7 @@
     <ClInclude Include="Compiler\BfIRBuilder.h" />
     <ClInclude Include="Compiler\BfIRCodeGen.h" />
     <ClInclude Include="Compiler\BfModuleTypeUtils.h" />
+    <ClInclude Include="Compiler\BfNamespaceVisitor.h" />
     <ClInclude Include="Compiler\BfResolvePass.h" />
     <ClInclude Include="Compiler\BfSource.h" />
     <ClInclude Include="Compiler\BfConstResolver.h" />

+ 4 - 0
IDEHelper/IDEHelper.vcxproj.filters

@@ -205,6 +205,9 @@
     <ClCompile Include="Compiler\BfTargetTriple.cpp">
       <Filter>Debugger</Filter>
     </ClCompile>
+    <ClCompile Include="Compiler\BfNamespaceVisitor.cpp">
+      <Filter>Debugger</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Compiler\BfAst.h">
@@ -389,5 +392,6 @@
     <ClInclude Include="Compiler\BfTargetTriple.h">
       <Filter>Compiler</Filter>
     </ClInclude>
+    <ClInclude Include="Compiler\BfNamespaceVisitor.h" />
   </ItemGroup>
 </Project>