mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Added support for global:: lookups
This commit is contained in:
parent
ee50457885
commit
958a1630aa
13 changed files with 202 additions and 28 deletions
|
@ -1611,6 +1611,8 @@ const char* Beefy::BfTokenToString(BfToken token)
|
|||
return ";";
|
||||
case BfToken_Colon:
|
||||
return ":";
|
||||
case BfToken_ColonColon:
|
||||
return "::";
|
||||
case BfToken_Comma:
|
||||
return ",";
|
||||
case BfToken_Dot:
|
||||
|
|
|
@ -304,6 +304,7 @@ enum BfToken : uint8
|
|||
BfToken_RDblChevron,
|
||||
BfToken_Semicolon,
|
||||
BfToken_Colon,
|
||||
BfToken_ColonColon,
|
||||
BfToken_Comma,
|
||||
BfToken_Dot,
|
||||
BfToken_DotDot,
|
||||
|
@ -2014,6 +2015,13 @@ public:
|
|||
BfTokenNode* mColonToken;
|
||||
BfAstNode* mTargetNode; // . : or identifier
|
||||
BfAttributeDirective* mAttributes;
|
||||
|
||||
BfAstNode* GetTargetNode()
|
||||
{
|
||||
if ((mColonToken != NULL) && (mColonToken->mToken == BfToken_ColonColon))
|
||||
return mColonToken;
|
||||
return mTargetNode;
|
||||
}
|
||||
}; BF_AST_DECL(BfScopeNode, BfAstNode);
|
||||
|
||||
class BfNewNode : public BfAstNode
|
||||
|
@ -2108,6 +2116,12 @@ public:
|
|||
ASTREF(BfIdentifierNode*) mLeft;
|
||||
ASTREF(BfTokenNode*) mDot;
|
||||
ASTREF(BfIdentifierNode*) mRight;
|
||||
|
||||
bool IsGlobalLookup()
|
||||
{
|
||||
return (mDot != NULL) && (mDot->mToken == BfToken_ColonColon);
|
||||
}
|
||||
|
||||
}; BF_AST_DECL(BfQualifiedNameNode, BfIdentifierNode);
|
||||
|
||||
class BfUsingDirective : public BfStatement
|
||||
|
@ -2599,6 +2613,12 @@ public:
|
|||
ASTREF(BfTypeReference*) mLeft;
|
||||
ASTREF(BfTokenNode*) mDot;
|
||||
ASTREF(BfTypeReference*) mRight;
|
||||
|
||||
bool IsGlobalLookup()
|
||||
{
|
||||
return (mDot != NULL) && (mDot->mToken == BfToken_ColonColon);
|
||||
}
|
||||
|
||||
}; BF_AST_DECL(BfQualifiedTypeReference, BfTypeReference);
|
||||
|
||||
class BfResolvedTypeReference : public BfTypeReference
|
||||
|
@ -3036,6 +3056,13 @@ public:
|
|||
|
||||
BfAstNode* mTargetNode;
|
||||
|
||||
BfAstNode* GetScopeNameNode()
|
||||
{
|
||||
if ((mColonToken != NULL) && (mColonToken->mToken == BfToken_ColonColon))
|
||||
return mColonToken;
|
||||
return mScopeName;
|
||||
}
|
||||
|
||||
// virtual bool IsMissingSemicolon() override
|
||||
// {
|
||||
// return BfNodeDynCastExact<BfBlock>(mTargetNode) == NULL;
|
||||
|
@ -3059,6 +3086,13 @@ public:
|
|||
BfAstNode* mTarget;
|
||||
BfTokenNode* mColonToken;
|
||||
BfAstNode* mScopeName; // :, mixin, or identifier
|
||||
|
||||
BfAstNode* GetScopeNameNode()
|
||||
{
|
||||
if ((mColonToken != NULL) && (mColonToken->mToken == BfToken_ColonColon))
|
||||
return mColonToken;
|
||||
return mScopeName;
|
||||
}
|
||||
}; BF_AST_DECL(BfScopedInvocationTarget, BfAstNode);
|
||||
|
||||
class BfInvocationExpression : public BfMethodBoundExpression
|
||||
|
|
|
@ -1853,7 +1853,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
|
|||
{
|
||||
"alignof", "append", "as", "asm", "base", "break", "case", "catch", "checked", "continue", "const", "default", "defer",
|
||||
"delegate", "delete", "do", "else", "false", "finally",
|
||||
"fixed", "for", "function", "if", "implicit", "in", "internal", "is", "isconst", "new", "mixin", "not", "null",
|
||||
"fixed", "for", "function", "global", "if", "implicit", "in", "internal", "is", "isconst", "new", "mixin", "not", "null",
|
||||
"offsetof", "out", "params", "readonly", "ref", "rettype", "return",
|
||||
"sealed", "sizeof", "scope", "static", "strideof", "struct", "switch", /*"this",*/ "try", "true", "typeof", "unchecked",
|
||||
"using", "var", "virtual", "volatile", "where", "while",
|
||||
|
@ -1873,7 +1873,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
|
|||
const char* tokens[] =
|
||||
{
|
||||
"abstract", "append", "base", "class", "concrete", "const",
|
||||
"delegate", "extern", "enum", "explicit", "extension", "function",
|
||||
"delegate", "extern", "enum", "explicit", "extension", "function", "global",
|
||||
"interface", "in", "implicit", "internal", "mixin", "namespace", "new",
|
||||
"operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "rettype", "return",
|
||||
"scope", "sealed", "static", "struct", "this", "typealias",
|
||||
|
@ -1926,6 +1926,16 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken
|
|||
if (!WantsEntries())
|
||||
return false;
|
||||
|
||||
bool isGlobalLookup = true;
|
||||
if (auto dotTokenNode = BfNodeDynCast<BfTokenNode>(dotToken))
|
||||
{
|
||||
if (dotTokenNode->mToken == BfToken_ColonColon)
|
||||
{
|
||||
CheckNode(memberName, false, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BfAttributedIdentifierNode* attrIdentifier = NULL;
|
||||
bool isAutocompletingName = false;
|
||||
if ((attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(memberName)))
|
||||
|
|
|
@ -17223,8 +17223,8 @@ void BfExprEvaluator::ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode*
|
|||
{
|
||||
if (auto scopeNode = BfNodeDynCast<BfScopeNode>(allocNode))
|
||||
{
|
||||
newToken = scopeNode->mScopeToken;
|
||||
allocTarget.mScopeData = mModule->FindScope(scopeNode->mTargetNode, true);
|
||||
newToken = scopeNode->mScopeToken;
|
||||
allocTarget.mScopeData = mModule->FindScope(scopeNode->GetTargetNode(), true);
|
||||
|
||||
if (autoComplete != NULL)
|
||||
{
|
||||
|
@ -17799,7 +17799,9 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
}
|
||||
auto targetNameNode = targetSrc;
|
||||
if (scopedInvocationTarget != NULL)
|
||||
targetNameNode = scopedInvocationTarget->mTarget;
|
||||
{
|
||||
targetNameNode = scopedInvocationTarget->GetScopeNameNode();
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -18214,7 +18216,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
auto checkNode = origTargetSrc;
|
||||
if (scopedInvocationTarget != NULL)
|
||||
{
|
||||
auto targetScope = mModule->FindScope(scopedInvocationTarget->mScopeName, curMethodState->mMixinState);
|
||||
auto targetScope = mModule->FindScope(scopedInvocationTarget->GetScopeNameNode(), curMethodState->mMixinState);
|
||||
if (targetScope != NULL)
|
||||
{
|
||||
mixinState->mTargetScope = targetScope;
|
||||
|
@ -19106,7 +19108,20 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
if (GetAutoComplete() != NULL)
|
||||
GetAutoComplete()->CheckMemberReference(qualifiedName->mLeft, qualifiedName->mDot, qualifiedName->mRight);
|
||||
|
||||
if (qualifiedName->mLeft->GetSrcLength() == 4)
|
||||
bool isGlobalLookup = false;
|
||||
if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(target))
|
||||
{
|
||||
if (qualifiedNameNode->IsGlobalLookup())
|
||||
{
|
||||
if (auto subQualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(qualifiedNameNode->mRight))
|
||||
{
|
||||
qualifiedName = subQualifiedNameNode;
|
||||
isGlobalLookup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((!isGlobalLookup) && (qualifiedName->mLeft->GetSrcLength() == 4))
|
||||
{
|
||||
if (CheckIsBase(qualifiedName->mLeft))
|
||||
bypassVirtual = true;
|
||||
|
@ -19127,7 +19142,8 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
targetFunctionName = qualifiedName->mRight->ToString();
|
||||
|
||||
bool hadError = false;
|
||||
thisValue = LookupIdentifier(qualifiedName->mLeft, true, &hadError);
|
||||
if (!isGlobalLookup)
|
||||
thisValue = LookupIdentifier(qualifiedName->mLeft, true, &hadError);
|
||||
|
||||
CheckResultForReading(thisValue);
|
||||
if (mPropDef != NULL)
|
||||
|
@ -19141,18 +19157,22 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
|
||||
if ((!thisValue) && (mPropDef == NULL))
|
||||
{
|
||||
auto typeLookupFlags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowGlobalContainer | BfResolveTypeRefFlag_IgnoreLookupError);
|
||||
if (isGlobalLookup)
|
||||
typeLookupFlags = (BfResolveTypeRefFlags)(typeLookupFlags | BfResolveTypeRefFlag_GlobalLookup);
|
||||
|
||||
// Identifier not found. Static method? Just check speculatively don't throw error
|
||||
BfType* type;
|
||||
{
|
||||
//SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
||||
type = mModule->ResolveTypeRef(qualifiedName->mLeft, NULL, BfPopulateType_DataAndMethods, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowGlobalContainer | BfResolveTypeRefFlag_IgnoreLookupError));
|
||||
type = mModule->ResolveTypeRef(qualifiedName->mLeft, NULL, BfPopulateType_DataAndMethods, typeLookupFlags);
|
||||
}
|
||||
|
||||
if (type == NULL)
|
||||
{
|
||||
//SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
||||
|
||||
type = mModule->ResolveTypeRef(qualifiedName, methodGenericArguments, BfPopulateType_DataAndMethods, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowGlobalContainer | BfResolveTypeRefFlag_IgnoreLookupError));
|
||||
type = mModule->ResolveTypeRef(qualifiedName, methodGenericArguments, BfPopulateType_DataAndMethods, typeLookupFlags);
|
||||
if (type != NULL)
|
||||
{
|
||||
// This is a CTOR call, treat it as such
|
||||
|
|
|
@ -16568,7 +16568,7 @@ BfScopeData* BfModule::FindScope(BfAstNode* scopeName, BfMixinState* fromMixinSt
|
|||
|
||||
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(scopeName))
|
||||
{
|
||||
if (tokenNode->GetToken() == BfToken_Colon)
|
||||
if ((tokenNode->GetToken() == BfToken_Colon) || (tokenNode->GetToken() == BfToken_ColonColon))
|
||||
{
|
||||
if ((!allowAcrossDeferredBlock) && (mCurMethodState->mInDeferredBlock))
|
||||
{
|
||||
|
|
|
@ -10519,12 +10519,15 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
|||
if (mSystem->mTypeDefs.TryGet(findName, NULL))
|
||||
mSystem->FindTypeDef(findName, numGenericArgs, useProject, BfAtomComposite(), allowPrivate, &lookupCtx);
|
||||
|
||||
for (auto& checkNamespace : useTypeDef->mNamespaceSearch)
|
||||
if ((resolveFlags & BfResolveTypeRefFlag_GlobalLookup) == 0)
|
||||
{
|
||||
BfAtom* atom = findName.mParts[0];
|
||||
BfAtom* prevAtom = checkNamespace.mParts[checkNamespace.mSize - 1];
|
||||
if (atom->mPrevNamesMap.ContainsKey(prevAtom))
|
||||
mSystem->FindTypeDef(findName, numGenericArgs, useProject, checkNamespace, allowPrivate, &lookupCtx);
|
||||
for (auto& checkNamespace : useTypeDef->mNamespaceSearch)
|
||||
{
|
||||
BfAtom* atom = findName.mParts[0];
|
||||
BfAtom* prevAtom = checkNamespace.mParts[checkNamespace.mSize - 1];
|
||||
if (atom->mPrevNamesMap.ContainsKey(prevAtom))
|
||||
mSystem->FindTypeDef(findName, numGenericArgs, useProject, checkNamespace, allowPrivate, &lookupCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10550,7 +10553,7 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
|||
}
|
||||
}
|
||||
|
||||
if ((!lookupCtx.HasValidMatch()) && (typeInstance == NULL))
|
||||
if ((!lookupCtx.HasValidMatch()) && (typeInstance == NULL) && ((resolveFlags & BfResolveTypeRefFlag_GlobalLookup) == 0))
|
||||
{
|
||||
if (useTypeDef->mOuterType != NULL)
|
||||
return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef->mOuterType, error);
|
||||
|
@ -10591,6 +10594,12 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric
|
|||
if (useTypeDef != NULL)
|
||||
useTypeDef = useTypeDef->GetDefinition();
|
||||
|
||||
if ((resolveFlags & BfResolveTypeRefFlag_GlobalLookup) != 0)
|
||||
{
|
||||
// No need to cache
|
||||
return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, error, NULL, resolveFlags);
|
||||
}
|
||||
|
||||
if ((typeInstance == NULL) && (useTypeDef == NULL))
|
||||
{
|
||||
BfProject* project = NULL;
|
||||
|
@ -10648,7 +10657,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric
|
|||
BfTypeLookupEntry typeLookupEntry;
|
||||
typeLookupEntry.mName.Reference(findName);
|
||||
typeLookupEntry.mNumGenericParams = numGenericArgs;
|
||||
typeLookupEntry.mFlags = ((resolveFlags & BfResolveTypeRefFlag_SpecializedProject) != 0) ? BfTypeLookupEntry::Flags_SpecializedProject : BfTypeLookupEntry::Flags_None;
|
||||
typeLookupEntry.mFlags = ((resolveFlags & BfResolveTypeRefFlag_SpecializedProject) != 0) ? BfTypeLookupEntry::Flags_SpecializedProject : BfTypeLookupEntry::Flags_None;
|
||||
typeLookupEntry.mUseTypeDef = useTypeDef;
|
||||
|
||||
BfTypeLookupEntry* typeLookupEntryPtr = NULL;
|
||||
|
@ -11589,6 +11598,12 @@ BfType* BfModule::ResolveTypeRef_Ref(BfTypeReference* typeRef, BfPopulateType po
|
|||
|
||||
if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
|
||||
{
|
||||
if (qualifiedTypeRef->IsGlobalLookup())
|
||||
{
|
||||
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_GlobalLookup);
|
||||
return ResolveTypeRef_Ref(qualifiedTypeRef->mRight, populateType, resolveFlags, numGenericArgs);
|
||||
}
|
||||
|
||||
//TODO: Determine why we had this prevIgnoreErrors set here. It causes things like IEnumerator<Hey.Test<INVALIDNAME>> not fail
|
||||
// properly on INVALIDNAME
|
||||
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, /*true*/mIgnoreErrors);
|
||||
|
|
|
@ -2630,6 +2630,13 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro
|
|||
mToken = BfToken_Dot;
|
||||
mSyntaxToken = BfSyntaxToken_Token;
|
||||
}
|
||||
else if (mSrc[mSrcIdx] == ':')
|
||||
{
|
||||
mSrcIdx++;
|
||||
mTokenEnd = mSrcIdx;
|
||||
mToken = BfToken_ColonColon;
|
||||
mSyntaxToken = BfSyntaxToken_Token;
|
||||
}
|
||||
else
|
||||
{
|
||||
mToken = BfToken_Colon;
|
||||
|
|
|
@ -4248,6 +4248,11 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
|
|||
FailAfter("Expected scope name", deferStmt);
|
||||
}
|
||||
}
|
||||
else if (nextTokenNode->GetToken() == BfToken_ColonColon)
|
||||
{
|
||||
MEMBER_SET(deferStmt, mColonToken, nextTokenNode);
|
||||
mVisitorPos.MoveNext();
|
||||
}
|
||||
else if (nextTokenNode->GetToken() == BfToken_LParen)
|
||||
{
|
||||
mPassInstance->Warn(0, "Syntax deprecated", nextTokenNode);
|
||||
|
@ -5868,7 +5873,7 @@ BfTypeReference* BfReducer::CreateRefTypeRef(BfTypeReference* elementType, BfTok
|
|||
return refTypeRef;
|
||||
}
|
||||
|
||||
BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
|
||||
BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode, bool allowGlobalLookup)
|
||||
{
|
||||
AssertCurrentNode(leftNode);
|
||||
|
||||
|
@ -5879,9 +5884,15 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
|
|||
auto leftIdentifier = (BfIdentifierNode*)leftNode;
|
||||
while (true)
|
||||
{
|
||||
bool isGlobalLookup = false;
|
||||
|
||||
auto nextToken = mVisitorPos.Get(mVisitorPos.mReadPos + 1);
|
||||
auto tokenNode = BfNodeDynCast<BfTokenNode>(nextToken);
|
||||
if ((tokenNode == NULL) || ((tokenNode->GetToken() != BfToken_Dot) /*&& (tokenNode->GetToken() != BfToken_QuestionDot)*/))
|
||||
if ((tokenNode != NULL) && (tokenNode->mToken == BfToken_ColonColon) && (leftNode->IsExact<BfIdentifierNode>()) && (leftNode->Equals("global")) && (allowGlobalLookup))
|
||||
{
|
||||
isGlobalLookup = true;
|
||||
}
|
||||
else if ((tokenNode == NULL) || ((tokenNode->GetToken() != BfToken_Dot) /*&& (tokenNode->GetToken() != BfToken_QuestionDot)*/))
|
||||
return leftIdentifier;
|
||||
|
||||
auto nextNextToken = mVisitorPos.Get(mVisitorPos.mReadPos + 2);
|
||||
|
@ -5906,6 +5917,22 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
|
|||
return leftIdentifier;
|
||||
}
|
||||
|
||||
if (isGlobalLookup)
|
||||
{
|
||||
// For 'global::', we put 'global' on the left and the rest on the right which is different from normal
|
||||
mVisitorPos.MoveNext(); // past .
|
||||
mVisitorPos.MoveNext(); // past right
|
||||
auto rightSide = CompactQualifiedName(rightIdentifier, false);
|
||||
|
||||
auto qualifiedNameNode = mAlloc->Alloc<BfQualifiedNameNode>();
|
||||
ReplaceNode(leftIdentifier, qualifiedNameNode);
|
||||
qualifiedNameNode->mLeft = leftIdentifier;
|
||||
MEMBER_SET(qualifiedNameNode, mDot, tokenNode);
|
||||
MEMBER_SET(qualifiedNameNode, mRight, rightSide);
|
||||
|
||||
return qualifiedNameNode;
|
||||
}
|
||||
|
||||
// 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);
|
||||
if ((prevNodeToken != NULL) &&
|
||||
|
@ -7935,7 +7962,7 @@ BfInvocationExpression* BfReducer::CreateInvocationExpression(BfAstNode* target,
|
|||
|
||||
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
||||
{
|
||||
if (nextToken->GetToken() == BfToken_Colon)
|
||||
if ((nextToken->GetToken() == BfToken_Colon) || (nextToken->GetToken() == BfToken_ColonColon))
|
||||
{
|
||||
auto scopedInvocationTarget = CreateScopedInvocationTarget(invocationExpr->mTarget, nextToken);
|
||||
invocationExpr->SetSrcEnd(scopedInvocationTarget->GetSrcEnd());
|
||||
|
@ -8317,6 +8344,10 @@ BfScopedInvocationTarget* BfReducer::CreateScopedInvocationTarget(BfAstNode*& ta
|
|||
MEMBER_SET(scopedInvocationTarget, mColonToken, colonToken);
|
||||
|
||||
mVisitorPos.MoveNext();
|
||||
|
||||
if (colonToken->mToken == BfToken_ColonColon)
|
||||
return scopedInvocationTarget;
|
||||
|
||||
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
||||
{
|
||||
if ((nextToken->GetToken() == BfToken_Colon) || (nextToken->GetToken() == BfToken_Mixin))
|
||||
|
@ -8473,7 +8504,7 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
|||
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||
if (nextToken == NULL)
|
||||
return allocToken;
|
||||
if ((nextToken->mToken != BfToken_Colon) && (nextToken->mToken != BfToken_LBracket))
|
||||
if ((nextToken->mToken != BfToken_Colon) && (nextToken->mToken != BfToken_ColonColon) && (nextToken->mToken != BfToken_LBracket))
|
||||
return allocToken;
|
||||
|
||||
auto scopeNode = mAlloc->Alloc<BfScopeNode>();
|
||||
|
@ -8504,6 +8535,11 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
|||
FailAfter("Expected scope name", scopeNode);
|
||||
}
|
||||
}
|
||||
else if (nextToken->mToken == BfToken_ColonColon)
|
||||
{
|
||||
MEMBER_SET(scopeNode, mColonToken, nextToken);
|
||||
mVisitorPos.MoveNext();
|
||||
}
|
||||
|
||||
nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||
if (nextToken == NULL)
|
||||
|
|
|
@ -231,7 +231,7 @@ public:
|
|||
void ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, BfBlock* block);
|
||||
BfAstNode* ReadTypeMember(BfTokenNode* node, bool declStarted = false, int depth = 0, BfAstNode* deferredHeadNode = NULL);
|
||||
BfAstNode* ReadTypeMember(BfAstNode* node, bool declStarted = false, int depth = 0, BfAstNode* deferredHeadNode = NULL);
|
||||
BfIdentifierNode* CompactQualifiedName(BfAstNode* leftNode);
|
||||
BfIdentifierNode* CompactQualifiedName(BfAstNode* leftNode, bool allowGlobalLookup = true);
|
||||
void TryIdentifierConvert(int readPos);
|
||||
void CreateQualifiedNames(BfAstNode* node);
|
||||
BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode);
|
||||
|
|
|
@ -42,7 +42,8 @@ enum BfResolveTypeRefFlags
|
|||
BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000,
|
||||
BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000,
|
||||
BfResolveTypeRefFlag_IgnoreProtection = 0x100000,
|
||||
BfResolveTypeRefFlag_SpecializedProject = 0x200000
|
||||
BfResolveTypeRefFlag_SpecializedProject = 0x200000,
|
||||
BfResolveTypeRefFlag_GlobalLookup = 0x400000
|
||||
};
|
||||
|
||||
enum BfTypeNameFlags : uint16
|
||||
|
@ -1735,7 +1736,7 @@ struct BfTypeLookupEntry
|
|||
enum Flags : uint8
|
||||
{
|
||||
Flags_None,
|
||||
Flags_SpecializedProject
|
||||
Flags_SpecializedProject,
|
||||
};
|
||||
|
||||
BfAtomComposite mName;
|
||||
|
|
|
@ -283,8 +283,10 @@ void BfSourceClassifier::Visit(BfIdentifierNode* identifier)
|
|||
void BfSourceClassifier::Visit(BfQualifiedNameNode* qualifiedName)
|
||||
{
|
||||
Visit((BfAstNode*)qualifiedName);
|
||||
|
||||
|
||||
VisitChild(qualifiedName->mLeft);
|
||||
if (qualifiedName->IsGlobalLookup())
|
||||
SetElementType(qualifiedName->mLeft, BfSourceElementType_Namespace);
|
||||
VisitChild(qualifiedName->mDot);
|
||||
VisitChild(qualifiedName->mRight);
|
||||
if (BfNodeIsExact<BfIdentifierNode>(qualifiedName->mRight))
|
||||
|
@ -350,6 +352,8 @@ void BfSourceClassifier::Visit(BfQualifiedTypeReference* qualifiedType)
|
|||
Visit((BfAstNode*)qualifiedType);
|
||||
|
||||
VisitChild(qualifiedType->mLeft);
|
||||
if (qualifiedType->IsGlobalLookup())
|
||||
SetElementType(qualifiedType->mLeft, BfSourceElementType_Namespace);
|
||||
VisitChild(qualifiedType->mDot);
|
||||
VisitChild(qualifiedType->mRight);
|
||||
}
|
||||
|
@ -495,6 +499,8 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
|
|||
if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
|
||||
{
|
||||
VisitChild(qualifiedName->mLeft);
|
||||
if (qualifiedName->IsGlobalLookup())
|
||||
SetElementType(qualifiedName->mLeft, BfSourceElementType_Namespace);
|
||||
VisitChild(qualifiedName->mDot);
|
||||
VisitChild(qualifiedName->mRight);
|
||||
identifier = qualifiedName->mRight;
|
||||
|
|
|
@ -7387,6 +7387,8 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
|||
|
||||
BfScopeData* scope = NULL;
|
||||
|
||||
auto scopeNameNode = deferStmt->GetScopeNameNode();
|
||||
|
||||
if (deferStmt->mScopeToken != NULL)
|
||||
{
|
||||
if (deferStmt->mScopeToken->GetToken() == BfToken_Scope)
|
||||
|
@ -7394,9 +7396,9 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
|||
else
|
||||
scope = &mCurMethodState->mHeadScope;
|
||||
}
|
||||
else if (deferStmt->mScopeName != NULL)
|
||||
else if (scopeNameNode != NULL)
|
||||
{
|
||||
scope = FindScope(deferStmt->mScopeName, true);
|
||||
scope = FindScope(scopeNameNode, true);
|
||||
|
||||
if (scope == NULL)
|
||||
{
|
||||
|
|
41
IDEHelper/Tests/src/Lookups.bf
Normal file
41
IDEHelper/Tests/src/Lookups.bf
Normal file
|
@ -0,0 +1,41 @@
|
|||
#pragma warning disable 168
|
||||
|
||||
namespace Tests;
|
||||
|
||||
namespace A.B
|
||||
{
|
||||
class Zonk<T>
|
||||
{
|
||||
public static int sVal = 123;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
global::B.Init();
|
||||
global::A.B.Zonk<int>.sVal = 234;
|
||||
global::B.MethodT<float>();
|
||||
global::System.String str = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace B
|
||||
{
|
||||
static
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
}
|
||||
|
||||
public static void MethodT<T>()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Lookups
|
||||
{
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue