1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 20:12:21 +02:00

Better handling of autocomplete with tokens

This commit is contained in:
Brian Fiete 2020-05-26 06:10:51 -07:00
parent 74f3ef4e43
commit e16e4613b6
14 changed files with 108 additions and 65 deletions

View file

@ -51,6 +51,11 @@ void BfStructuralVisitor::Visit(BfLabeledBlock* labeledBlock)
Visit(labeledBlock->ToBase()); Visit(labeledBlock->ToBase());
} }
void BfStructuralVisitor::Visit(BfErrorNode* bfErrorNode)
{
Visit(bfErrorNode->ToBase());
}
void BfStructuralVisitor::Visit(BfScopeNode* scopeNode) void BfStructuralVisitor::Visit(BfScopeNode* scopeNode)
{ {
Visit(scopeNode->ToBase()); Visit(scopeNode->ToBase());

View file

@ -399,7 +399,7 @@ public:
BfStructuralVisitor(); BfStructuralVisitor();
virtual void Visit(BfAstNode* bfAstNode) {} virtual void Visit(BfAstNode* bfAstNode) {}
virtual void Visit(BfErrorNode* bfErrorNode) {} virtual void Visit(BfErrorNode* bfErrorNode);
virtual void Visit(BfScopeNode* scopeNode); virtual void Visit(BfScopeNode* scopeNode);
virtual void Visit(BfNewNode* newNode); virtual void Visit(BfNewNode* newNode);
virtual void Visit(BfLabeledBlock* labeledBlock); virtual void Visit(BfLabeledBlock* labeledBlock);
@ -1461,15 +1461,6 @@ T* BfNodeDynCastExact(BfAstNode* node)
BfIdentifierNode* BfIdentifierCast(BfAstNode* node); BfIdentifierNode* BfIdentifierCast(BfAstNode* node);
BfAstNode* BfNodeToNonTemporary(BfAstNode* node); BfAstNode* BfNodeToNonTemporary(BfAstNode* node);
class BfErrorNode : public BfAstNode
{
public:
BF_AST_TYPE(BfErrorNode, BfAstNode);
BfAstNode* mRefNode;
}; BF_AST_DECL(BfErrorNode, BfAstNode);
class BfStatement : public BfAstNode class BfStatement : public BfAstNode
{ {
public: public:
@ -1496,6 +1487,14 @@ public:
bool VerifyIsStatement(BfPassInstance* passInstance, bool ignoreError = false); bool VerifyIsStatement(BfPassInstance* passInstance, bool ignoreError = false);
}; BF_AST_DECL(BfExpression, BfAstNode); }; BF_AST_DECL(BfExpression, BfAstNode);
class BfErrorNode : public BfExpression
{
public:
BF_AST_TYPE(BfErrorNode, BfExpression);
BfAstNode* mRefNode;
}; BF_AST_DECL(BfErrorNode, BfExpression);
class BfExpressionStatement : public BfStatement class BfExpressionStatement : public BfStatement
{ {
public: public:

View file

@ -921,7 +921,7 @@ void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringIm
// return IsInExpression(node->mParent); // return IsInExpression(node->mParent);
// } // }
void BfAutoComplete::AddTopLevelNamespaces(BfIdentifierNode* identifierNode) void BfAutoComplete::AddTopLevelNamespaces(BfAstNode* identifierNode)
{ {
String filter; String filter;
if (identifierNode != NULL) if (identifierNode != NULL)
@ -964,7 +964,7 @@ void BfAutoComplete::AddTopLevelNamespaces(BfIdentifierNode* identifierNode)
} }
} }
void BfAutoComplete::AddTopLevelTypes(BfIdentifierNode* identifierNode, bool onlyAttribute) void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttribute)
{ {
String filter; String filter;
@ -1144,7 +1144,7 @@ void BfAutoComplete::AddTopLevelTypes(BfIdentifierNode* identifierNode, bool onl
} }
} }
void BfAutoComplete::CheckIdentifier(BfIdentifierNode* identifierNode, bool isInExpression, bool isUsingDirective) void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpression, bool isUsingDirective)
{ {
if ((identifierNode != NULL) && (!IsAutocompleteNode(identifierNode))) if ((identifierNode != NULL) && (!IsAutocompleteNode(identifierNode)))
return; return;
@ -2335,12 +2335,12 @@ void BfAutoComplete::CheckResult(BfAstNode* node, const BfTypedValue& typedValue
} }
} }
void BfAutoComplete::CheckLocalDef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl) void BfAutoComplete::CheckLocalDef(BfAstNode* identifierNode, BfLocalVariable* varDecl)
{ {
CheckLocalRef(identifierNode, varDecl); CheckLocalRef(identifierNode, varDecl);
} }
void BfAutoComplete::CheckLocalRef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl) void BfAutoComplete::CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* varDecl)
{ {
if (mReplaceLocalId != -1) if (mReplaceLocalId != -1)
return; return;
@ -2406,7 +2406,7 @@ void BfAutoComplete::CheckLocalRef(BfIdentifierNode* identifierNode, BfLocalVari
} }
} }
void BfAutoComplete::CheckFieldRef(BfIdentifierNode* identifierNode, BfFieldInstance* fieldInst) void BfAutoComplete::CheckFieldRef(BfAstNode* identifierNode, BfFieldInstance* fieldInst)
{ {
if (mResolveType == BfResolveType_GetSymbolInfo) if (mResolveType == BfResolveType_GetSymbolInfo)
{ {
@ -2438,7 +2438,7 @@ void BfAutoComplete::CheckFieldRef(BfIdentifierNode* identifierNode, BfFieldInst
} }
} }
void BfAutoComplete::CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode) void BfAutoComplete::CheckLabel(BfAstNode* identifierNode, BfAstNode* precedingNode)
{ {
String filter; String filter;
if (identifierNode != NULL) if (identifierNode != NULL)

View file

@ -175,7 +175,7 @@ public:
BfAstNode* mGetDefinitionNode; BfAstNode* mGetDefinitionNode;
BfResolveType mResolveType; BfResolveType mResolveType;
BfTypeInstance* mShowAttributeProperties; BfTypeInstance* mShowAttributeProperties;
BfIdentifierNode* mIdentifierUsed; BfAstNode* mIdentifierUsed;
bool mIgnoreFixits; bool mIgnoreFixits;
bool mHasFriendSet; bool mHasFriendSet;
bool mUncertain; // May be an unknown identifier, do not aggressively autocomplete bool mUncertain; // May be an unknown identifier, do not aggressively autocomplete
@ -212,8 +212,8 @@ public:
void AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeInstance* selfType, const StringImpl& filter, bool allowPrivate); void AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeInstance* selfType, const StringImpl& filter, bool allowPrivate);
bool InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter); bool InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter);
void AddEnumTypeMembers(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate); void AddEnumTypeMembers(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate);
void AddTopLevelNamespaces(BfIdentifierNode* identifierNode); void AddTopLevelNamespaces(BfAstNode* identifierNode);
void AddTopLevelTypes(BfIdentifierNode* identifierNode, bool onlyAttribute = false); void AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttribute = false);
void AddOverrides(const StringImpl& filter); void AddOverrides(const StringImpl& filter);
void UpdateReplaceData(); void UpdateReplaceData();
void AddTypeInstanceEntry(BfTypeInstance* typeInst); void AddTypeInstanceEntry(BfTypeInstance* typeInst);
@ -233,7 +233,7 @@ public:
void RemoveMethodMatchInfo(); void RemoveMethodMatchInfo();
void ClearMethodMatchEntries(); void ClearMethodMatchEntries();
void CheckIdentifier(BfIdentifierNode* identifierNode, bool isInExpression = false, bool isUsingDirective = false); void CheckIdentifier(BfAstNode* identifierNode, bool isInExpression = false, bool isUsingDirective = false);
bool CheckMemberReference(BfAstNode* target, BfAstNode* dotToken, BfAstNode* memberName, bool onlyShowTypes = false, BfType* expectingType = NULL, bool isUsingDirective = false, bool onlyAttribute = false); bool CheckMemberReference(BfAstNode* target, BfAstNode* dotToken, BfAstNode* memberName, bool onlyShowTypes = false, BfType* expectingType = NULL, bool isUsingDirective = false, bool onlyAttribute = false);
bool CheckExplicitInterface(BfTypeInstance* interfaceType, BfAstNode* dotToken, BfAstNode* memberName); bool CheckExplicitInterface(BfTypeInstance* interfaceType, BfAstNode* dotToken, BfAstNode* memberName);
void CheckTypeRef(BfTypeReference* typeRef, bool mayBeIdentifier, bool isInExpression = false, bool onlyAttribute = false); void CheckTypeRef(BfTypeReference* typeRef, bool mayBeIdentifier, bool isInExpression = false, bool onlyAttribute = false);
@ -244,10 +244,10 @@ public:
void CheckProperty(BfPropertyDeclaration* propertyDeclaration); void CheckProperty(BfPropertyDeclaration* propertyDeclaration);
void CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedTypeRef); void CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedTypeRef);
void CheckResult(BfAstNode* node, const BfTypedValue& typedValue); void CheckResult(BfAstNode* node, const BfTypedValue& typedValue);
void CheckLocalDef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl); void CheckLocalDef(BfAstNode* identifierNode, BfLocalVariable* varDecl);
void CheckLocalRef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl); void CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* varDecl);
void CheckFieldRef(BfIdentifierNode* identifierNode, BfFieldInstance* fieldInst); void CheckFieldRef(BfAstNode* identifierNode, BfFieldInstance* fieldInst);
void CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode = NULL); void CheckLabel(BfAstNode* identifierNode, BfAstNode* precedingNode = NULL);
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

@ -125,6 +125,11 @@ void BfElementVisitor::Visit(BfLabelableStatement* labelableStmt)
} }
} }
void BfElementVisitor::Visit(BfErrorNode* bfErrorNode)
{
Visit(bfErrorNode->mRefNode);
}
void BfElementVisitor::Visit(BfScopeNode* scopeNode) void BfElementVisitor::Visit(BfScopeNode* scopeNode)
{ {
Visit(scopeNode->ToBase()); Visit(scopeNode->ToBase());

View file

@ -10,7 +10,7 @@ public:
BfElementVisitor(); BfElementVisitor();
virtual void Visit(BfAstNode* bfAstNode) {} virtual void Visit(BfAstNode* bfAstNode) {}
virtual void Visit(BfErrorNode* bfErrorNode) {} virtual void Visit(BfErrorNode* bfErrorNode);
virtual void Visit(BfScopeNode* scopeNode); virtual void Visit(BfScopeNode* scopeNode);
virtual void Visit(BfNewNode* newNode); virtual void Visit(BfNewNode* newNode);
virtual void Visit(BfLabeledBlock* labeledBlock); virtual void Visit(BfLabeledBlock* labeledBlock);

View file

@ -2290,6 +2290,15 @@ void BfExprEvaluator::Evaluate(BfAstNode* astNode, bool propogateNullConditional
} }
} }
void BfExprEvaluator::Visit(BfErrorNode* errorNode)
{
mModule->Fail("Invalid token", errorNode);
auto autoComplete = GetAutoComplete();
if (autoComplete != NULL)
autoComplete->CheckIdentifier(errorNode->mRefNode, true);
}
void BfExprEvaluator::Visit(BfTypeReference* typeRef) void BfExprEvaluator::Visit(BfTypeReference* typeRef)
{ {
mResult.mType = ResolveTypeRef(typeRef, BfPopulateType_Declaration); mResult.mType = ResolveTypeRef(typeRef, BfPopulateType_Declaration);
@ -3583,7 +3592,10 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
bool isStaticCtor = (mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor) && bool isStaticCtor = (mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor) &&
(mModule->mCurMethodInstance->mMethodDef->mIsStatic); (mModule->mCurMethodInstance->mMethodDef->mIsStatic);
if ((field->mIsReadOnly) && (!isStaticCtor)) if ((field->mIsReadOnly) && (!isStaticCtor))
retVal = mModule->LoadValue(retVal, NULL, mIsVolatileReference); {
if (retVal.IsAddr())
retVal.mKind = BfTypedValueKind_ReadOnlyAddr;
}
else else
mIsHeapReference = true; mIsHeapReference = true;
return retVal; return retVal;

View file

@ -405,6 +405,7 @@ public:
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
virtual void Visit(BfErrorNode* errorNode) override;
virtual void Visit(BfTypeReference* typeRef) override; virtual void Visit(BfTypeReference* typeRef) override;
virtual void Visit(BfAttributedExpression* attribExpr) override; virtual void Visit(BfAttributedExpression* attribExpr) override;
virtual void Visit(BfBlock* blockExpr) override; virtual void Visit(BfBlock* blockExpr) override;

View file

@ -2787,9 +2787,15 @@ void BfPrinter::Visit(BfRootNode* rootNode)
child->Accept(this); child->Accept(this);
} }
// Flush whitespace at the end of the document
BfParserData* bfParser = rootNode->GetSourceData()->ToParserData(); BfParserData* bfParser = rootNode->GetSourceData()->ToParserData();
if (bfParser != NULL) if (bfParser != NULL)
Write(rootNode, rootNode->GetSrcEnd(), bfParser->mSrcLength - rootNode->GetSrcEnd()); {
BfAstNode endNode;
BfAstNode::Zero<BfAstNode>(&endNode);
endNode.Init(rootNode->GetSrcEnd(), rootNode->GetSrcEnd(), bfParser->mSrcLength - rootNode->GetSrcEnd());
Visit(&endNode);
}
if (mCharMapping != NULL) if (mCharMapping != NULL)
{ {

View file

@ -1402,16 +1402,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
AssertCurrentNode(node); AssertCurrentNode(node);
/*if (auto block = BfNodeDynCast<BfBlock>(node))
{
HandleBlock(block, true);
return block;
}*/
auto rhsCreateExprFlags = (CreateExprFlags)(createExprFlags & CreateExprFlags_BreakOnRChevron); auto rhsCreateExprFlags = (CreateExprFlags)(createExprFlags & CreateExprFlags_BreakOnRChevron);
node = ReplaceTokenStarter(node);
auto exprLeft = BfNodeDynCast<BfExpression>(node); auto exprLeft = BfNodeDynCast<BfExpression>(node);
AssertCurrentNode(node); AssertCurrentNode(node);
@ -2431,6 +2423,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
{ {
if (nextTokenNode->GetToken() == BfToken_Dot) if (nextTokenNode->GetToken() == BfToken_Dot)
{ {
TryIdentifierConvert(checkIdx + 2);
auto nextNextCheckNode = mVisitorPos.Get(checkIdx + 2); auto nextNextCheckNode = mVisitorPos.Get(checkIdx + 2);
if (auto identifierNode = BfNodeDynCast<BfIdentifierNode>(nextNextCheckNode)) if (auto identifierNode = BfNodeDynCast<BfIdentifierNode>(nextNextCheckNode))
@ -4265,8 +4259,6 @@ BfAstNode* BfReducer::CreateStatement(BfAstNode* node, CreateStmtFlags createStm
{ {
AssertCurrentNode(node); AssertCurrentNode(node);
node = ReplaceTokenStarter(node);
if ((createStmtFlags & CreateStmtFlags_AllowUnterminatedExpression) != 0) if ((createStmtFlags & CreateStmtFlags_AllowUnterminatedExpression) != 0)
{ {
if (IsTerminatingExpression(node)) if (IsTerminatingExpression(node))
@ -5033,11 +5025,6 @@ BfTypeReference* BfReducer::CreateTypeRef(BfAstNode* firstNode, CreateTypeRefFla
} }
return CreateRefTypeRef(typeRef, tokenNode); return CreateRefTypeRef(typeRef, tokenNode);
} }
else if ((token == BfToken_In) || (token == BfToken_As))
{
// This is mostly to allow a partially typed 'int' to be parsed as 'in' to make autocomplete nicer
return CreateTypeRef(ReplaceTokenStarter(firstNode), createTypeRefFlags);
}
} }
return DoCreateTypeRef(firstNode, createTypeRefFlags); return DoCreateTypeRef(firstNode, createTypeRefFlags);
} }
@ -5107,8 +5094,20 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
auto nextNextToken = mVisitorPos.Get(mVisitorPos.mReadPos + 2); auto nextNextToken = mVisitorPos.Get(mVisitorPos.mReadPos + 2);
auto rightIdentifier = BfNodeDynCast<BfIdentifierNode>(nextNextToken); auto rightIdentifier = BfNodeDynCast<BfIdentifierNode>(nextNextToken);
if (rightIdentifier == NULL)
{
if (auto rightToken = BfNodeDynCast<BfTokenNode>(nextNextToken))
{
if (BfTokenIsKeyword(rightToken->mToken))
{
rightIdentifier = mAlloc->Alloc<BfIdentifierNode>();
ReplaceNode(rightToken, rightIdentifier);
}
}
if (rightIdentifier == NULL) if (rightIdentifier == NULL)
return leftIdentifier; return leftIdentifier;
}
// If the previous dotted span failed (IE: had chevrons) then don't insert qualified names in the middle of it // If the previous dotted span failed (IE: had chevrons) then don't insert qualified names in the middle of it
auto prevNodeToken = BfNodeDynCast<BfTokenNode>(prevNode); auto prevNodeToken = BfNodeDynCast<BfTokenNode>(prevNode);
@ -5131,6 +5130,20 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
return leftIdentifier; return leftIdentifier;
} }
void BfReducer::TryIdentifierConvert(int readPos)
{
auto node = mVisitorPos.Get(readPos);
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(node))
{
if (BfTokenIsKeyword(tokenNode->mToken))
{
auto identifierNode = mAlloc->Alloc<BfIdentifierNode>();
ReplaceNode(tokenNode, identifierNode);
mVisitorPos.Set(readPos, identifierNode);
}
}
}
void BfReducer::CreateQualifiedNames(BfAstNode* node) void BfReducer::CreateQualifiedNames(BfAstNode* node)
{ {
auto block = BfNodeDynCast<BfBlock>(node); auto block = BfNodeDynCast<BfBlock>(node);
@ -6266,8 +6279,6 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, int depth)
AssertCurrentNode(node); AssertCurrentNode(node);
node = ReplaceTokenStarter(node);
BfTokenNode* refToken = NULL; BfTokenNode* refToken = NULL;
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(node)) if (auto tokenNode = BfNodeDynCast<BfTokenNode>(node))
@ -9296,21 +9307,7 @@ void BfReducer::HandleBlock(BfBlock* block, bool allowEndingExpression)
auto statement = CreateStatement(node, flags); auto statement = CreateStatement(node, flags);
if (statement == NULL) if (statement == NULL)
{ statement = mSource->CreateErrorNode(node);
auto nextNode = mVisitorPos.GetNext();
isDone = !mVisitorPos.MoveNext();
#ifdef BF_AST_HAS_PARENT_MEMBER
BF_ASSERT(node->mParent != NULL);
#endif
node->RemoveSelf();
BF_ASSERT(node->GetSourceData() == mSource->mSourceData);
mSource->AddErrorNode(node);
if (nextNode == NULL)
break;
continue;
}
isDone = !mVisitorPos.MoveNext(); isDone = !mVisitorPos.MoveNext();
mVisitorPos.Write(statement); mVisitorPos.Write(statement);

View file

@ -185,6 +185,7 @@ public:
BfAstNode* ReadTypeMember(BfTokenNode* node, int depth = 0); BfAstNode* ReadTypeMember(BfTokenNode* node, int depth = 0);
BfAstNode* ReadTypeMember(BfAstNode* node, int depth = 0); BfAstNode* ReadTypeMember(BfAstNode* node, int depth = 0);
BfIdentifierNode* CompactQualifiedName(BfAstNode* leftNode); BfIdentifierNode* CompactQualifiedName(BfAstNode* leftNode);
void TryIdentifierConvert(int readPos);
void CreateQualifiedNames(BfAstNode* node); void CreateQualifiedNames(BfAstNode* node);
BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode); BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode);
BfFieldDeclaration* CreateFieldDeclaration(BfTokenNode* tokenNode, BfTypeReference* typeRef, BfIdentifierNode* nameIdentifier, BfFieldDeclaration* prevFieldDeclaration); BfFieldDeclaration* CreateFieldDeclaration(BfTokenNode* tokenNode, BfTypeReference* typeRef, BfIdentifierNode* nameIdentifier, BfFieldDeclaration* prevFieldDeclaration);

