mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Added nameof
This commit is contained in:
parent
dd0d67cca1
commit
7dd2324fcf
13 changed files with 307 additions and 13 deletions
|
@ -361,6 +361,11 @@ void BfStructuralVisitor::Visit(BfOffsetOfExpression* offsetOfExpr)
|
||||||
Visit(offsetOfExpr->ToBase());
|
Visit(offsetOfExpr->ToBase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfStructuralVisitor::Visit(BfNameOfExpression* nameOfExpr)
|
||||||
|
{
|
||||||
|
Visit(nameOfExpr->ToBase());
|
||||||
|
}
|
||||||
|
|
||||||
void BfStructuralVisitor::Visit(BfIsConstExpression* isConstExpr)
|
void BfStructuralVisitor::Visit(BfIsConstExpression* isConstExpr)
|
||||||
{
|
{
|
||||||
Visit(isConstExpr->ToBase());
|
Visit(isConstExpr->ToBase());
|
||||||
|
|
|
@ -381,6 +381,7 @@ class BfTypeAttrExpression;
|
||||||
class BfSizeOfExpression;
|
class BfSizeOfExpression;
|
||||||
class BfAlignOfExpression;
|
class BfAlignOfExpression;
|
||||||
class BfOffsetOfExpression;
|
class BfOffsetOfExpression;
|
||||||
|
class BfNameOfExpression;
|
||||||
class BfStrideOfExpression;
|
class BfStrideOfExpression;
|
||||||
class BfIsConstExpression;
|
class BfIsConstExpression;
|
||||||
class BfDefaultExpression;
|
class BfDefaultExpression;
|
||||||
|
@ -508,6 +509,7 @@ public:
|
||||||
virtual void Visit(BfAlignOfExpression* alignOfExpr);
|
virtual void Visit(BfAlignOfExpression* alignOfExpr);
|
||||||
virtual void Visit(BfStrideOfExpression* strideOfExpr);
|
virtual void Visit(BfStrideOfExpression* strideOfExpr);
|
||||||
virtual void Visit(BfOffsetOfExpression* offsetOfExpr);
|
virtual void Visit(BfOffsetOfExpression* offsetOfExpr);
|
||||||
|
virtual void Visit(BfNameOfExpression* nameOfExpr);
|
||||||
virtual void Visit(BfIsConstExpression* isConstExpr);
|
virtual void Visit(BfIsConstExpression* isConstExpr);
|
||||||
virtual void Visit(BfDefaultExpression* defaultExpr);
|
virtual void Visit(BfDefaultExpression* defaultExpr);
|
||||||
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
||||||
|
@ -2728,6 +2730,16 @@ public:
|
||||||
BfIdentifierNode* mMemberName;
|
BfIdentifierNode* mMemberName;
|
||||||
}; BF_AST_DECL(BfOffsetOfExpression, BfTypeAttrExpression);
|
}; BF_AST_DECL(BfOffsetOfExpression, BfTypeAttrExpression);
|
||||||
|
|
||||||
|
class BfNameOfExpression : public BfExpression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BF_AST_TYPE(BfNameOfExpression, BfExpression);
|
||||||
|
BfTokenNode* mToken;
|
||||||
|
BfTokenNode* mOpenParen;
|
||||||
|
BfAstNode* mTarget;
|
||||||
|
BfTokenNode* mCloseParen;
|
||||||
|
}; BF_AST_DECL(BfNameOfExpression, BfExpression);
|
||||||
|
|
||||||
class BfIsConstExpression : public BfExpression
|
class BfIsConstExpression : public BfExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -689,7 +689,13 @@ void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfAutoComplete::CheckProtection(BfProtection protection, BfTypeDef* typeDef, bool allowProtected, bool allowPrivate)
|
bool BfAutoComplete::CheckProtection(BfProtection protection, BfTypeDef* typeDef, bool allowProtected, bool allowPrivate)
|
||||||
{
|
{
|
||||||
|
if (mResolveType == BfResolveType_GetSymbolInfo)
|
||||||
|
{
|
||||||
|
// This is needed for nameof on private inner types
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ((protection == BfProtection_Internal) && (typeDef != NULL))
|
if ((protection == BfProtection_Internal) && (typeDef != NULL))
|
||||||
{
|
{
|
||||||
return mModule->CheckProtection(protection, typeDef, allowProtected, allowPrivate);
|
return mModule->CheckProtection(protection, typeDef, allowProtected, allowPrivate);
|
||||||
|
|
|
@ -519,6 +519,8 @@ void BfElementVisitor::Visit(BfTypeAttrExpression* typeAttrExpr)
|
||||||
|
|
||||||
void BfElementVisitor::Visit(BfOffsetOfExpression* offsetOfExpr)
|
void BfElementVisitor::Visit(BfOffsetOfExpression* offsetOfExpr)
|
||||||
{
|
{
|
||||||
|
Visit(offsetOfExpr->ToBase());
|
||||||
|
|
||||||
VisitChild(offsetOfExpr->mToken);
|
VisitChild(offsetOfExpr->mToken);
|
||||||
VisitChild(offsetOfExpr->mOpenParen);
|
VisitChild(offsetOfExpr->mOpenParen);
|
||||||
VisitChild(offsetOfExpr->mTypeRef);
|
VisitChild(offsetOfExpr->mTypeRef);
|
||||||
|
@ -527,6 +529,16 @@ void BfElementVisitor::Visit(BfOffsetOfExpression* offsetOfExpr)
|
||||||
VisitChild(offsetOfExpr->mCloseParen);
|
VisitChild(offsetOfExpr->mCloseParen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfElementVisitor::Visit(BfNameOfExpression* nameOfExpr)
|
||||||
|
{
|
||||||
|
Visit(nameOfExpr->ToBase());
|
||||||
|
|
||||||
|
VisitChild(nameOfExpr->mToken);
|
||||||
|
VisitChild(nameOfExpr->mOpenParen);
|
||||||
|
VisitChild(nameOfExpr->mTarget);
|
||||||
|
VisitChild(nameOfExpr->mCloseParen);
|
||||||
|
}
|
||||||
|
|
||||||
void BfElementVisitor::Visit(BfDefaultExpression* defaultExpr)
|
void BfElementVisitor::Visit(BfDefaultExpression* defaultExpr)
|
||||||
{
|
{
|
||||||
Visit(defaultExpr->ToBase());
|
Visit(defaultExpr->ToBase());
|
||||||
|
|
|
@ -72,6 +72,7 @@ public:
|
||||||
virtual void Visit(BfParameterDeclaration* paramDecl);
|
virtual void Visit(BfParameterDeclaration* paramDecl);
|
||||||
virtual void Visit(BfTypeAttrExpression* typeAttrExpr);
|
virtual void Visit(BfTypeAttrExpression* typeAttrExpr);
|
||||||
virtual void Visit(BfOffsetOfExpression* offsetOfExpr);
|
virtual void Visit(BfOffsetOfExpression* offsetOfExpr);
|
||||||
|
virtual void Visit(BfNameOfExpression* nameOfExpr);
|
||||||
virtual void Visit(BfDefaultExpression* defaultExpr);
|
virtual void Visit(BfDefaultExpression* defaultExpr);
|
||||||
virtual void Visit(BfIsConstExpression* isConstExpr);
|
virtual void Visit(BfIsConstExpression* isConstExpr);
|
||||||
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
||||||
|
|
|
@ -3762,6 +3762,49 @@ static bool IsCharType(BfTypeCode typeCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfExprEvaluator::CheckForMethodName(BfAstNode* refNode, BfTypeInstance* typeInst, const StringImpl& findName)
|
||||||
|
{
|
||||||
|
BF_ASSERT((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0);
|
||||||
|
|
||||||
|
auto autoComplete = GetAutoComplete();
|
||||||
|
|
||||||
|
while (typeInst != NULL)
|
||||||
|
{
|
||||||
|
auto typeDef = typeInst->mTypeDef;
|
||||||
|
typeDef->PopulateMemberSets();
|
||||||
|
|
||||||
|
BfMemberSetEntry* memberSetEntry;
|
||||||
|
if (typeDef->mMethodSet.TryGetWith(findName, &memberSetEntry))
|
||||||
|
{
|
||||||
|
if (mModule->mCompiler->mResolvePassData != NULL)
|
||||||
|
mModule->mCompiler->mResolvePassData->HandleMethodReference(refNode, typeDef, (BfMethodDef*)memberSetEntry->mMemberDef);
|
||||||
|
|
||||||
|
if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(refNode)))
|
||||||
|
{
|
||||||
|
autoComplete->SetDefinitionLocation(((BfMethodDef*)memberSetEntry->mMemberDef)->GetRefNode());
|
||||||
|
if ((autoComplete->mResolveType == BfResolveType_GetSymbolInfo) && (autoComplete->mDefType == NULL))
|
||||||
|
{
|
||||||
|
autoComplete->mDefType = typeDef;
|
||||||
|
autoComplete->mDefMethod = (BfMethodDef*)memberSetEntry->mMemberDef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mModule->mCompiler->mResolvePassData != NULL)
|
||||||
|
{
|
||||||
|
if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(refNode))
|
||||||
|
sourceClassifier->SetElementType(refNode, BfSourceElementType_Method);
|
||||||
|
}
|
||||||
|
|
||||||
|
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NameOfSuccess);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
typeInst = typeInst->mBaseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool BfExprEvaluator::IsVar(BfType* type, bool forceIgnoreWrites)
|
bool BfExprEvaluator::IsVar(BfType* type, bool forceIgnoreWrites)
|
||||||
{
|
{
|
||||||
if (type->IsVar())
|
if (type->IsVar())
|
||||||
|
@ -4591,6 +4634,9 @@ void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0) && (mModule->mCurTypeInstance != NULL) && (CheckForMethodName(identifierNode, mModule->mCurTypeInstance, identifierNode->ToString())))
|
||||||
|
return;
|
||||||
|
|
||||||
if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0)
|
if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0)
|
||||||
mModule->Fail("Identifier not found", identifierNode);
|
mModule->Fail("Identifier not found", identifierNode);
|
||||||
}
|
}
|
||||||
|
@ -5063,7 +5109,7 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe
|
||||||
}
|
}
|
||||||
else if (!target)
|
else if (!target)
|
||||||
{
|
{
|
||||||
if (mModule->PreFail())
|
if (((mBfEvalExprFlags & BfEvalExprFlags_NameOf) == 0) && (mModule->PreFail()))
|
||||||
{
|
{
|
||||||
if ((flags & BfLookupFieldFlag_CheckingOuter) != 0)
|
if ((flags & BfLookupFieldFlag_CheckingOuter) != 0)
|
||||||
mModule->Fail(StrFormat("An instance reference is required to reference non-static outer field '%s.%s'", mModule->TypeToString(typeInstance).c_str(), fieldDef->mName.c_str()),
|
mModule->Fail(StrFormat("An instance reference is required to reference non-static outer field '%s.%s'", mModule->TypeToString(typeInstance).c_str(), fieldDef->mName.c_str()),
|
||||||
|
@ -5530,7 +5576,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
||||||
auto prop = nextProp;
|
auto prop = nextProp;
|
||||||
nextProp = nextProp->mNextWithSameName;
|
nextProp = nextProp->mNextWithSameName;
|
||||||
|
|
||||||
if ((!isFailurePass) && (!mModule->CheckProtection(protectionCheckFlags, curCheckType, prop->mDeclaringType->mProject, prop->mProtection, startCheckType)))
|
if ((!isFailurePass) && ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) == 0) && (!mModule->CheckProtection(protectionCheckFlags, curCheckType, prop->mDeclaringType->mProject, prop->mProtection, startCheckType)))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -5543,7 +5589,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!target.IsStatic()) || (prop->mIsStatic))
|
if ((!target.IsStatic()) || (prop->mIsStatic) || ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0))
|
||||||
{
|
{
|
||||||
if (!mModule->IsInSpecializedSection())
|
if (!mModule->IsInSpecializedSection())
|
||||||
{
|
{
|
||||||
|
@ -10864,6 +10910,10 @@ void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode*
|
||||||
{
|
{
|
||||||
FixitAddMember(typeInst, mExpectingType, nameRight->ToString(), false);
|
FixitAddMember(typeInst, mExpectingType, nameRight->ToString(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0) && (typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, fieldName)))
|
||||||
|
return;
|
||||||
|
|
||||||
mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(lookupType).c_str()), nameRight);
|
mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(lookupType).c_str()), nameRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11013,6 +11063,13 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0)
|
||||||
|
{
|
||||||
|
auto typeInst = lookupType.mType->ToTypeInstance();
|
||||||
|
if ((typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, findName)))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0)
|
if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0)
|
||||||
mModule->Fail("Field not found", nameRight);
|
mModule->Fail("Field not found", nameRight);
|
||||||
return;
|
return;
|
||||||
|
@ -11885,6 +11942,135 @@ void BfExprEvaluator::Visit(BfOffsetOfExpression* offsetOfExpr)
|
||||||
DoTypeIntAttr(offsetOfExpr->mTypeRef, offsetOfExpr->mCommaToken, offsetOfExpr->mMemberName, BfToken_OffsetOf);
|
DoTypeIntAttr(offsetOfExpr->mTypeRef, offsetOfExpr->mCommaToken, offsetOfExpr->mMemberName, BfToken_OffsetOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfExprEvaluator::Visit(BfNameOfExpression* nameOfExpr)
|
||||||
|
{
|
||||||
|
String name;
|
||||||
|
|
||||||
|
if (mModule->IsInSpecializedGeneric())
|
||||||
|
{
|
||||||
|
if (auto identifierNode = BfNodeDynCastExact<BfIdentifierNode>(nameOfExpr->mTarget))
|
||||||
|
{
|
||||||
|
// This is necessary so we don't resolve 'T' to the actual generic argument type
|
||||||
|
name = identifierNode->ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.IsEmpty())
|
||||||
|
{
|
||||||
|
auto type = mModule->ResolveTypeRef(nameOfExpr->mTarget, {}, BfPopulateType_IdentityNoRemapAlias,
|
||||||
|
(BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowUnboundGeneric | BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_IgnoreProtection));
|
||||||
|
if (type != NULL)
|
||||||
|
{
|
||||||
|
auto typeInst = type->ToTypeInstance();
|
||||||
|
if (typeInst != NULL)
|
||||||
|
name = typeInst->mTypeDef->mName->ToString();
|
||||||
|
else
|
||||||
|
name = mModule->TypeToString(type);
|
||||||
|
|
||||||
|
mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
|
||||||
|
|
||||||
|
// Just do this for autocomplete
|
||||||
|
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
||||||
|
VisitChild(nameOfExpr->mTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.IsEmpty())
|
||||||
|
{
|
||||||
|
if (auto identifer = BfNodeDynCast<BfIdentifierNode>(nameOfExpr->mTarget))
|
||||||
|
{
|
||||||
|
String targetStr = nameOfExpr->mTarget->ToString();
|
||||||
|
BfAtomComposite targetComposite;
|
||||||
|
bool isValid = mModule->mSystem->ParseAtomComposite(targetStr, targetComposite);
|
||||||
|
bool namespaceExists = false;
|
||||||
|
|
||||||
|
BfProject* bfProject = NULL;
|
||||||
|
auto activeTypeDef = mModule->GetActiveTypeDef();
|
||||||
|
if (activeTypeDef != NULL)
|
||||||
|
bfProject = activeTypeDef->mProject;
|
||||||
|
auto _CheckProject = [&](BfProject* project)
|
||||||
|
{
|
||||||
|
if ((isValid) && (project->mNamespaces.ContainsKey(targetComposite)))
|
||||||
|
namespaceExists = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (bfProject != NULL)
|
||||||
|
{
|
||||||
|
for (int depIdx = -1; depIdx < (int)bfProject->mDependencies.size(); depIdx++)
|
||||||
|
{
|
||||||
|
BfProject* depProject = (depIdx == -1) ? bfProject : bfProject->mDependencies[depIdx];
|
||||||
|
_CheckProject(depProject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto project : mModule->mSystem->mProjects)
|
||||||
|
_CheckProject(project);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (namespaceExists)
|
||||||
|
{
|
||||||
|
if (mModule->mCompiler->mResolvePassData != NULL)
|
||||||
|
{
|
||||||
|
if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(nameOfExpr->mTarget))
|
||||||
|
{
|
||||||
|
BfAstNode* checkIdentifier = identifer;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto qualifiedIdentifier = BfNodeDynCast<BfQualifiedNameNode>(checkIdentifier);
|
||||||
|
if (qualifiedIdentifier == NULL)
|
||||||
|
break;
|
||||||
|
sourceClassifier->SetElementType(qualifiedIdentifier->mRight, BfSourceElementType_Namespace);
|
||||||
|
checkIdentifier = qualifiedIdentifier->mLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceClassifier->SetElementType(checkIdentifier, BfSourceElementType_Namespace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name = targetComposite.mParts[targetComposite.mSize - 1]->ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.IsEmpty())
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NameOf));
|
||||||
|
VisitChild(nameOfExpr->mTarget);
|
||||||
|
|
||||||
|
if ((mBfEvalExprFlags & BfEvalExprFlags_NameOfSuccess) != 0)
|
||||||
|
{
|
||||||
|
BfAstNode* nameNode = nameOfExpr->mTarget;
|
||||||
|
if (auto attributedIdentifierNode = BfNodeDynCast<BfAttributedIdentifierNode>(nameNode))
|
||||||
|
nameNode = attributedIdentifierNode->mIdentifier;
|
||||||
|
if (auto memberReferenceExpr = BfNodeDynCast<BfMemberReferenceExpression>(nameNode))
|
||||||
|
nameNode = memberReferenceExpr->mMemberName;
|
||||||
|
if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(nameNode))
|
||||||
|
nameNode = qualifiedNameNode->mRight;
|
||||||
|
name = nameNode->ToString();
|
||||||
|
}
|
||||||
|
else if (mResultFieldInstance != NULL)
|
||||||
|
{
|
||||||
|
auto fieldDef = mResultFieldInstance->GetFieldDef();
|
||||||
|
if (fieldDef != NULL)
|
||||||
|
name = fieldDef->mName;
|
||||||
|
}
|
||||||
|
else if (mResultLocalVar != NULL)
|
||||||
|
{
|
||||||
|
name = mResultLocalVar->mName;
|
||||||
|
}
|
||||||
|
else if (mPropDef != NULL)
|
||||||
|
{
|
||||||
|
name = mPropDef->mName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((name.IsEmpty()) && (nameOfExpr->mTarget != NULL))
|
||||||
|
mModule->Fail("Expression does not have a name", nameOfExpr->mTarget);
|
||||||
|
|
||||||
|
mResult = BfTypedValue(mModule->GetStringObjectValue(name), mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
|
||||||
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::Visit(BfIsConstExpression* isConstExpr)
|
void BfExprEvaluator::Visit(BfIsConstExpression* isConstExpr)
|
||||||
{
|
{
|
||||||
if (isConstExpr->mExpression == NULL)
|
if (isConstExpr->mExpression == NULL)
|
||||||
|
@ -21142,6 +21328,13 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx
|
||||||
{
|
{
|
||||||
if (auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mMemberName))
|
if (auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mMemberName))
|
||||||
{
|
{
|
||||||
|
if ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0)
|
||||||
|
{
|
||||||
|
auto typeInst = thisValue.mType->ToTypeInstance();
|
||||||
|
if ((typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, findName)))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mResult.mType = mModule->ResolveInnerType(thisValue.mType, targetIdentifier, BfPopulateType_Declaration);
|
mResult.mType = mModule->ResolveInnerType(thisValue.mType, targetIdentifier, BfPopulateType_Declaration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,8 +273,6 @@ public:
|
||||||
bool IsVarCall(BfType*& outReturnType);
|
bool IsVarCall(BfType*& outReturnType);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BfBaseClassWalker
|
class BfBaseClassWalker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -432,6 +430,7 @@ public:
|
||||||
BfExprEvaluator(BfModule* module);
|
BfExprEvaluator(BfModule* module);
|
||||||
~BfExprEvaluator();
|
~BfExprEvaluator();
|
||||||
|
|
||||||
|
bool CheckForMethodName(BfAstNode* refNode, BfTypeInstance* typeInst, const StringImpl& findName);
|
||||||
bool IsVar(BfType* type, bool forceIgnoreWrites = false);
|
bool IsVar(BfType* type, bool forceIgnoreWrites = false);
|
||||||
void GetLiteral(BfAstNode* refNode, const BfVariant& variant);
|
void GetLiteral(BfAstNode* refNode, const BfVariant& variant);
|
||||||
void FinishExpressionResult();
|
void FinishExpressionResult();
|
||||||
|
@ -559,6 +558,7 @@ public:
|
||||||
virtual void Visit(BfAlignOfExpression* alignOfExpr) override;
|
virtual void Visit(BfAlignOfExpression* alignOfExpr) override;
|
||||||
virtual void Visit(BfStrideOfExpression* strideOfExpr) override;
|
virtual void Visit(BfStrideOfExpression* strideOfExpr) override;
|
||||||
virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override;
|
virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override;
|
||||||
|
virtual void Visit(BfNameOfExpression* nameOfExpr) override;
|
||||||
virtual void Visit(BfIsConstExpression* isConstExpr) override;
|
virtual void Visit(BfIsConstExpression* isConstExpr) override;
|
||||||
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
||||||
virtual void Visit(BfUninitializedExpression* uninitialziedExpr) override;
|
virtual void Visit(BfUninitializedExpression* uninitialziedExpr) override;
|
||||||
|
|
|
@ -54,7 +54,7 @@ enum BfPopulateType
|
||||||
BfPopulateType_Full_Force
|
BfPopulateType_Full_Force
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfEvalExprFlags
|
enum BfEvalExprFlags : int64
|
||||||
{
|
{
|
||||||
BfEvalExprFlags_None = 0,
|
BfEvalExprFlags_None = 0,
|
||||||
BfEvalExprFlags_ExplicitCast = 1,
|
BfEvalExprFlags_ExplicitCast = 1,
|
||||||
|
@ -89,6 +89,8 @@ enum BfEvalExprFlags
|
||||||
BfEvalExprFlags_AllowGenericConstValue = 0x20000000,
|
BfEvalExprFlags_AllowGenericConstValue = 0x20000000,
|
||||||
BfEvalExprFlags_IsExpressionBody = 0x40000000,
|
BfEvalExprFlags_IsExpressionBody = 0x40000000,
|
||||||
BfEvalExprFlags_AppendFieldInitializer = 0x80000000,
|
BfEvalExprFlags_AppendFieldInitializer = 0x80000000,
|
||||||
|
BfEvalExprFlags_NameOf = 0x100000000LL,
|
||||||
|
BfEvalExprFlags_NameOfSuccess = 0x200000000LL,
|
||||||
|
|
||||||
BfEvalExprFlags_InheritFlags = BfEvalExprFlags_NoAutoComplete | BfEvalExprFlags_Comptime | BfEvalExprFlags_DeclType
|
BfEvalExprFlags_InheritFlags = BfEvalExprFlags_NoAutoComplete | BfEvalExprFlags_Comptime | BfEvalExprFlags_DeclType
|
||||||
};
|
};
|
||||||
|
@ -1947,7 +1949,7 @@ public:
|
||||||
BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
||||||
BfType* ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
BfType* ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
||||||
BfType* ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
BfType* ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
||||||
BfType* ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopulateType populateType = BfPopulateType_Data, bool ignoreErrors = false, int numGenericArgs = 0);
|
BfType* ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopulateType populateType = BfPopulateType_Data, bool ignoreErrors = false, int numGenericArgs = 0, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
||||||
BfTypeDef* GetCombinedPartialTypeDef(BfTypeDef* type);
|
BfTypeDef* GetCombinedPartialTypeDef(BfTypeDef* type);
|
||||||
BfTypeInstance* GetOuterType(BfType* type);
|
BfTypeInstance* GetOuterType(BfType* type);
|
||||||
bool IsInnerType(BfType* checkInnerType, BfType* checkOuterType);
|
bool IsInnerType(BfType* checkInnerType, BfType* checkOuterType);
|
||||||
|
|
|
@ -8029,7 +8029,7 @@ void BfModule::HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDe
|
||||||
mCompiler->mResolvePassData->HandleMethodGenericParam(refNode, typeDef, methodDef, methodGenericParamIdx);
|
mCompiler->mResolvePassData->HandleMethodGenericParam(refNode, typeDef, methodDef, methodGenericParamIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopulateType populateType, bool ignoreErrors, int numGenericArgs)
|
BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopulateType populateType, bool ignoreErrors, int numGenericArgs, BfResolveTypeRefFlags resolveFlags)
|
||||||
{
|
{
|
||||||
BfTypeDef* nestedTypeDef = NULL;
|
BfTypeDef* nestedTypeDef = NULL;
|
||||||
|
|
||||||
|
@ -8092,7 +8092,8 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopu
|
||||||
{
|
{
|
||||||
auto latestCheckType = checkType->GetLatest();
|
auto latestCheckType = checkType->GetLatest();
|
||||||
|
|
||||||
if ((!isFailurePass) && (!CheckProtection(latestCheckType->mProtection, latestCheckType, allowProtected, allowPrivate)))
|
if ((!isFailurePass) && ((resolveFlags & BfResolveTypeRefFlag_IgnoreProtection) == 0) &&
|
||||||
|
(!CheckProtection(latestCheckType->mProtection, latestCheckType, allowProtected, allowPrivate)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (checkType->mProject != checkOuterType->mTypeDef->mProject)
|
if (checkType->mProject != checkOuterType->mTypeDef->mProject)
|
||||||
|
@ -8135,7 +8136,7 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopu
|
||||||
|
|
||||||
if (nestedTypeDef == NULL)
|
if (nestedTypeDef == NULL)
|
||||||
{
|
{
|
||||||
if (!mIgnoreErrors && !ignoreErrors)
|
if ((!mIgnoreErrors) && (!ignoreErrors) && ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0))
|
||||||
{
|
{
|
||||||
StringT<64> name;
|
StringT<64> name;
|
||||||
name.Append(findName);
|
name.Append(findName);
|
||||||
|
@ -11020,7 +11021,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolvedType = ResolveInnerType(leftType, qualifiedTypeRef->mRight, populateType, false, numGenericArgs);
|
auto resolvedType = ResolveInnerType(leftType, qualifiedTypeRef->mRight, populateType, false, numGenericArgs, resolveFlags);
|
||||||
if ((resolvedType != NULL) && (mCurTypeInstance != NULL))
|
if ((resolvedType != NULL) && (mCurTypeInstance != NULL))
|
||||||
AddDependency(leftType, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
|
AddDependency(leftType, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
|
||||||
return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
|
return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags);
|
||||||
|
|
|
@ -3174,6 +3174,8 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro
|
||||||
case TOKEN_HASH('n', 'a', 'm', 'e'):
|
case TOKEN_HASH('n', 'a', 'm', 'e'):
|
||||||
if (SrcPtrHasToken("namespace"))
|
if (SrcPtrHasToken("namespace"))
|
||||||
mToken = BfToken_Namespace;
|
mToken = BfToken_Namespace;
|
||||||
|
else if (SrcPtrHasToken("nameof"))
|
||||||
|
mToken = BfToken_NameOf;
|
||||||
break;
|
break;
|
||||||
case TOKEN_HASH('n', 'e', 'w', 0):
|
case TOKEN_HASH('n', 'e', 'w', 0):
|
||||||
if (SrcPtrHasToken("new"))
|
if (SrcPtrHasToken("new"))
|
||||||
|
|
|
@ -2352,6 +2352,41 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
||||||
exprLeft = CreateMemberReferenceExpression(typeRef);
|
exprLeft = CreateMemberReferenceExpression(typeRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (tokenNode->GetToken() == BfToken_NameOf)
|
||||||
|
{
|
||||||
|
BfNameOfExpression* nameOfExpr = mAlloc->Alloc<BfNameOfExpression>();
|
||||||
|
ReplaceNode(tokenNode, nameOfExpr);
|
||||||
|
nameOfExpr->mToken = tokenNode;
|
||||||
|
tokenNode = ExpectTokenAfter(nameOfExpr, BfToken_LParen);
|
||||||
|
MEMBER_SET_CHECKED(nameOfExpr, mOpenParen, tokenNode);
|
||||||
|
|
||||||
|
mVisitorPos.MoveNext();
|
||||||
|
int outEndNode = -1;
|
||||||
|
bool isTypeRef = IsTypeReference(mVisitorPos.GetCurrent(), BfToken_RParen, -1, &outEndNode);
|
||||||
|
mVisitorPos.mReadPos--;
|
||||||
|
|
||||||
|
if ((isTypeRef) && (outEndNode > 0))
|
||||||
|
{
|
||||||
|
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(mVisitorPos.Get(outEndNode - 1)))
|
||||||
|
{
|
||||||
|
if ((tokenNode->mToken == BfToken_RChevron) || (tokenNode->mToken == BfToken_RDblChevron))
|
||||||
|
{
|
||||||
|
// Can ONLY be a type reference
|
||||||
|
auto typeRef = CreateTypeRefAfter(nameOfExpr);
|
||||||
|
MEMBER_SET_CHECKED(nameOfExpr, mTarget, typeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nameOfExpr->mTarget == NULL)
|
||||||
|
{
|
||||||
|
auto expr = CreateExpressionAfter(nameOfExpr);
|
||||||
|
MEMBER_SET_CHECKED(nameOfExpr, mTarget, expr);
|
||||||
|
}
|
||||||
|
tokenNode = ExpectTokenAfter(nameOfExpr, BfToken_RParen);
|
||||||
|
MEMBER_SET_CHECKED(nameOfExpr, mCloseParen, tokenNode);
|
||||||
|
exprLeft = nameOfExpr;
|
||||||
|
}
|
||||||
|
|
||||||
if (exprLeft == NULL)
|
if (exprLeft == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,7 +40,8 @@ enum BfResolveTypeRefFlags
|
||||||
BfResolveTypeRefFlag_AllowGlobalsSelf = 0x10000,
|
BfResolveTypeRefFlag_AllowGlobalsSelf = 0x10000,
|
||||||
BfResolveTypeRefFlag_AllowImplicitConstExpr = 0x20000,
|
BfResolveTypeRefFlag_AllowImplicitConstExpr = 0x20000,
|
||||||
BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000,
|
BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000,
|
||||||
BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000
|
BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000,
|
||||||
|
BfResolveTypeRefFlag_IgnoreProtection = 0x100000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfTypeNameFlags : uint16
|
enum BfTypeNameFlags : uint16
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#pragma warning disable 168
|
#pragma warning disable 168
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Interop;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace Tests
|
namespace Tests
|
||||||
{
|
{
|
||||||
|
@ -24,5 +26,27 @@ namespace Tests
|
||||||
inStr.Length > 1 || 2 == 3
|
inStr.Length > 1 || 2 == 3
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GetName<T>(String str)
|
||||||
|
{
|
||||||
|
str.Append(nameof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public static void TestNameof()
|
||||||
|
{
|
||||||
|
var point = (x: 3, y: 4);
|
||||||
|
|
||||||
|
Test.Assert(nameof(System) == "System");
|
||||||
|
Test.Assert(nameof(System.Collections) == "Collections");
|
||||||
|
Test.Assert(nameof(point) == "point");
|
||||||
|
Test.Assert(nameof(point.x) == "x");
|
||||||
|
Test.Assert(nameof(Tests.Expressions) == "Expressions");
|
||||||
|
Test.Assert(nameof(c_int) == "c_int");
|
||||||
|
Test.Assert(nameof(List<int>) == "List");
|
||||||
|
Test.Assert(nameof(List<int>.Add) == "Add");
|
||||||
|
Test.Assert(nameof(TestBasics) == "TestBasics");
|
||||||
|
Test.Assert(GetName<String>(.. scope .()) == "T");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue