1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 20:42:21 +02:00

Allowing capture of shadowed (@) variables

This commit is contained in:
Brian Fiete 2020-01-23 13:07:43 -08:00
parent 95e4c1b3ca
commit e1958d165e
2 changed files with 57 additions and 20 deletions

View file

@ -2818,11 +2818,16 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
}
int varSkipCount = 0;
StringT<128> wantName = findName;
while (wantName.StartsWith("@"))
StringT<128> wantName;
wantName.Reference(findName);
if (findName.StartsWith('@'))
{
varSkipCount++;
wantName.Remove(0);
wantName = findName;
while (wantName.StartsWith("@"))
{
varSkipCount++;
wantName.Remove(0);
}
}
if (wantName.IsEmpty())
@ -2887,12 +2892,31 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
// Check for the captured locals. It's important we do it here so we get local-first precedence still
if (closureTypeInst != NULL)
{
{
int varSkipCount = 0;
StringT<128> wantName;
wantName.Reference(findName);
if (findName.StartsWith('@'))
{
wantName = findName;
while (wantName.StartsWith("@"))
{
varSkipCount++;
wantName.Remove(0);
}
}
closureTypeInst->mTypeDef->PopulateMemberSets();
BfMemberSetEntry* memberSetEntry = NULL;
if (closureTypeInst->mTypeDef->mFieldSet.TryGetWith(findName, &memberSetEntry))
{
if (closureTypeInst->mTypeDef->mFieldSet.TryGetWith((StringImpl&)wantName, &memberSetEntry))
{
auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
while ((varSkipCount > 0) && (fieldDef != NULL))
{
fieldDef = fieldDef->mNextWithSameName;
varSkipCount--;
}
auto& field = closureTypeInst->mFieldInstances[fieldDef->mIdx];
if (!field.mResolvedType->IsValuelessType())
{
@ -3145,7 +3169,22 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
else if (target.mType != NULL)
{
startCheckType = target.mType->ToTypeInstance();
}
}
String findName;
int varSkipCount = 0;
if (fieldName.StartsWith('@'))
{
findName = fieldName;
while (findName.StartsWith('@'))
{
findName.Remove(0);
varSkipCount++;
}
}
else
findName.Reference(fieldName);
auto activeTypeDef = mModule->GetActiveTypeDef();
for (int pass = 0; pass < 2; pass++)
@ -3159,9 +3198,14 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
curCheckType->mTypeDef->PopulateMemberSets();
BfFieldDef* nextField = NULL;
BfMemberSetEntry* entry;
if (curCheckType->mTypeDef->mFieldSet.TryGetWith(fieldName, &entry))
if (curCheckType->mTypeDef->mFieldSet.TryGetWith(findName, &entry))
nextField = (BfFieldDef*)entry->mMemberDef;
while ((varSkipCount > 0) && (nextField != NULL))
{
nextField = nextField->mNextWithSameName;
}
BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
BfFieldDef* matchedField = NULL;
while (nextField != NULL)
@ -3174,16 +3218,9 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
continue;
}
//OLD:
bool isResolvingFields = curCheckType->mResolvingConstField || curCheckType->mResolvingVarField;
// mCurMethodState is NULL when we're pre-evaluating var field expressions
// to determine their type in PopulateFields
/*if (!isResolvingFields)
{
mModule->PopulateType(curCheckType, BfPopulateType_Data);
}*/
if (curCheckType->mFieldInstances.IsEmpty())
{
mModule->PopulateType(curCheckType, BfPopulateType_Data);
@ -3219,7 +3256,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
}
if (matchedField != NULL)
{
{
auto field = matchedField;
auto fieldInstance = &curCheckType->mFieldInstances[field->mIdx];

View file

@ -822,7 +822,7 @@ struct BfMemberSetEntry
return mMemberDef->mName == other.mMemberDef->mName;
}
bool operator==(const String& other) const
bool operator==(const StringImpl& other) const
{
return mMemberDef->mName == other;
}