mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Added ability to rename labels and goto definition on labels
This commit is contained in:
parent
a7e9182d4b
commit
c9da45715b
6 changed files with 86 additions and 29 deletions
|
@ -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();
|
||||
|
|
|
@ -247,7 +247,7 @@ public:
|
|||
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 CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode, BfScopeData* scopeData);
|
||||
void CheckEmptyStart(BfAstNode* prevNode, BfType* type);
|
||||
bool CheckFixit(BfAstNode* node);
|
||||
void CheckInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode* node);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -303,10 +303,11 @@ public:
|
|||
BfIRMDNode mDIScope;
|
||||
BfIRMDNode mDIInlinedAt;
|
||||
String mLabel;
|
||||
BfAstNode* mLabelNode;
|
||||
BfIdentifierNode* mLabelNode;
|
||||
int mLocalVarStart;
|
||||
int mScopeDepth;
|
||||
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:
|
||||
|
|
|
@ -4951,12 +4951,6 @@ 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)
|
||||
|
@ -5039,12 +5042,6 @@ 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)
|
||||
|
@ -6490,13 +6496,6 @@ 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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue