1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00
Beef/IDEHelper/Compiler/BfSourceClassifier.cpp

882 lines
No EOL
23 KiB
C++

#include "BfSourceClassifier.h"
#include "BfParser.h"
#include "BeefySysLib/util/BeefPerf.h"
USING_NS_BF;
BfSourceClassifier::BfSourceClassifier(BfParser* bfParser, CharData* charData)
{
mParser = bfParser;
mCharData = charData;
mSkipMethodInternals = false;
mSkipTypeDeclarations = false;
mSkipAttributes = false;
mIsSideChannel = false;
mPreserveFlags = false;
mClassifierPassId = 0;
mEnabled = true;
mPrevNode = NULL;
mCurMember = NULL;
mCurLocalMethodDeclaration = NULL;
mSkipAnonymousTypes = false;
}
void BfSourceClassifier::ModifyFlags(BfAstNode* node, uint8 andFlags, uint8 orFlags)
{
if (node != NULL)
{
ModifyFlags(node->GetSrcStart(), node->GetSrcEnd(), andFlags, orFlags);
}
}
void BfSourceClassifier::ModifyFlags(int startPos, int endPos, uint8 andFlags, uint8 orFlags)
{
if (!mEnabled)
return;
endPos = std::min(endPos, mParser->mOrigSrcLength);
for (int i = startPos; i < endPos; i++)
{
mCharData[i].mDisplayPassId = mClassifierPassId;
mCharData[i].mDisplayFlags = (mCharData[i].mDisplayFlags & andFlags) | orFlags;
}
}
void BfSourceClassifier::SetElementType(BfAstNode* node, BfSourceElementType elementType)
{
if (node != NULL)
{
SetElementType(node->GetSrcStart(), node->GetSrcEnd(), elementType);
}
}
void BfSourceClassifier::SetElementType(BfAstNode * node, BfTypeCode typeCode)
{
BfSourceElementType elemType = BfSourceElementType_Type;
if (typeCode == BfTypeCode_Interface)
elemType = BfSourceElementType_Interface;
else if (typeCode == BfTypeCode_Object)
elemType = BfSourceElementType_RefType;
else if (typeCode == BfTypeCode_Struct)
elemType = BfSourceElementType_Struct;
SetElementType(node, elemType);
}
void BfSourceClassifier::SetHighestElementType(int startPos, int endPos, BfSourceElementType elementType)
{
if (!mEnabled)
return;
endPos = BF_MIN(endPos, mParser->mOrigSrcLength);
for (int i = startPos; i < endPos; i++)
{
auto& charData = mCharData[i];
charData.mDisplayPassId = mClassifierPassId;
charData.mDisplayTypeId = BF_MAX(charData.mDisplayTypeId, (uint8)elementType);
}
}
void BfSourceClassifier::SetHighestElementType(BfAstNode* node, BfSourceElementType elementType)
{
if (node != NULL)
{
SetHighestElementType(node->GetSrcStart(), node->GetSrcEnd(), elementType);
}
}
void BfSourceClassifier::SetElementType(int startPos, int endPos, BfSourceElementType elementType)
{
if (!mEnabled)
return;
endPos = BF_MIN(endPos, mParser->mOrigSrcLength);
for (int i = startPos; i < endPos; i++)
{
mCharData[i].mDisplayPassId = mClassifierPassId;
mCharData[i].mDisplayTypeId = (uint8)elementType;
}
}
void BfSourceClassifier::VisitMembers(BfBlock* node)
{
mPrevNode = NULL;
for (auto& childNodeRef : *node)
{
BfAstNode* child = childNodeRef;
child->Accept(this);
mPrevNode = child;
}
}
bool BfSourceClassifier::IsInterestedInMember(BfAstNode* node, bool forceSkip)
{
if ((mSkipMethodInternals || forceSkip) && (mParser->mCursorIdx != -1) &&
(!node->Contains(mParser->mCursorIdx, 1, 0)))
return false;
return true;
}
void BfSourceClassifier::HandleLeafNode(BfAstNode* node)
{
if (!mEnabled)
return;
int nodeStart = node->GetSrcStart();
int srcStart = nodeStart;
int triviaStart = node->GetTriviaStart();
if (triviaStart != -1)
{
srcStart = triviaStart;
if ((mIsSideChannel) && (mPrevNode != NULL))
srcStart = std::max(mPrevNode->GetSrcEnd(), srcStart);
}
if (nodeStart != srcStart)
SetElementType(srcStart, nodeStart, BfSourceElementType_Normal);
//SetElementType(srcStart, node->GetSrcEnd(), BfSourceElementType_Normal);
if (!mPreserveFlags)
ModifyFlags(srcStart, node->GetSrcEnd(), ~BfSourceElementFlag_CompilerFlags_Mask, 0);
}
void BfSourceClassifier::Visit(BfAstNode* node)
{
}
void BfSourceClassifier::Visit(BfErrorNode* errorNode)
{
//Visit(errorNode->ToBase());
VisitChildNoRef(errorNode->mRefNode);
}
void BfSourceClassifier::Visit(BfFieldDeclaration* fieldDecl)
{
if (!IsInterestedInMember(fieldDecl))
return;
BfElementVisitor::Visit(fieldDecl);
VisitChild(fieldDecl->mConstSpecifier);
VisitChild(fieldDecl->mReadOnlySpecifier);
VisitChild(fieldDecl->mTypeRef);
VisitChild(fieldDecl->mNameNode);
SetElementType(fieldDecl->mNameNode, BfSourceElementType_Member);
}
void BfSourceClassifier::Visit(BfFieldDtorDeclaration* fieldDtorDecl)
{
Visit(fieldDtorDecl->ToBase());
BfElementVisitor::Visit(fieldDtorDecl);
if (fieldDtorDecl->mTildeToken != NULL)
SetElementType(fieldDtorDecl->mTildeToken, BfSourceElementType_Method);
}
void BfSourceClassifier::Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection)
{
HandleLeafNode(preprocesorIgnoredSection);
Visit(preprocesorIgnoredSection->ToBase());
SetElementType(preprocesorIgnoredSection, BfSourceElementType_Comment);
}
void BfSourceClassifier::Visit(BfPreprocessorNode* preprocessorNode)
{
HandleLeafNode(preprocessorNode);
if (!mPreserveFlags)
ModifyFlags(preprocessorNode, ~BfSourceElementFlag_CompilerFlags_Mask, 0);
SetElementType(preprocessorNode, BfSourceElementType_Normal);
Visit(preprocessorNode->ToBase());
}
void BfSourceClassifier::Visit(BfCommentNode* commentNode)
{
HandleLeafNode(commentNode);
Visit(commentNode->ToBase());
SetElementType(commentNode, BfSourceElementType_Comment);
}
void BfSourceClassifier::Visit(BfAttributeDirective* attributeDirective)
{
if (mSkipAttributes)
return;
// Skip?
{
if (auto typeDeclaration = BfNodeDynCast<BfTypeDeclaration>(mCurMember))
{
if (typeDeclaration->mAttributes == attributeDirective)
return;
}
if (mCurLocalMethodDeclaration == NULL)
{
if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(mCurMember))
{
if (methodDecl->mAttributes == attributeDirective)
return;
}
}
if (auto propDecl = BfNodeDynCast<BfPropertyDeclaration>(mCurMember))
{
if (propDecl->mAttributes == attributeDirective)
return;
for (auto methodDeclaration : propDecl->mMethods)
{
if (methodDeclaration->mAttributes == attributeDirective)
return;
}
}
}
BfElementVisitor::Visit(attributeDirective);
VisitChild(attributeDirective->mAttrCloseToken);
VisitChild(attributeDirective->mAttrOpenToken); // Either [ or ,
VisitChild(attributeDirective->mAttrCloseToken);
if (attributeDirective->mAttributeTargetSpecifier != NULL)
{
if (auto attributeTargetSpecifier = BfNodeDynCast<BfAttributeTargetSpecifier>(attributeDirective->mAttributeTargetSpecifier))
{
VisitChild(attributeTargetSpecifier->mTargetToken);
VisitChild(attributeTargetSpecifier->mColonToken);
}
else
{
VisitChild(attributeDirective->mAttributeTargetSpecifier);
}
}
VisitChild(attributeDirective->mAttributeTypeRef);
VisitChild(attributeDirective->mCtorOpenParen);
VisitChild(attributeDirective->mCtorCloseParen);
for (auto& arg : attributeDirective->mArguments)
VisitChild(arg);
for (auto& comma : attributeDirective->mCommas)
VisitChild(comma);
VisitChild(attributeDirective->mNextAttribute);
}
void BfSourceClassifier::Visit(BfIdentifierNode* identifier)
{
HandleLeafNode(identifier);
Visit(identifier->ToBase());
if ((identifier->Equals("this")) || (identifier->Equals("base")))
SetElementType(identifier, BfSourceElementType_Keyword);
else
SetElementType(identifier, BfSourceElementType_Identifier);
}
void BfSourceClassifier::Visit(BfQualifiedNameNode* qualifiedName)
{
Visit((BfAstNode*)qualifiedName);
VisitChild(qualifiedName->mLeft);
VisitChild(qualifiedName->mDot);
VisitChild(qualifiedName->mRight);
if (BfNodeIsExact<BfIdentifierNode>(qualifiedName->mRight))
SetElementType(qualifiedName->mRight, BfSourceElementType_Member);
}
void BfSourceClassifier::Visit(BfThisExpression* thisExpr)
{
HandleLeafNode(thisExpr);
Visit((BfAstNode*)thisExpr);
SetElementType(thisExpr, BfSourceElementType_Keyword);
}
void BfSourceClassifier::Visit(BfBaseExpression* baseExpr)
{
HandleLeafNode(baseExpr);
Visit((BfAstNode*)baseExpr);
SetElementType(baseExpr, BfSourceElementType_Keyword);
}
void BfSourceClassifier::Visit(BfMemberReferenceExpression* memberRefExpr)
{
Visit((BfAstNode*)memberRefExpr);
VisitChild(memberRefExpr->mTarget);
VisitChild(memberRefExpr->mDotToken);
VisitChild(memberRefExpr->mMemberName);
SetElementType(memberRefExpr->mMemberName, BfSourceElementType_Member);
}
void BfSourceClassifier::Visit(BfNamedTypeReference* typeRef)
{
HandleLeafNode(typeRef);
Visit(typeRef->ToBase());
//auto identifier = typeRef->mNameNode;
if (typeRef != NULL)
{
BfIdentifierNode* checkName = typeRef->mNameNode;
while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkName))
{
SetElementType(qualifiedNameNode->mRight, BfSourceElementType_Type);
checkName = qualifiedNameNode->mLeft;
}
if (checkName != NULL)
SetElementType(checkName, BfSourceElementType_Type);
}
}
void BfSourceClassifier::Visit(BfTagTypeRef* typeRef)
{
Visit((BfAstNode*)typeRef);
VisitChild(typeRef->mTagNode);
SetElementType(typeRef->mTagNode, BfSourceElementType_Keyword);
VisitChild(typeRef->mNameNode);
SetElementType(typeRef->mNameNode, BfSourceElementType_Type);
}
void BfSourceClassifier::Visit(BfQualifiedTypeReference* qualifiedType)
{
Visit((BfAstNode*)qualifiedType);
VisitChild(qualifiedType->mLeft);
VisitChild(qualifiedType->mDot);
VisitChild(qualifiedType->mRight);
}
void BfSourceClassifier::Visit(BfRefTypeRef* typeRef)
{
Visit((BfAstNode*)typeRef);
VisitChild(typeRef->mRefToken);
SetElementType(typeRef->mRefToken, BfSourceElementType_Type);
VisitChild(typeRef->mElementType);
}
void BfSourceClassifier::Visit(BfArrayTypeRef* arrayType)
{
Visit((BfAstNode*)arrayType);
VisitChild(arrayType->mElementType);
VisitChild(arrayType->mOpenBracket);
for (auto& param : arrayType->mParams)
VisitChild(param);
VisitChild(arrayType->mCloseBracket);
}
void BfSourceClassifier::Visit(BfPointerTypeRef* pointerType)
{
Visit((BfAstNode*)pointerType);
VisitChild(pointerType->mElementType);
VisitChild(pointerType->mStarNode);
}
void BfSourceClassifier::Visit(BfGenericInstanceTypeRef* genericInstTypeRef)
{
BfElementVisitor::Visit(genericInstTypeRef);
VisitChild(genericInstTypeRef->mElementType);
VisitChild(genericInstTypeRef->mOpenChevron);
for (int i = 0; i < (int) genericInstTypeRef->mGenericArguments.size(); i++)
{
if (genericInstTypeRef->mCommas.mVals != NULL)
{
if ((i > 0) && (i - 1 < (int)genericInstTypeRef->mCommas.size()))
VisitChild(genericInstTypeRef->mCommas[i - 1]);
}
VisitChild(genericInstTypeRef->mGenericArguments[i]);
}
VisitChild(genericInstTypeRef->mCloseChevron);
}
void BfSourceClassifier::Visit(BfVariableDeclaration* varDecl)
{
BfElementVisitor::Visit(varDecl);
if (!varDecl->IsA<BfParameterDeclaration>())
SetElementType(varDecl->mNameNode, BfSourceElementType_Local);
}
void BfSourceClassifier::Visit(BfLambdaBindExpression* lambdaBindExpr)
{
BfElementVisitor::Visit(lambdaBindExpr);
for (auto param : lambdaBindExpr->mParams)
{
SetElementType(param, BfSourceElementType_Parameter);
}
}
void BfSourceClassifier::Visit(BfLocalMethodDeclaration* methodDecl)
{
if (IsInterestedInMember(methodDecl, true))
{
SetAndRestoreValue<BfLocalMethodDeclaration*> prevLocalMethodDecl(mCurLocalMethodDeclaration, methodDecl);
BfElementVisitor::Visit(methodDecl);
}
}
void BfSourceClassifier::Visit(BfLiteralExpression* literalExpr)
{
HandleLeafNode(literalExpr);
Visit(literalExpr->ToBase());
SetElementType(literalExpr, BfSourceElementType_Literal);
}
void BfSourceClassifier::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
{
HandleLeafNode(stringInterpolationExpression);
Visit(stringInterpolationExpression->ToBase());
SetElementType(stringInterpolationExpression, BfSourceElementType_Literal);
VisitChild(stringInterpolationExpression->mAllocNode);
for (auto& expr : stringInterpolationExpression->mExpressions)
{
SetElementType(expr, BfSourceElementType_Normal);
VisitChild(expr);
}
}
void BfSourceClassifier::Visit(BfTokenNode* tokenNode)
{
HandleLeafNode(tokenNode);
Visit(tokenNode->ToBase());
if (BfTokenIsKeyword(tokenNode->GetToken()))
SetElementType(tokenNode, BfSourceElementType_Keyword);
else
SetElementType(tokenNode, BfSourceElementType_Normal);
}
void BfSourceClassifier::Visit(BfCaseExpression* caseExpr)
{
BfElementVisitor::Visit(caseExpr);
SetElementType(caseExpr->mNotToken, BfSourceElementType_Keyword);
}
void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
{
//BfElementVisitor::Visit(invocationExpr);
Visit(invocationExpr->ToBase());
//BP_ZONE("BfSourceClassifier BfInvocationExpression");
BfAstNode* target = invocationExpr->mTarget;
if (target == NULL)
return;
VisitChild(invocationExpr->mOpenParen);
VisitChild(invocationExpr->mCloseParen);
VisitChild(invocationExpr->mGenericArgs);
if (auto scopedTarget = BfNodeDynCast<BfScopedInvocationTarget>(target))
{
VisitChild(target);
target = scopedTarget->mTarget;
VisitChild(scopedTarget->mScopeName);
}
BfAstNode* identifier = NULL;
if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
{
VisitChild(qualifiedName->mLeft);
VisitChild(qualifiedName->mDot);
VisitChild(qualifiedName->mRight);
identifier = qualifiedName->mRight;
}
else if ((identifier = BfNodeDynCast<BfIdentifierNode>(target)))
{
VisitChild(target);
// Leave as BfAttributedIdentifierNode if that's the case
identifier = target;
}
else if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
{
VisitChild(qualifiedName->mLeft);
VisitChild(qualifiedName->mDot);
VisitChild(qualifiedName->mRight);
identifier = qualifiedName->mRight;
}
else if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(target))
{
VisitChild(memberRefExpr->mTarget);
VisitChild(memberRefExpr->mDotToken);
VisitChild(memberRefExpr->mMemberName);
identifier = memberRefExpr->mMemberName;
}
else
{
VisitChild(target);
}
if (identifier != NULL)
{
if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(identifier))
{
VisitChild(attrIdentifier->mAttributes);
identifier = attrIdentifier->mIdentifier;
}
if (identifier != NULL)
SetElementType(identifier, BfSourceElementType_Method);
}
for (auto& val : invocationExpr->mArguments)
VisitChild(val);
for (auto& val : invocationExpr->mCommas)
VisitChild(val);
}
void BfSourceClassifier::Visit(BfIndexerExpression* indexerExpr)
{
//BfElementVisitor::Visit(indexerExpr);
Visit(indexerExpr->ToBase());
VisitChild(indexerExpr->mTarget);
VisitChild(indexerExpr->mOpenBracket);
for (auto& val : indexerExpr->mArguments)
VisitChild(val);
for (auto& val : indexerExpr->mCommas)
VisitChild(val);
VisitChild(indexerExpr->mCloseBracket);
}
void BfSourceClassifier::Visit(BfConstructorDeclaration* ctorDeclaration)
{
if (!IsInterestedInMember(ctorDeclaration))
return;
BfElementVisitor::Visit(ctorDeclaration);
VisitChild(ctorDeclaration->mThisToken);
auto identifier = ctorDeclaration->mThisToken;
if (identifier == NULL)
return;
SetElementType(identifier, BfSourceElementType_Method);
}
void BfSourceClassifier::Visit(BfDestructorDeclaration* dtorDeclaration)
{
BfElementVisitor::Visit(dtorDeclaration);
VisitChild(dtorDeclaration->mTildeToken);
VisitChild(dtorDeclaration->mThisToken);
auto identifier = dtorDeclaration->mThisToken;
if (identifier == NULL)
return;
SetElementType(identifier, BfSourceElementType_Method);
identifier = dtorDeclaration->mTildeToken;
if (identifier == NULL)
return;
SetElementType(identifier, BfSourceElementType_Method);
}
void BfSourceClassifier::Visit(BfMethodDeclaration* methodDeclaration)
{
if (!IsInterestedInMember(methodDeclaration))
return;
//BP_ZONE("BfSourceClassifier BfMethodDeclaration");
SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, methodDeclaration);
BfElementVisitor::Visit(methodDeclaration);
SetElementType(methodDeclaration->mNameNode, BfSourceElementType_Method);
for (auto paramDecl : methodDeclaration->mParams)
{
if (paramDecl != NULL)
SetElementType(paramDecl->mNameNode, BfSourceElementType_Parameter);
}
if (methodDeclaration->mGenericParams != NULL)
{
for (auto& genericParam : methodDeclaration->mGenericParams->mGenericParams)
{
BfIdentifierNode* typeRef = genericParam;
SetElementType(typeRef, BfSourceElementType_GenericParam);
}
}
if (methodDeclaration->mGenericConstraintsDeclaration != NULL)
{
for (auto constraintNode : methodDeclaration->mGenericConstraintsDeclaration->mGenericConstraints)
{
if (auto genericConstraint = BfNodeDynCast<BfGenericConstraint>(constraintNode))
{
BfTypeReference* typeRef = genericConstraint->mTypeRef;
if (typeRef != NULL)
{
if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
SetElementType(typeRef, BfSourceElementType_GenericParam);
else
VisitChild(typeRef);
}
}
}
}
}
void BfSourceClassifier::Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration)
{
if ((propertyMethodDeclaration->mBody != NULL) && (!IsInterestedInMember(propertyMethodDeclaration->mBody)))
return;
BfElementVisitor::Visit(propertyMethodDeclaration);
}
void BfSourceClassifier::Visit(BfPropertyDeclaration* propertyDeclaration)
{
SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, propertyDeclaration);
BfElementVisitor::Visit(propertyDeclaration);
SetElementType(propertyDeclaration->mNameNode, BfSourceElementType_Member);
if (auto expr = BfNodeDynCast<BfPropertyBodyExpression>(propertyDeclaration->mDefinitionBlock))
return;
for (auto methodDeclaration : propertyDeclaration->mMethods)
{
if ((methodDeclaration != NULL) && (methodDeclaration->mNameNode != NULL))
SetElementType(methodDeclaration->mNameNode, BfSourceElementType_Method);
}
}
void BfSourceClassifier::Visit(BfTypeDeclaration* typeDeclaration)
{
if ((mSkipAnonymousTypes) && (typeDeclaration->IsAnonymous()))
return;
if (typeDeclaration->mIgnoreDeclaration)
return;
SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, typeDeclaration);
if ((mSkipTypeDeclarations) && (!typeDeclaration->IsAnonymous()))
{
if (auto defineBlock = BfNodeDynCast<BfBlock>(typeDeclaration->mDefineNode))
{
// Clear out any potential "fail after" errors on the closing brace-
// Can happen when we don't close out a namespace, for example
if (defineBlock->mCloseBrace != NULL)
VisitChild(defineBlock->mCloseBrace);
}
return;
}
Handle(typeDeclaration);
}
void BfSourceClassifier::Handle(BfTypeDeclaration* typeDeclaration)
{
if (mParser->mCursorIdx != -1)
{
// This is to fix a case where we are typing out a type name, so an "actualTypeDef" will not be found during autocomplete
// and therefore we will not process the attributes. Removing this will cause classify flashing while typing
SetAndRestoreValue<bool> prevSkipAttributes(mSkipAttributes, true);
BfElementVisitor::Visit(typeDeclaration);
}
else
BfElementVisitor::Visit(typeDeclaration);
llvm::SmallVector<BfTypeReference*, 2> mBaseClasses;
llvm::SmallVector<BfAstNode*, 2> mBaseClassCommas;
if (typeDeclaration->mGenericParams != NULL)
{
for (auto& genericParam : typeDeclaration->mGenericParams->mGenericParams)
{
BfIdentifierNode* typeRef = genericParam;
SetElementType(typeRef, BfSourceElementType_GenericParam);
}
}
if (typeDeclaration->mGenericConstraintsDeclaration != NULL)
{
for (auto constraintNode : typeDeclaration->mGenericConstraintsDeclaration->mGenericConstraints)
{
auto genericConstraint = BfNodeDynCast<BfGenericConstraint>(constraintNode);
BfTypeReference* typeRef = genericConstraint->mTypeRef;
if (typeRef != NULL)
{
if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
SetElementType(namedTypeRef, BfSourceElementType_GenericParam);
}
}
}
auto typeRef = typeDeclaration->mNameNode;
if (typeRef != NULL)
SetElementType(typeRef, BfSourceElementType_Type);
}
void BfSourceClassifier::MarkSkipped(int startPos, int endPos)
{
for (int i = startPos; i < endPos; i++)
{
mCharData[i].mDisplayPassId = BfSourceDisplayId_SkipResult;
}
}
void BfSourceClassifier::MarkSkipped(BfAstNode* node)
{
MarkSkipped(node->GetSrcStart(), node->GetSrcEnd());
}
void BfSourceClassifier::DeferNodes(BfBlock* block)
{
for (auto child : *block)
mDeferredNodes.Add(child);
}
void BfSourceClassifier::FlushDeferredNodes()
{
for (auto node : mDeferredNodes)
VisitChild(node);
mDeferredNodes.Clear();
}
void BfSourceClassifier::Visit(BfTypeAliasDeclaration* typeDeclaration)
{
if (typeDeclaration->mIgnoreDeclaration)
return;
BfElementVisitor::Visit(typeDeclaration);
}
void BfSourceClassifier::Visit(BfUsingDirective* usingDirective)
{
BfElementVisitor::Visit(usingDirective);
auto checkIdentifier = usingDirective->mNamespace;
if (checkIdentifier != NULL)
{
while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkIdentifier))
{
SetElementType(qualifiedNameNode->mRight, BfSourceElementType_Namespace);
checkIdentifier = qualifiedNameNode->mLeft;
}
if (checkIdentifier != NULL)
SetElementType(checkIdentifier, BfSourceElementType_Namespace);
}
}
void BfSourceClassifier::Visit(BfUsingModDirective* usingDirective)
{
BfElementVisitor::Visit(usingDirective);
}
void BfSourceClassifier::Visit(BfNamespaceDeclaration* namespaceDeclaration)
{
BfElementVisitor::Visit(namespaceDeclaration);
auto checkIdentifier = namespaceDeclaration->mNameNode;
if (checkIdentifier != NULL)
{
while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkIdentifier))
{
SetElementType(qualifiedNameNode->mRight, BfSourceElementType_Namespace);
checkIdentifier = qualifiedNameNode->mLeft;
}
if (checkIdentifier != NULL)
SetElementType(checkIdentifier, BfSourceElementType_Namespace);
}
}
bool BfSourceClassifier::WantsSkipParentMethod(BfAstNode* node)
{
if (!mSkipMethodInternals)
return false;
#ifdef BF_AST_HAS_PARENT_MEMBER
if (node->mParent->IsA<BfMethodDeclaration>())
{
BF_ASSERT(node->mParent == mCurMember);
}
if (auto propDecl = BfNodeDynCast<BfPropertyDeclaration>(node->mParent))
{
BF_ASSERT(node->mParent == mCurMember);
}
#endif
if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(mCurMember))
{
if (methodDecl->mBody == node)
return true;
}
if (auto propDecl = BfNodeDynCast<BfPropertyDeclaration>(mCurMember))
{
for (auto methodDeclaration : propDecl->mMethods)
{
if (node == methodDeclaration->mBody)
return true;
}
}
return false;
}
void BfSourceClassifier::Visit(BfGenericConstraintsDeclaration* genericConstraints)
{
/*if (WantsSkipParentMethod(genericConstraints))
return;*/
BfElementVisitor::Visit(genericConstraints);
}
void BfSourceClassifier::Visit(BfBlock* block)
{
if (WantsSkipParentMethod(block))
return;
if (block->mOpenBrace != NULL)
Visit(block->mOpenBrace);
if (block->mCloseBrace != NULL)
Visit(block->mCloseBrace);
VisitMembers(block);
}
void BfSourceClassifier::Visit(BfRootNode* rootNode)
{
// Clear off the flags at the end
ModifyFlags(mParser->mRootNode->GetSrcEnd(), mParser->mOrigSrcLength, 0, 0);
VisitMembers(rootNode);
}
void BfSourceClassifier::Visit(BfInlineAsmStatement* asmStmt)
{
if (asmStmt->mOpenBrace != NULL)
Visit(asmStmt->mOpenBrace);
if (asmStmt->mCloseBrace != NULL)
Visit(asmStmt->mCloseBrace);
//VisitMembers(asmStmt);
}
void BfSourceClassifier::Visit(BfInlineAsmInstruction* asmInst)
{
//VisitMembers(asmInst);
}