1
0
Fork 0
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:
Brian Fiete 2020-05-29 16:58:47 -07:00
parent a7e9182d4b
commit c9da45715b
6 changed files with 86 additions and 29 deletions

View file

@ -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();

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -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:

View file

@ -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);