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
|
@ -2434,7 +2434,7 @@ void BfAutoComplete::CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* v
|
||||||
{
|
{
|
||||||
mInsertStartIdx = identifierNode->GetSrcStart();
|
mInsertStartIdx = identifierNode->GetSrcStart();
|
||||||
mInsertEndIdx = identifierNode->GetSrcEnd();
|
mInsertEndIdx = identifierNode->GetSrcEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mResolveType == BfResolveType_GetResultString)
|
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;
|
String filter;
|
||||||
if (identifierNode != NULL)
|
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))
|
if (!IsAutocompleteNode(identifierNode))
|
||||||
return;
|
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();
|
filter = identifierNode->ToString();
|
||||||
mInsertStartIdx = identifierNode->GetSrcStart();
|
mInsertStartIdx = identifierNode->GetSrcStart();
|
||||||
mInsertEndIdx = identifierNode->GetSrcEnd();
|
mInsertEndIdx = identifierNode->GetSrcEnd();
|
||||||
|
|
|
@ -246,8 +246,8 @@ public:
|
||||||
void CheckResult(BfAstNode* node, const BfTypedValue& typedValue);
|
void CheckResult(BfAstNode* node, const BfTypedValue& typedValue);
|
||||||
void CheckLocalDef(BfAstNode* identifierNode, BfLocalVariable* varDecl);
|
void CheckLocalDef(BfAstNode* identifierNode, BfLocalVariable* varDecl);
|
||||||
void CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* varDecl);
|
void CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* varDecl);
|
||||||
void CheckFieldRef(BfAstNode* identifierNode, BfFieldInstance* fieldInst);
|
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);
|
void CheckEmptyStart(BfAstNode* prevNode, BfType* type);
|
||||||
bool CheckFixit(BfAstNode* node);
|
bool CheckFixit(BfAstNode* node);
|
||||||
void CheckInterfaceFixit(BfTypeInstance* typeInstance, 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);
|
auto targetScope = mModule->FindScope(scopedInvocationTarget->mScopeName, curMethodState->mMixinState);
|
||||||
if (targetScope != NULL)
|
if (targetScope != NULL)
|
||||||
|
{
|
||||||
mixinState->mTargetScope = targetScope;
|
mixinState->mTargetScope = targetScope;
|
||||||
|
if (autoComplete != NULL)
|
||||||
|
{
|
||||||
|
if (auto identifer = BfNodeDynCast<BfIdentifierNode>(scopedInvocationTarget->mScopeName))
|
||||||
|
autoComplete->CheckLabel(identifer, NULL, targetScope);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mModule->mBfIRBuilder->SaveDebugLocation();
|
mModule->mBfIRBuilder->SaveDebugLocation();
|
||||||
|
|
|
@ -1654,8 +1654,16 @@ void BfModule::NewScopeState(bool createLexicalBlock, bool flushValueScope)
|
||||||
{
|
{
|
||||||
auto curScope = mCurMethodState->mCurScope;
|
auto curScope = mCurMethodState->mCurScope;
|
||||||
if (curScope->mLabelNode != NULL)
|
if (curScope->mLabelNode != NULL)
|
||||||
|
{
|
||||||
curScope->mLabelNode->ToString(curScope->mLabel);
|
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())
|
if (!mCurMethodState->mCurScope->mLabel.IsEmpty())
|
||||||
{
|
{
|
||||||
auto checkScope = mCurMethodState->mCurScope->mPrevScope;
|
auto checkScope = mCurMethodState->mCurScope->mPrevScope;
|
||||||
|
|
|
@ -303,10 +303,11 @@ public:
|
||||||
BfIRMDNode mDIScope;
|
BfIRMDNode mDIScope;
|
||||||
BfIRMDNode mDIInlinedAt;
|
BfIRMDNode mDIInlinedAt;
|
||||||
String mLabel;
|
String mLabel;
|
||||||
BfAstNode* mLabelNode;
|
BfIdentifierNode* mLabelNode;
|
||||||
int mLocalVarStart;
|
int mLocalVarStart;
|
||||||
int mScopeDepth;
|
int mScopeDepth;
|
||||||
int mMixinDepth;
|
int mMixinDepth;
|
||||||
|
int mScopeLocalId;
|
||||||
bool mIsScopeHead; // For first scope data or for inlined start
|
bool mIsScopeHead; // For first scope data or for inlined start
|
||||||
bool mIsLoop;
|
bool mIsLoop;
|
||||||
bool mIsConditional; // Rarely set - usually we rely on OuterIsConditional or InnerIsConditional
|
bool mIsConditional; // Rarely set - usually we rely on OuterIsConditional or InnerIsConditional
|
||||||
|
@ -352,6 +353,7 @@ public:
|
||||||
mAllowVariableDeclarations = true;
|
mAllowVariableDeclarations = true;
|
||||||
mMixinDepth = 0;
|
mMixinDepth = 0;
|
||||||
mScopeDepth = 0;
|
mScopeDepth = 0;
|
||||||
|
mScopeLocalId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
~BfScopeData()
|
~BfScopeData()
|
||||||
|
@ -937,7 +939,7 @@ public:
|
||||||
bool mAllowUinitReads;
|
bool mAllowUinitReads;
|
||||||
bool mCancelledDeferredCall;
|
bool mCancelledDeferredCall;
|
||||||
bool mNoObjectAccessChecks;
|
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
|
int mCurAccessId; // For checking to see if a block reads from or writes to a local
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -4950,13 +4950,7 @@ void BfModule::Visit(BfYieldStatement* yieldStmt)
|
||||||
void BfModule::Visit(BfBreakStatement* breakStmt)
|
void BfModule::Visit(BfBreakStatement* breakStmt)
|
||||||
{
|
{
|
||||||
bool inMixinDecl = (mCurMethodInstance != NULL) && (mCurMethodInstance->IsMixin());
|
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);
|
UpdateSrcPos(breakStmt);
|
||||||
mBfIRBuilder->CreateEnsureInstructionAt();
|
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 ((breakData == NULL) || (!breakData->mIRBreakBlock))
|
||||||
{
|
{
|
||||||
if (inMixinDecl)
|
if (inMixinDecl)
|
||||||
|
@ -5038,13 +5041,7 @@ void BfModule::Visit(BfBreakStatement* breakStmt)
|
||||||
void BfModule::Visit(BfContinueStatement* continueStmt)
|
void BfModule::Visit(BfContinueStatement* continueStmt)
|
||||||
{
|
{
|
||||||
bool inMixinDecl = (mCurMethodInstance != NULL) && (mCurMethodInstance->IsMixin());
|
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);
|
UpdateSrcPos(continueStmt);
|
||||||
mBfIRBuilder->CreateEnsureInstructionAt();
|
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 ((breakData == NULL) || (!breakData->mIRContinueBlock))
|
||||||
{
|
{
|
||||||
if (inMixinDecl)
|
if (inMixinDecl)
|
||||||
|
@ -6489,14 +6495,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
||||||
|
|
||||||
UpdateSrcPos(deferStmt);
|
UpdateSrcPos(deferStmt);
|
||||||
EmitEnsureInstructionAt();
|
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;
|
BfScopeData* scope = NULL;
|
||||||
|
|
||||||
if (deferStmt->mScopeToken != NULL)
|
if (deferStmt->mScopeToken != NULL)
|
||||||
|
@ -6511,6 +6510,13 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
||||||
else
|
else
|
||||||
scope = mCurMethodState->mCurScope;
|
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))
|
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);
|
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