View file

@ -58,7 +58,7 @@ bool BfSource::WantsStats()
return ((int)parser->mFileName.IndexOf("main2.cs") != -1); return ((int)parser->mFileName.IndexOf("main2.cs") != -1);
} }
void BfSource::AddErrorNode(BfAstNode* astNode) BfErrorNode* BfSource::CreateErrorNode(BfAstNode* astNode)
{ {
BfErrorNode* errorNode = BfNodeDynCast<BfErrorNode>(astNode); BfErrorNode* errorNode = BfNodeDynCast<BfErrorNode>(astNode);
if (errorNode == NULL) if (errorNode == NULL)
@ -67,8 +67,12 @@ void BfSource::AddErrorNode(BfAstNode* astNode)
errorNode->Init(astNode->GetSrcStart(), astNode->GetSrcStart(), astNode->GetSrcEnd()); errorNode->Init(astNode->GetSrcStart(), astNode->GetSrcStart(), astNode->GetSrcEnd());
errorNode->mRefNode = astNode; errorNode->mRefNode = astNode;
} }
return errorNode;
}
mPendingErrorNodes.push_back(errorNode); void BfSource::AddErrorNode(BfAstNode* astNode)
{
mPendingErrorNodes.push_back(CreateErrorNode(astNode));
} }
int BfSource::AllocChars(int charCount) int BfSource::AllocChars(int charCount)

