Browse Source

Added ability to rename labels and goto definition on labels

Brian Fiete 5 years ago
parent
commit
c9da45715b

+ 36 - 2
IDEHelper/Compiler/BfAutoComplete.cpp

@@ -2434,7 +2434,7 @@ void BfAutoComplete::CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* v
 			{
 				mInsertStartIdx = identifierNode->GetSrcStart();
 				mInsertEndIdx = identifierNode->GetSrcEnd();
-			}			
+			}
 		}
 	}	
 	else if (mResolveType == BfResolveType_GetResultString)
@@ -2489,13 +2489,47 @@ void BfAutoComplete::CheckFieldRef(BfAstNode* identifierNode, BfFieldInstance* f
 	}
 }
 
-void BfAutoComplete::CheckLabel(BfAstNode* identifierNode, BfAstNode* precedingNode)
+void BfAutoComplete::CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode, BfScopeData* scopeData)
 {
 	String filter;
 	if (identifierNode != NULL)
 	{
+		if ((mModule->mCompiler->mResolvePassData != NULL) && (scopeData != NULL))
+		{			
+			auto rootMethodState = mModule->mCurMethodState->GetRootMethodState();
+			mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, rootMethodState->mMethodInstance->GetOwner()->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, scopeData->mScopeLocalId);
+		}
+
 		if (!IsAutocompleteNode(identifierNode))
 			return;
+		
+		if (scopeData != NULL)
+		{
+			if (mResolveType == BfResolveType_GoToDefinition)
+			{
+				SetDefinitionLocation(scopeData->mLabelNode);
+			}
+			else if (mResolveType == BfResolveType_GetSymbolInfo)
+			{
+				auto rootMethodInstance = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance;
+				if (rootMethodInstance == NULL)
+					return;
+
+				mDefType = mModule->mCurTypeInstance->mTypeDef;
+
+				mReplaceLocalId = scopeData->mScopeLocalId;
+				mDefMethod = rootMethodInstance->mMethodDef;
+				if (mInsertStartIdx == -1)
+				{
+					mInsertStartIdx = identifierNode->GetSrcStart();
+					mInsertEndIdx = identifierNode->GetSrcEnd();
+				}
+			}
+
+			if (scopeData->mLabelNode == identifierNode)
+				return;
+		}
+
 		filter = identifierNode->ToString();
 		mInsertStartIdx = identifierNode->GetSrcStart();
 		mInsertEndIdx = identifierNode->GetSrcEnd();

+ 2 - 2
IDEHelper/Compiler/BfAutoComplete.h

@@ -246,8 +246,8 @@ public:
 	void CheckResult(BfAstNode* node, const BfTypedValue& typedValue);
 	void CheckLocalDef(BfAstNode* identifierNode, BfLocalVariable* varDecl);
 	void CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* varDecl);
-	void CheckFieldRef(BfAstNode* identifierNode, BfFieldInstance* fieldInst);
-	void CheckLabel(BfAstNode* identifierNode, BfAstNode* precedingNode = NULL);
+	void CheckFieldRef(BfAstNode* identifierNode, BfFieldInstance* fieldInst);	
+	void CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode, BfScopeData* scopeData);
 	void CheckEmptyStart(BfAstNode* prevNode, BfType* type);	
 	bool CheckFixit(BfAstNode* node);	
 	void CheckInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode* node);

+ 7 - 0
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -12964,7 +12964,14 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
 	{
 		auto targetScope = mModule->FindScope(scopedInvocationTarget->mScopeName, curMethodState->mMixinState);
 		if (targetScope != NULL)
+		{
 			mixinState->mTargetScope = targetScope;
+			if (autoComplete != NULL)
+			{
+				if (auto identifer = BfNodeDynCast<BfIdentifierNode>(scopedInvocationTarget->mScopeName))
+					autoComplete->CheckLabel(identifer, NULL, targetScope);
+			}
+		}
 	}
 	
 	mModule->mBfIRBuilder->SaveDebugLocation();

+ 8 - 0
IDEHelper/Compiler/BfModule.cpp

@@ -1654,8 +1654,16 @@ void BfModule::NewScopeState(bool createLexicalBlock, bool flushValueScope)
 {
 	auto curScope = mCurMethodState->mCurScope;
 	if (curScope->mLabelNode != NULL)
+	{
 		curScope->mLabelNode->ToString(curScope->mLabel);
 
+		auto rootMethodState = mCurMethodState->GetRootMethodState();
+		curScope->mScopeLocalId = rootMethodState->mCurLocalVarId++;
+		auto autoComplete = mCompiler->GetAutoComplete();
+		if (autoComplete != NULL)
+			autoComplete->CheckLabel(curScope->mLabelNode, NULL, curScope);		
+	}
+
 	if (!mCurMethodState->mCurScope->mLabel.IsEmpty())
 	{
 		auto checkScope = mCurMethodState->mCurScope->mPrevScope;

+ 5 - 3
IDEHelper/Compiler/BfModule.h

@@ -303,10 +303,11 @@ public:
 	BfIRMDNode mDIScope;
 	BfIRMDNode mDIInlinedAt;	
 	String mLabel;
-	BfAstNode* mLabelNode;
+	BfIdentifierNode* mLabelNode;
 	int mLocalVarStart;		
 	int mScopeDepth;
-	int mMixinDepth;	
+	int mMixinDepth;
+	int mScopeLocalId;
 	bool mIsScopeHead; // For first scope data or for inlined start
 	bool mIsLoop;
 	bool mIsConditional; // Rarely set - usually we rely on OuterIsConditional or InnerIsConditional
@@ -352,6 +353,7 @@ public:
 		mAllowVariableDeclarations = true;
 		mMixinDepth = 0;
 		mScopeDepth = 0;
+		mScopeLocalId = -1;
 	}	
 
 	~BfScopeData()
@@ -937,7 +939,7 @@ public:
 	bool mAllowUinitReads;
 	bool mCancelledDeferredCall;	
 	bool mNoObjectAccessChecks;
-	int mCurLocalVarId;
+	int mCurLocalVarId; // Can also refer to a label
 	int mCurAccessId; // For checking to see if a block reads from or writes to a local
 
 public:

+ 28 - 22
IDEHelper/Compiler/BfStmtEvaluator.cpp

@@ -4950,13 +4950,7 @@ void BfModule::Visit(BfYieldStatement* yieldStmt)
 void BfModule::Visit(BfBreakStatement* breakStmt)
 {
 	bool inMixinDecl = (mCurMethodInstance != NULL) && (mCurMethodInstance->IsMixin());
-
-	if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
-	{
-		if (auto identifer = BfNodeDynCast<BfIdentifierNode>(breakStmt->mLabel))
-			mCompiler->mResolvePassData->mAutoComplete->CheckLabel(identifer, breakStmt->mBreakNode);
-	}
-
+	
 	UpdateSrcPos(breakStmt);
 	mBfIRBuilder->CreateEnsureInstructionAt();
 
@@ -4975,6 +4969,15 @@ void BfModule::Visit(BfBreakStatement* breakStmt)
 		}		
 	}
 
+	if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
+	{
+		BfScopeData* scope = NULL;
+		if (breakData != NULL)
+			scope = breakData->mScope;
+		if (auto identifer = BfNodeDynCast<BfIdentifierNode>(breakStmt->mLabel))
+			mCompiler->mResolvePassData->mAutoComplete->CheckLabel(identifer, breakStmt->mBreakNode, scope);
+	}
+
 	if ((breakData == NULL) || (!breakData->mIRBreakBlock))
 	{		
 		if (inMixinDecl)
@@ -5038,13 +5041,7 @@ void BfModule::Visit(BfBreakStatement* breakStmt)
 void BfModule::Visit(BfContinueStatement* continueStmt)
 {
 	bool inMixinDecl = (mCurMethodInstance != NULL) && (mCurMethodInstance->IsMixin());
-
-	if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
-	{
-		if (auto identifer = BfNodeDynCast<BfIdentifierNode>(continueStmt->mLabel))
-			mCompiler->mResolvePassData->mAutoComplete->CheckLabel(identifer, continueStmt->mContinueNode);
-	}
-	
+		
 	UpdateSrcPos(continueStmt);
 	mBfIRBuilder->CreateEnsureInstructionAt();
 
@@ -5069,6 +5066,15 @@ void BfModule::Visit(BfContinueStatement* continueStmt)
 		}
 	}	
 
+	if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
+	{
+		BfScopeData* scope = NULL;
+		if (breakData != NULL)
+			scope = breakData->mScope;
+		if (auto identifer = BfNodeDynCast<BfIdentifierNode>(continueStmt->mLabel))
+			mCompiler->mResolvePassData->mAutoComplete->CheckLabel(identifer, continueStmt->mContinueNode, scope);
+	}
+
 	if ((breakData == NULL) || (!breakData->mIRContinueBlock))
 	{
 		if (inMixinDecl)
@@ -6489,14 +6495,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
 
 	UpdateSrcPos(deferStmt);	
 	EmitEnsureInstructionAt();
-	
-	if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
-	{
-		auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(deferStmt->mScopeName);
-		if ((deferStmt->mScopeName == NULL) || (targetIdentifier != NULL))
-			mCompiler->mResolvePassData->mAutoComplete->CheckLabel(targetIdentifier, deferStmt->mColonToken);		
-	}
-
+		
 	BfScopeData* scope = NULL;
 
 	if (deferStmt->mScopeToken != NULL)
@@ -6511,6 +6510,13 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
 	else
 		scope = mCurMethodState->mCurScope;
 
+	if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
+	{		
+		auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(deferStmt->mScopeName);
+		if ((deferStmt->mScopeName == NULL) || (targetIdentifier != NULL))
+			mCompiler->mResolvePassData->mAutoComplete->CheckLabel(targetIdentifier, deferStmt->mColonToken, scope);
+	}
+
 	if ((scope == mCurMethodState->mCurScope) && (scope->mCloseNode == NULL))
 	{
 		Warn(0, "This defer will immediately execute. Consider specifying a wider scope target such as 'defer::'", deferStmt->mDeferToken);