From 014263c3a704898100b0f8d34f474c3e8525427d Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 31 May 2020 07:12:17 -0700 Subject: [PATCH] Added ability to rename namespaces --- IDE/src/Compiler/BfParser.bf | 1 + IDE/src/Compiler/BfResolvePassData.bf | 10 ++- IDE/src/ui/RenameSymbolDialog.bf | 5 ++ IDEHelper/Compiler/BfAutoComplete.cpp | 37 +++++++++ IDEHelper/Compiler/BfAutoComplete.h | 7 +- IDEHelper/Compiler/BfCompiler.cpp | 98 +++++++++++++++++------ IDEHelper/Compiler/BfDefBuilder.h | 1 - IDEHelper/Compiler/BfModuleTypeUtils.cpp | 50 ++++++++---- IDEHelper/Compiler/BfNamespaceVisitor.cpp | 96 ++++++++++++++++++++++ IDEHelper/Compiler/BfNamespaceVisitor.h | 31 +++++++ IDEHelper/Compiler/BfResolvePass.cpp | 88 +++++++++++++------- IDEHelper/Compiler/BfResolvePass.h | 10 ++- IDEHelper/Compiler/BfSystem.cpp | 6 ++ IDEHelper/DebugManager.cpp | 5 +- IDEHelper/IDEHelper.vcxproj | 2 + IDEHelper/IDEHelper.vcxproj.filters | 4 + 16 files changed, 373 insertions(+), 78 deletions(-) create mode 100644 IDEHelper/Compiler/BfNamespaceVisitor.cpp create mode 100644 IDEHelper/Compiler/BfNamespaceVisitor.h diff --git a/IDE/src/Compiler/BfParser.bf b/IDE/src/Compiler/BfParser.bf index 71ac7c5e..611ac727 100644 --- a/IDE/src/Compiler/BfParser.bf +++ b/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; diff --git a/IDE/src/Compiler/BfResolvePassData.bf b/IDE/src/Compiler/BfResolvePassData.bf index 50b74d11..9d7ebccc 100644 --- a/IDE/src/Compiler/BfResolvePassData.bf +++ b/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); diff --git a/IDE/src/ui/RenameSymbolDialog.bf b/IDE/src/ui/RenameSymbolDialog.bf index 51e43662..f8261b1f 100644 --- a/IDE/src/ui/RenameSymbolDialog.bf +++ b/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; diff --git a/IDEHelper/Compiler/BfAutoComplete.cpp b/IDEHelper/Compiler/BfAutoComplete.cpp index 2cb0fa17..ce8f0882 100644 --- a/IDEHelper/Compiler/BfAutoComplete.cpp +++ b/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(checkNode)) + { + if (!IsAutocompleteNode(qualifiedTypeRef->mLeft)) + break; + namespaceCount--; + checkNode = qualifiedTypeRef->mLeft; + } + while (auto qualifiedNameNode = BfNodeDynCast(checkNode)) + { + if (!IsAutocompleteNode(qualifiedNameNode->mLeft)) + break; + namespaceCount--; + checkNode = qualifiedNameNode->mLeft; + } + + while (auto qualifiedTypeRef = BfNodeDynCast(checkNode)) + checkNode = qualifiedTypeRef->mRight; + while (auto qualifiedNameNode = BfNodeDynCast(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); diff --git a/IDEHelper/Compiler/BfAutoComplete.h b/IDEHelper/Compiler/BfAutoComplete.h index 0a56eed7..1005170e 100644 --- a/IDEHelper/Compiler/BfAutoComplete.h +++ b/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); diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 656c2ce0..49731cdf 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/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 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 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 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] == '!') diff --git a/IDEHelper/Compiler/BfDefBuilder.h b/IDEHelper/Compiler/BfDefBuilder.h index acd6c8f0..d3be35cd 100644 --- a/IDEHelper/Compiler/BfDefBuilder.h +++ b/IDEHelper/Compiler/BfDefBuilder.h @@ -1,4 +1,3 @@ - #include "BeefySysLib/Common.h" #include "BfAst.h" #include "BfSystem.h" diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 95f7b26b..7b324789 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/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) diff --git a/IDEHelper/Compiler/BfNamespaceVisitor.cpp b/IDEHelper/Compiler/BfNamespaceVisitor.cpp new file mode 100644 index 00000000..821bc8ba --- /dev/null +++ b/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(checkNode)) + checkNode = qualifiedTypeRef->mLeft; + else if (auto elementedTypeRef = BfNodeDynCast(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 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); +} diff --git a/IDEHelper/Compiler/BfNamespaceVisitor.h b/IDEHelper/Compiler/BfNamespaceVisitor.h new file mode 100644 index 00000000..0f59dca5 --- /dev/null +++ b/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 \ No newline at end of file diff --git a/IDEHelper/Compiler/BfResolvePass.cpp b/IDEHelper/Compiler/BfResolvePass.cpp index d3d35f98..4502e3eb 100644 --- a/IDEHelper/Compiler/BfResolvePass.cpp +++ b/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(baseNode)) + { + baseNode = qualifiedTypeRef->mRight; + } + else if (auto elementedTypeRef = BfNodeDynCast(baseNode)) + { + baseNode = elementedTypeRef->mElementType; + } + else if (auto namedTypeRef = BfNodeDynCast(baseNode)) + { + baseNode = namedTypeRef->mNameNode; + } + else if (auto qualifiedNameNode = BfNodeDynCast(baseNode)) + { + baseNode = qualifiedNameNode->mRight; + } + else if (auto declTypeRef = BfNodeDynCast(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) - { - if (auto qualifiedTypeRef = BfNodeDynCast(baseNode)) - { - baseNode = qualifiedTypeRef->mRight; - } - else if (auto elementedTypeRef = BfNodeDynCast(baseNode)) - { - baseNode = elementedTypeRef->mElementType; - } - else if (auto namedTypeRef = BfNodeDynCast(baseNode)) - { - baseNode = namedTypeRef->mNameNode; - } - else if (auto qualifiedNameNode = BfNodeDynCast(baseNode)) - { - baseNode = qualifiedNameNode->mRight; - } - else if (auto declTypeRef = BfNodeDynCast(baseNode)) - { - baseNode = NULL; - break; - } - else - break; - } - + 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(recordNode)) + { + recordNode = qualifiedTypeRef->mLeft; + } + else if (auto qualifiedNameNode = BfNodeDynCast(recordNode)) + { + recordNode = qualifiedNameNode->mLeft; + } + else + return; + } + + auto baseNode = FindBaseNode(recordNode); if (baseNode != NULL) RecordReplaceNode(baseNode); } diff --git a/IDEHelper/Compiler/BfResolvePass.h b/IDEHelper/Compiler/BfResolvePass.h index 71180746..db73f5a7 100644 --- a/IDEHelper/Compiler/BfResolvePass.h +++ b/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 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(); }; diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index e0630628..3694c2f2 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/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; diff --git a/IDEHelper/DebugManager.cpp b/IDEHelper/DebugManager.cpp index 386ed176..2ba0f72a 100644 --- a/IDEHelper/DebugManager.cpp +++ b/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); } diff --git a/IDEHelper/IDEHelper.vcxproj b/IDEHelper/IDEHelper.vcxproj index 155eef07..dad92d12 100644 --- a/IDEHelper/IDEHelper.vcxproj +++ b/IDEHelper/IDEHelper.vcxproj @@ -309,6 +309,7 @@ + @@ -375,6 +376,7 @@ + diff --git a/IDEHelper/IDEHelper.vcxproj.filters b/IDEHelper/IDEHelper.vcxproj.filters index 984f6941..1f9bcd9d 100644 --- a/IDEHelper/IDEHelper.vcxproj.filters +++ b/IDEHelper/IDEHelper.vcxproj.filters @@ -205,6 +205,9 @@ Debugger + + Debugger + @@ -389,5 +392,6 @@ Compiler + \ No newline at end of file