View file

@ -102,6 +102,7 @@ public:
virtual BfParser* ToParser() { return NULL; } virtual BfParser* ToParser() { return NULL; }
BfErrorNode* BfSource::CreateErrorNode(BfAstNode* astNode);
void AddErrorNode(BfAstNode* astNode); void AddErrorNode(BfAstNode* astNode);
int AllocChars(int charCount); int AllocChars(int charCount);
void FinishSideNodes(); void FinishSideNodes();

View file

@ -3517,6 +3517,10 @@ void BfModule::Visit(BfUncheckedStatement* uncheckedStmt)
void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool includeFalseStmt) void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool includeFalseStmt)
{ {
auto autoComplete = mCompiler->GetAutoComplete();
if (autoComplete != NULL)
autoComplete->CheckIdentifier(ifStmt->mIfToken, true);
if (ifStmt->mCondition == NULL) if (ifStmt->mCondition == NULL)
{ {
AssertErrorState(); AssertErrorState();
@ -3764,6 +3768,10 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
{ {
UpdateSrcPos(deleteStmt); UpdateSrcPos(deleteStmt);
auto autoComplete = mCompiler->GetAutoComplete();
if (autoComplete != NULL)
autoComplete->CheckIdentifier(deleteStmt->mDeleteToken, true);
bool isAppendDelete = false; bool isAppendDelete = false;
BfTypedValue customAllocator; BfTypedValue customAllocator;
if (deleteStmt->mAllocExpr != NULL) if (deleteStmt->mAllocExpr != NULL)
@ -5463,6 +5471,10 @@ void BfModule::Visit(BfWhileStatement* whileStmt)
void BfModule::Visit(BfForStatement* forStmt) void BfModule::Visit(BfForStatement* forStmt)
{ {
auto autoComplete = mCompiler->GetAutoComplete();
if (autoComplete != NULL)
autoComplete->CheckIdentifier(forStmt->mForToken, true);
UpdateSrcPos(forStmt); UpdateSrcPos(forStmt);
auto startBB = mBfIRBuilder->CreateBlock("for.start", true); auto startBB = mBfIRBuilder->CreateBlock("for.start", true);