mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +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 ";";
|
return ";";
|
||||||
case BfToken_Colon:
|
case BfToken_Colon:
|
||||||
return ":";
|
return ":";
|
||||||
|
case BfToken_ColonColon:
|
||||||
|
return "::";
|
||||||
case BfToken_Comma:
|
case BfToken_Comma:
|
||||||
return ",";
|
return ",";
|
||||||
case BfToken_Dot:
|
case BfToken_Dot:
|
||||||
|
|
|
@ -304,6 +304,7 @@ enum BfToken : uint8
|
||||||
BfToken_RDblChevron,
|
BfToken_RDblChevron,
|
||||||
BfToken_Semicolon,
|
BfToken_Semicolon,
|
||||||
BfToken_Colon,
|
BfToken_Colon,
|
||||||
|
BfToken_ColonColon,
|
||||||
BfToken_Comma,
|
BfToken_Comma,
|
||||||
BfToken_Dot,
|
BfToken_Dot,
|
||||||
BfToken_DotDot,
|
BfToken_DotDot,
|
||||||
|
@ -2014,6 +2015,13 @@ public:
|
||||||
BfTokenNode* mColonToken;
|
BfTokenNode* mColonToken;
|
||||||
BfAstNode* mTargetNode; // . : or identifier
|
BfAstNode* mTargetNode; // . : or identifier
|
||||||
BfAttributeDirective* mAttributes;
|
BfAttributeDirective* mAttributes;
|
||||||
|
|
||||||
|
BfAstNode* GetTargetNode()
|
||||||
|
{
|
||||||
|
if ((mColonToken != NULL) && (mColonToken->mToken == BfToken_ColonColon))
|
||||||
|
return mColonToken;
|
||||||
|
return mTargetNode;
|
||||||
|
}
|
||||||
}; BF_AST_DECL(BfScopeNode, BfAstNode);
|
}; BF_AST_DECL(BfScopeNode, BfAstNode);
|
||||||
|
|
||||||
class BfNewNode : public BfAstNode
|
class BfNewNode : public BfAstNode
|
||||||
|
@ -2108,6 +2116,12 @@ public:
|
||||||
ASTREF(BfIdentifierNode*) mLeft;
|
ASTREF(BfIdentifierNode*) mLeft;
|
||||||
ASTREF(BfTokenNode*) mDot;
|
ASTREF(BfTokenNode*) mDot;
|
||||||
ASTREF(BfIdentifierNode*) mRight;
|
ASTREF(BfIdentifierNode*) mRight;
|
||||||
|
|
||||||
|
bool IsGlobalLookup()
|
||||||
|
{
|
||||||
|
return (mDot != NULL) && (mDot->mToken == BfToken_ColonColon);
|
||||||
|
}
|
||||||
|
|
||||||
}; BF_AST_DECL(BfQualifiedNameNode, BfIdentifierNode);
|
}; BF_AST_DECL(BfQualifiedNameNode, BfIdentifierNode);
|
||||||
|
|
||||||
class BfUsingDirective : public BfStatement
|
class BfUsingDirective : public BfStatement
|
||||||
|
@ -2599,6 +2613,12 @@ public:
|
||||||
ASTREF(BfTypeReference*) mLeft;
|
ASTREF(BfTypeReference*) mLeft;
|
||||||
ASTREF(BfTokenNode*) mDot;
|
ASTREF(BfTokenNode*) mDot;
|
||||||
ASTREF(BfTypeReference*) mRight;
|
ASTREF(BfTypeReference*) mRight;
|
||||||
|
|
||||||
|
bool IsGlobalLookup()
|
||||||
|
{
|
||||||
|
return (mDot != NULL) && (mDot->mToken == BfToken_ColonColon);
|
||||||
|
}
|
||||||
|
|
||||||
}; BF_AST_DECL(BfQualifiedTypeReference, BfTypeReference);
|
}; BF_AST_DECL(BfQualifiedTypeReference, BfTypeReference);
|
||||||
|
|
||||||
class BfResolvedTypeReference : public BfTypeReference
|
class BfResolvedTypeReference : public BfTypeReference
|
||||||
|
@ -3036,6 +3056,13 @@ public:
|
||||||
|
|
||||||
BfAstNode* mTargetNode;
|
BfAstNode* mTargetNode;
|
||||||
|
|
||||||
|
BfAstNode* GetScopeNameNode()
|
||||||
|
{
|
||||||
|
if ((mColonToken != NULL) && (mColonToken->mToken == BfToken_ColonColon))
|
||||||
|
return mColonToken;
|
||||||
|
return mScopeName;
|
||||||
|
}
|
||||||
|
|
||||||
// virtual bool IsMissingSemicolon() override
|
// virtual bool IsMissingSemicolon() override
|
||||||
// {
|
// {
|
||||||
// return BfNodeDynCastExact<BfBlock>(mTargetNode) == NULL;
|
// return BfNodeDynCastExact<BfBlock>(mTargetNode) == NULL;
|
||||||
|
@ -3059,6 +3086,13 @@ public:
|
||||||
BfAstNode* mTarget;
|
BfAstNode* mTarget;
|
||||||
BfTokenNode* mColonToken;
|
BfTokenNode* mColonToken;
|
||||||
BfAstNode* mScopeName; // :, mixin, or identifier
|
BfAstNode* mScopeName; // :, mixin, or identifier
|
||||||
|
|
||||||
|
BfAstNode* GetScopeNameNode()
|
||||||
|
{
|
||||||
|
if ((mColonToken != NULL) && (mColonToken->mToken == BfToken_ColonColon))
|
||||||
|
return mColonToken;
|
||||||
|
return mScopeName;
|
||||||
|
}
|
||||||
}; BF_AST_DECL(BfScopedInvocationTarget, BfAstNode);
|
}; BF_AST_DECL(BfScopedInvocationTarget, BfAstNode);
|
||||||
|
|
||||||
class BfInvocationExpression : public BfMethodBoundExpression
|
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",
|
"alignof", "append", "as", "asm", "base", "break", "case", "catch", "checked", "continue", "const", "default", "defer",
|
||||||
"delegate", "delete", "do", "else", "false", "finally",
|
"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",
|
"offsetof", "out", "params", "readonly", "ref", "rettype", "return",
|
||||||
"sealed", "sizeof", "scope", "static", "strideof", "struct", "switch", /*"this",*/ "try", "true", "typeof", "unchecked",
|
"sealed", "sizeof", "scope", "static", "strideof", "struct", "switch", /*"this",*/ "try", "true", "typeof", "unchecked",
|
||||||
"using", "var", "virtual", "volatile", "where", "while",
|
"using", "var", "virtual", "volatile", "where", "while",
|
||||||
|
@ -1873,7 +1873,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
|
||||||
const char* tokens[] =
|
const char* tokens[] =
|
||||||
{
|
{
|
||||||
"abstract", "append", "base", "class", "concrete", "const",
|
"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",
|
"interface", "in", "implicit", "internal", "mixin", "namespace", "new",
|
||||||
"operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "rettype", "return",
|
"operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "rettype", "return",
|
||||||
"scope", "sealed", "static", "struct", "this", "typealias",
|
"scope", "sealed", "static", "struct", "this", "typealias",
|
||||||
|
@ -1926,6 +1926,16 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken
|
||||||
if (!WantsEntries())
|
if (!WantsEntries())
|
||||||
return false;
|
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;
|
BfAttributedIdentifierNode* attrIdentifier = NULL;
|
||||||
bool isAutocompletingName = false;
|
bool isAutocompletingName = false;
|
||||||
if ((attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(memberName)))
|
if ((attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(memberName)))
|
||||||
|
|
|
@ -17224,7 +17224,7 @@ void BfExprEvaluator::ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode*
|
||||||
if (auto scopeNode = BfNodeDynCast<BfScopeNode>(allocNode))
|
if (auto scopeNode = BfNodeDynCast<BfScopeNode>(allocNode))
|
||||||
{
|
{
|
||||||
newToken = scopeNode->mScopeToken;
|
newToken = scopeNode->mScopeToken;
|
||||||
allocTarget.mScopeData = mModule->FindScope(scopeNode->mTargetNode, true);
|
allocTarget.mScopeData = mModule->FindScope(scopeNode->GetTargetNode(), true);
|
||||||
|
|
||||||
if (autoComplete != NULL)
|
if (autoComplete != NULL)
|
||||||
{
|
{
|
||||||
|
@ -17799,7 +17799,9 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
||||||
}
|
}
|
||||||
auto targetNameNode = targetSrc;
|
auto targetNameNode = targetSrc;
|
||||||
if (scopedInvocationTarget != NULL)
|
if (scopedInvocationTarget != NULL)
|
||||||
targetNameNode = scopedInvocationTarget->mTarget;
|
{
|
||||||
|
targetNameNode = scopedInvocationTarget->GetScopeNameNode();
|
||||||
|
}
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -18214,7 +18216,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
||||||
auto checkNode = origTargetSrc;
|
auto checkNode = origTargetSrc;
|
||||||
if (scopedInvocationTarget != NULL)
|
if (scopedInvocationTarget != NULL)
|
||||||
{
|
{
|
||||||
auto targetScope = mModule->FindScope(scopedInvocationTarget->mScopeName, curMethodState->mMixinState);
|
auto targetScope = mModule->FindScope(scopedInvocationTarget->GetScopeNameNode(), curMethodState->mMixinState);
|
||||||
if (targetScope != NULL)
|
if (targetScope != NULL)
|
||||||
{
|
{
|
||||||
mixinState->mTargetScope = targetScope;
|
mixinState->mTargetScope = targetScope;
|
||||||
|
@ -19106,7 +19108,20 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
if (GetAutoComplete() != NULL)
|
if (GetAutoComplete() != NULL)
|
||||||
GetAutoComplete()->CheckMemberReference(qualifiedName->mLeft, qualifiedName->mDot, qualifiedName->mRight);
|
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))
|
if (CheckIsBase(qualifiedName->mLeft))
|
||||||
bypassVirtual = true;
|
bypassVirtual = true;
|
||||||
|
@ -19127,6 +19142,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
targetFunctionName = qualifiedName->mRight->ToString();
|
targetFunctionName = qualifiedName->mRight->ToString();
|
||||||
|
|
||||||
bool hadError = false;
|
bool hadError = false;
|
||||||
|
if (!isGlobalLookup)
|
||||||
thisValue = LookupIdentifier(qualifiedName->mLeft, true, &hadError);
|
thisValue = LookupIdentifier(qualifiedName->mLeft, true, &hadError);
|
||||||
|
|
||||||
CheckResultForReading(thisValue);
|
CheckResultForReading(thisValue);
|
||||||
|
@ -19141,18 +19157,22 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
|
|
||||||
if ((!thisValue) && (mPropDef == NULL))
|
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
|
// Identifier not found. Static method? Just check speculatively don't throw error
|
||||||
BfType* type;
|
BfType* type;
|
||||||
{
|
{
|
||||||
//SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
//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)
|
if (type == NULL)
|
||||||
{
|
{
|
||||||
//SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
//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)
|
if (type != NULL)
|
||||||
{
|
{
|
||||||
// This is a CTOR call, treat it as such
|
// 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 (auto tokenNode = BfNodeDynCast<BfTokenNode>(scopeName))
|
||||||
{
|
{
|
||||||
if (tokenNode->GetToken() == BfToken_Colon)
|
if ((tokenNode->GetToken() == BfToken_Colon) || (tokenNode->GetToken() == BfToken_ColonColon))
|
||||||
{
|
{
|
||||||
if ((!allowAcrossDeferredBlock) && (mCurMethodState->mInDeferredBlock))
|
if ((!allowAcrossDeferredBlock) && (mCurMethodState->mInDeferredBlock))
|
||||||
{
|
{
|
||||||
|
|
|
@ -10519,6 +10519,8 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
||||||
if (mSystem->mTypeDefs.TryGet(findName, NULL))
|
if (mSystem->mTypeDefs.TryGet(findName, NULL))
|
||||||
mSystem->FindTypeDef(findName, numGenericArgs, useProject, BfAtomComposite(), allowPrivate, &lookupCtx);
|
mSystem->FindTypeDef(findName, numGenericArgs, useProject, BfAtomComposite(), allowPrivate, &lookupCtx);
|
||||||
|
|
||||||
|
if ((resolveFlags & BfResolveTypeRefFlag_GlobalLookup) == 0)
|
||||||
|
{
|
||||||
for (auto& checkNamespace : useTypeDef->mNamespaceSearch)
|
for (auto& checkNamespace : useTypeDef->mNamespaceSearch)
|
||||||
{
|
{
|
||||||
BfAtom* atom = findName.mParts[0];
|
BfAtom* atom = findName.mParts[0];
|
||||||
|
@ -10527,6 +10529,7 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
||||||
mSystem->FindTypeDef(findName, numGenericArgs, useProject, checkNamespace, allowPrivate, &lookupCtx);
|
mSystem->FindTypeDef(findName, numGenericArgs, useProject, checkNamespace, allowPrivate, &lookupCtx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!lookupCtx.HasValidMatch())
|
if (!lookupCtx.HasValidMatch())
|
||||||
{
|
{
|
||||||
|
@ -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)
|
if (useTypeDef->mOuterType != NULL)
|
||||||
return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef->mOuterType, error);
|
return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef->mOuterType, error);
|
||||||
|
@ -10591,6 +10594,12 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric
|
||||||
if (useTypeDef != NULL)
|
if (useTypeDef != NULL)
|
||||||
useTypeDef = useTypeDef->GetDefinition();
|
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))
|
if ((typeInstance == NULL) && (useTypeDef == NULL))
|
||||||
{
|
{
|
||||||
BfProject* project = NULL;
|
BfProject* project = NULL;
|
||||||
|
@ -11589,6 +11598,12 @@ BfType* BfModule::ResolveTypeRef_Ref(BfTypeReference* typeRef, BfPopulateType po
|
||||||
|
|
||||||
if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
|
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
|
//TODO: Determine why we had this prevIgnoreErrors set here. It causes things like IEnumerator<Hey.Test<INVALIDNAME>> not fail
|
||||||
// properly on INVALIDNAME
|
// properly on INVALIDNAME
|
||||||
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, /*true*/mIgnoreErrors);
|
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, /*true*/mIgnoreErrors);
|
||||||
|
|
|
@ -2630,6 +2630,13 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro
|
||||||
mToken = BfToken_Dot;
|
mToken = BfToken_Dot;
|
||||||
mSyntaxToken = BfSyntaxToken_Token;
|
mSyntaxToken = BfSyntaxToken_Token;
|
||||||
}
|
}
|
||||||
|
else if (mSrc[mSrcIdx] == ':')
|
||||||
|
{
|
||||||
|
mSrcIdx++;
|
||||||
|
mTokenEnd = mSrcIdx;
|
||||||
|
mToken = BfToken_ColonColon;
|
||||||
|
mSyntaxToken = BfSyntaxToken_Token;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mToken = BfToken_Colon;
|
mToken = BfToken_Colon;
|
||||||
|
|
|
@ -4248,6 +4248,11 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
|
||||||
FailAfter("Expected scope name", deferStmt);
|
FailAfter("Expected scope name", deferStmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (nextTokenNode->GetToken() == BfToken_ColonColon)
|
||||||
|
{
|
||||||
|
MEMBER_SET(deferStmt, mColonToken, nextTokenNode);
|
||||||
|
mVisitorPos.MoveNext();
|
||||||
|
}
|
||||||
else if (nextTokenNode->GetToken() == BfToken_LParen)
|
else if (nextTokenNode->GetToken() == BfToken_LParen)
|
||||||
{
|
{
|
||||||
mPassInstance->Warn(0, "Syntax deprecated", nextTokenNode);
|
mPassInstance->Warn(0, "Syntax deprecated", nextTokenNode);
|
||||||
|
@ -5868,7 +5873,7 @@ BfTypeReference* BfReducer::CreateRefTypeRef(BfTypeReference* elementType, BfTok
|
||||||
return refTypeRef;
|
return refTypeRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
|
BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode, bool allowGlobalLookup)
|
||||||
{
|
{
|
||||||
AssertCurrentNode(leftNode);
|
AssertCurrentNode(leftNode);
|
||||||
|
|
||||||
|
@ -5879,9 +5884,15 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
|
||||||
auto leftIdentifier = (BfIdentifierNode*)leftNode;
|
auto leftIdentifier = (BfIdentifierNode*)leftNode;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
bool isGlobalLookup = false;
|
||||||
|
|
||||||
auto nextToken = mVisitorPos.Get(mVisitorPos.mReadPos + 1);
|
auto nextToken = mVisitorPos.Get(mVisitorPos.mReadPos + 1);
|
||||||
auto tokenNode = BfNodeDynCast<BfTokenNode>(nextToken);
|
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;
|
return leftIdentifier;
|
||||||
|
|
||||||
auto nextNextToken = mVisitorPos.Get(mVisitorPos.mReadPos + 2);
|
auto nextNextToken = mVisitorPos.Get(mVisitorPos.mReadPos + 2);
|
||||||
|
@ -5906,6 +5917,22 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
|
||||||
return leftIdentifier;
|
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
|
// 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);
|
||||||
if ((prevNodeToken != NULL) &&
|
if ((prevNodeToken != NULL) &&
|
||||||
|
@ -7935,7 +7962,7 @@ BfInvocationExpression* BfReducer::CreateInvocationExpression(BfAstNode* target,
|
||||||
|
|
||||||
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
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);
|
auto scopedInvocationTarget = CreateScopedInvocationTarget(invocationExpr->mTarget, nextToken);
|
||||||
invocationExpr->SetSrcEnd(scopedInvocationTarget->GetSrcEnd());
|
invocationExpr->SetSrcEnd(scopedInvocationTarget->GetSrcEnd());
|
||||||
|
@ -8317,6 +8344,10 @@ BfScopedInvocationTarget* BfReducer::CreateScopedInvocationTarget(BfAstNode*& ta
|
||||||
MEMBER_SET(scopedInvocationTarget, mColonToken, colonToken);
|
MEMBER_SET(scopedInvocationTarget, mColonToken, colonToken);
|
||||||
|
|
||||||
mVisitorPos.MoveNext();
|
mVisitorPos.MoveNext();
|
||||||
|
|
||||||
|
if (colonToken->mToken == BfToken_ColonColon)
|
||||||
|
return scopedInvocationTarget;
|
||||||
|
|
||||||
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
||||||
{
|
{
|
||||||
if ((nextToken->GetToken() == BfToken_Colon) || (nextToken->GetToken() == BfToken_Mixin))
|
if ((nextToken->GetToken() == BfToken_Colon) || (nextToken->GetToken() == BfToken_Mixin))
|
||||||
|
@ -8473,7 +8504,7 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
||||||
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||||
if (nextToken == NULL)
|
if (nextToken == NULL)
|
||||||
return allocToken;
|
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;
|
return allocToken;
|
||||||
|
|
||||||
auto scopeNode = mAlloc->Alloc<BfScopeNode>();
|
auto scopeNode = mAlloc->Alloc<BfScopeNode>();
|
||||||
|
@ -8504,6 +8535,11 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
|
||||||
FailAfter("Expected scope name", scopeNode);
|
FailAfter("Expected scope name", scopeNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (nextToken->mToken == BfToken_ColonColon)
|
||||||
|
{
|
||||||
|
MEMBER_SET(scopeNode, mColonToken, nextToken);
|
||||||
|
mVisitorPos.MoveNext();
|
||||||
|
}
|
||||||
|
|
||||||
nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
|
||||||
if (nextToken == NULL)
|
if (nextToken == NULL)
|
||||||
|
|
|
@ -231,7 +231,7 @@ public:
|
||||||
void ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, BfBlock* block);
|
void ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, BfBlock* block);
|
||||||
BfAstNode* ReadTypeMember(BfTokenNode* node, bool declStarted = false, int depth = 0, BfAstNode* deferredHeadNode = NULL);
|
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);
|
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 TryIdentifierConvert(int readPos);
|
||||||
void CreateQualifiedNames(BfAstNode* node);
|
void CreateQualifiedNames(BfAstNode* node);
|
||||||
BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode);
|
BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode);
|
||||||
|
|
|
@ -42,7 +42,8 @@ enum BfResolveTypeRefFlags
|
||||||
BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000,
|
BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000,
|
||||||
BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000,
|
BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000,
|
||||||
BfResolveTypeRefFlag_IgnoreProtection = 0x100000,
|
BfResolveTypeRefFlag_IgnoreProtection = 0x100000,
|
||||||
BfResolveTypeRefFlag_SpecializedProject = 0x200000
|
BfResolveTypeRefFlag_SpecializedProject = 0x200000,
|
||||||
|
BfResolveTypeRefFlag_GlobalLookup = 0x400000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfTypeNameFlags : uint16
|
enum BfTypeNameFlags : uint16
|
||||||
|
@ -1735,7 +1736,7 @@ struct BfTypeLookupEntry
|
||||||
enum Flags : uint8
|
enum Flags : uint8
|
||||||
{
|
{
|
||||||
Flags_None,
|
Flags_None,
|
||||||
Flags_SpecializedProject
|
Flags_SpecializedProject,
|
||||||
};
|
};
|
||||||
|
|
||||||
BfAtomComposite mName;
|
BfAtomComposite mName;
|
||||||
|
|
|
@ -285,6 +285,8 @@ void BfSourceClassifier::Visit(BfQualifiedNameNode* qualifiedName)
|
||||||
Visit((BfAstNode*)qualifiedName);
|
Visit((BfAstNode*)qualifiedName);
|
||||||
|
|
||||||
VisitChild(qualifiedName->mLeft);
|
VisitChild(qualifiedName->mLeft);
|
||||||
|
if (qualifiedName->IsGlobalLookup())
|
||||||
|
SetElementType(qualifiedName->mLeft, BfSourceElementType_Namespace);
|
||||||
VisitChild(qualifiedName->mDot);
|
VisitChild(qualifiedName->mDot);
|
||||||
VisitChild(qualifiedName->mRight);
|
VisitChild(qualifiedName->mRight);
|
||||||
if (BfNodeIsExact<BfIdentifierNode>(qualifiedName->mRight))
|
if (BfNodeIsExact<BfIdentifierNode>(qualifiedName->mRight))
|
||||||
|
@ -350,6 +352,8 @@ void BfSourceClassifier::Visit(BfQualifiedTypeReference* qualifiedType)
|
||||||
Visit((BfAstNode*)qualifiedType);
|
Visit((BfAstNode*)qualifiedType);
|
||||||
|
|
||||||
VisitChild(qualifiedType->mLeft);
|
VisitChild(qualifiedType->mLeft);
|
||||||
|
if (qualifiedType->IsGlobalLookup())
|
||||||
|
SetElementType(qualifiedType->mLeft, BfSourceElementType_Namespace);
|
||||||
VisitChild(qualifiedType->mDot);
|
VisitChild(qualifiedType->mDot);
|
||||||
VisitChild(qualifiedType->mRight);
|
VisitChild(qualifiedType->mRight);
|
||||||
}
|
}
|
||||||
|
@ -495,6 +499,8 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
|
||||||
if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
|
if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
|
||||||
{
|
{
|
||||||
VisitChild(qualifiedName->mLeft);
|
VisitChild(qualifiedName->mLeft);
|
||||||
|
if (qualifiedName->IsGlobalLookup())
|
||||||
|
SetElementType(qualifiedName->mLeft, BfSourceElementType_Namespace);
|
||||||
VisitChild(qualifiedName->mDot);
|
VisitChild(qualifiedName->mDot);
|
||||||
VisitChild(qualifiedName->mRight);
|
VisitChild(qualifiedName->mRight);
|
||||||
identifier = qualifiedName->mRight;
|
identifier = qualifiedName->mRight;
|
||||||
|
|
|
@ -7387,6 +7387,8 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
||||||
|
|
||||||
BfScopeData* scope = NULL;
|
BfScopeData* scope = NULL;
|
||||||
|
|
||||||
|
auto scopeNameNode = deferStmt->GetScopeNameNode();
|
||||||
|
|
||||||
if (deferStmt->mScopeToken != NULL)
|
if (deferStmt->mScopeToken != NULL)
|
||||||
{
|
{
|
||||||
if (deferStmt->mScopeToken->GetToken() == BfToken_Scope)
|
if (deferStmt->mScopeToken->GetToken() == BfToken_Scope)
|
||||||
|
@ -7394,9 +7396,9 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
||||||
else
|
else
|
||||||
scope = &mCurMethodState->mHeadScope;
|
scope = &mCurMethodState->mHeadScope;
|
||||||
}
|
}
|
||||||
else if (deferStmt->mScopeName != NULL)
|
else if (scopeNameNode != NULL)
|
||||||
{
|
{
|
||||||
scope = FindScope(deferStmt->mScopeName, true);
|
scope = FindScope(scopeNameNode, true);
|
||||||
|
|
||||||
if (scope == NULL)
|
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