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());
}
void BfStructuralVisitor::Visit(BfErrorNode* bfErrorNode)
{
Visit(bfErrorNode->ToBase());
}
void BfStructuralVisitor::Visit(BfScopeNode* scopeNode)
{
Visit(scopeNode->ToBase());

View file

@ -399,7 +399,7 @@ public:
BfStructuralVisitor();
virtual void Visit(BfAstNode* bfAstNode) {}
virtual void Visit(BfErrorNode* bfErrorNode) {}
virtual void Visit(BfErrorNode* bfErrorNode);
virtual void Visit(BfScopeNode* scopeNode);
virtual void Visit(BfNewNode* newNode);
virtual void Visit(BfLabeledBlock* labeledBlock);
@ -1461,15 +1461,6 @@ T* BfNodeDynCastExact(BfAstNode* node)
BfIdentifierNode* BfIdentifierCast(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
{
public:
@ -1496,6 +1487,14 @@ public:
bool VerifyIsStatement(BfPassInstance* passInstance, bool ignoreError = false);
}; 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
{
public:

View file

@ -921,7 +921,7 @@ void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringIm
// return IsInExpression(node->mParent);
// }
void BfAutoComplete::AddTopLevelNamespaces(BfIdentifierNode* identifierNode)
void BfAutoComplete::AddTopLevelNamespaces(BfAstNode* identifierNode)
{
String filter;
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;
@ -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)))
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);
}
void BfAutoComplete::CheckLocalRef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl)
void BfAutoComplete::CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* varDecl)
{
if (mReplaceLocalId != -1)
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)
{
@ -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;
if (identifierNode != NULL)

View file

@ -175,7 +175,7 @@ public:
BfAstNode* mGetDefinitionNode;
BfResolveType mResolveType;
BfTypeInstance* mShowAttributeProperties;
BfIdentifierNode* mIdentifierUsed;
BfAstNode* mIdentifierUsed;
bool mIgnoreFixits;
bool mHasFriendSet;
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);
bool InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter);
void AddEnumTypeMembers(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate);
void AddTopLevelNamespaces(BfIdentifierNode* identifierNode);
void AddTopLevelTypes(BfIdentifierNode* identifierNode, bool onlyAttribute = false);
void AddTopLevelNamespaces(BfAstNode* identifierNode);
void AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttribute = false);
void AddOverrides(const StringImpl& filter);
void UpdateReplaceData();
void AddTypeInstanceEntry(BfTypeInstance* typeInst);
@ -233,7 +233,7 @@ public:
void RemoveMethodMatchInfo();
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 CheckExplicitInterface(BfTypeInstance* interfaceType, BfAstNode* dotToken, BfAstNode* memberName);
void CheckTypeRef(BfTypeReference* typeRef, bool mayBeIdentifier, bool isInExpression = false, bool onlyAttribute = false);
@ -244,10 +244,10 @@ public:
void CheckProperty(BfPropertyDeclaration* propertyDeclaration);
void CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedTypeRef);
void CheckResult(BfAstNode* node, const BfTypedValue& typedValue);
void CheckLocalDef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl);
void CheckLocalRef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl);
void CheckFieldRef(BfIdentifierNode* identifierNode, BfFieldInstance* fieldInst);
void CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode = NULL);
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 CheckEmptyStart(BfAstNode* prevNode, BfType* type);
bool CheckFixit(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)
{
Visit(scopeNode->ToBase());

View file

@ -10,7 +10,7 @@ public:
BfElementVisitor();
virtual void Visit(BfAstNode* bfAstNode) {}
virtual void Visit(BfErrorNode* bfErrorNode) {}
virtual void Visit(BfErrorNode* bfErrorNode);
virtual void Visit(BfScopeNode* scopeNode);
virtual void Visit(BfNewNode* newNode);
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)
{
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) &&
(mModule->mCurMethodInstance->mMethodDef->mIsStatic);
if ((field->mIsReadOnly) && (!isStaticCtor))
retVal = mModule->LoadValue(retVal, NULL, mIsVolatileReference);
{
if (retVal.IsAddr())
retVal.mKind = BfTypedValueKind_ReadOnlyAddr;
}
else
mIsHeapReference = true;
return retVal;

View file

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

View file

@ -2787,9 +2787,15 @@ void BfPrinter::Visit(BfRootNode* rootNode)
child->Accept(this);
}
// Flush whitespace at the end of the document
BfParserData* bfParser = rootNode->GetSourceData()->ToParserData();
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)
{

View file

@ -1402,16 +1402,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
AssertCurrentNode(node);
/*if (auto block = BfNodeDynCast<BfBlock>(node))
{
HandleBlock(block, true);
return block;
}*/
auto rhsCreateExprFlags = (CreateExprFlags)(createExprFlags & CreateExprFlags_BreakOnRChevron);
node = ReplaceTokenStarter(node);
auto exprLeft = BfNodeDynCast<BfExpression>(node);
AssertCurrentNode(node);
@ -2431,6 +2423,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
{
if (nextTokenNode->GetToken() == BfToken_Dot)
{
TryIdentifierConvert(checkIdx + 2);
auto nextNextCheckNode = mVisitorPos.Get(checkIdx + 2);
if (auto identifierNode = BfNodeDynCast<BfIdentifierNode>(nextNextCheckNode))
@ -4265,8 +4259,6 @@ BfAstNode* BfReducer::CreateStatement(BfAstNode* node, CreateStmtFlags createStm
{
AssertCurrentNode(node);
node = ReplaceTokenStarter(node);
if ((createStmtFlags & CreateStmtFlags_AllowUnterminatedExpression) != 0)
{
if (IsTerminatingExpression(node))
@ -5033,11 +5025,6 @@ BfTypeReference* BfReducer::CreateTypeRef(BfAstNode* firstNode, CreateTypeRefFla
}
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);
}
@ -5107,8 +5094,20 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
auto nextNextToken = mVisitorPos.Get(mVisitorPos.mReadPos + 2);
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)
return leftIdentifier;
}
// 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);
@ -5131,6 +5130,20 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
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)
{
auto block = BfNodeDynCast<BfBlock>(node);
@ -6266,8 +6279,6 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, int depth)
AssertCurrentNode(node);
node = ReplaceTokenStarter(node);
BfTokenNode* refToken = NULL;
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(node))
@ -9296,21 +9307,7 @@ void BfReducer::HandleBlock(BfBlock* block, bool allowEndingExpression)
auto statement = CreateStatement(node, flags);
if (statement == NULL)
{
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;
}
statement = mSource->CreateErrorNode(node);
isDone = !mVisitorPos.MoveNext();
mVisitorPos.Write(statement);

View file

@ -185,6 +185,7 @@ public:
BfAstNode* ReadTypeMember(BfTokenNode* node, int depth = 0);
BfAstNode* ReadTypeMember(BfAstNode* node, int depth = 0);
BfIdentifierNode* CompactQualifiedName(BfAstNode* leftNode);
void TryIdentifierConvert(int readPos);
void CreateQualifiedNames(BfAstNode* node);
BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode);
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);
}
void BfSource::AddErrorNode(BfAstNode* astNode)
BfErrorNode* BfSource::CreateErrorNode(BfAstNode* astNode)
{
BfErrorNode* errorNode = BfNodeDynCast<BfErrorNode>(astNode);
if (errorNode == NULL)
@ -67,8 +67,12 @@ void BfSource::AddErrorNode(BfAstNode* astNode)
errorNode->Init(astNode->GetSrcStart(), astNode->GetSrcStart(), astNode->GetSrcEnd());
errorNode->mRefNode = astNode;
}
return errorNode;
}
mPendingErrorNodes.push_back(errorNode);
void BfSource::AddErrorNode(BfAstNode* astNode)
{
mPendingErrorNodes.push_back(CreateErrorNode(astNode));
}
int BfSource::AllocChars(int charCount)

View file

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

View file

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