From 971cecdd99c34e8a48e263baebea17e968fa8dc8 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 6 Jan 2025 07:10:18 -0800 Subject: [PATCH] Allow private member access in initializer block when subclassing --- IDEHelper/Compiler/BfExprEvaluator.cpp | 65 ++++++++++++-------------- IDEHelper/Compiler/BfModule.cpp | 4 ++ IDEHelper/Compiler/BfModule.h | 2 + 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 838b90b9..048c21f3 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -11734,6 +11734,33 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) initValue = mModule->RemoveRef(initValue, false); bool isFirstAdd = true; + SetAndRestoreValue prevPrivateTypeInstance(mModule->mCurMethodState->mPrivateTypeInstance); + BfScopeData newScope; + + if (initExpr->mInlineTypeRef != NULL) + mModule->mCurMethodState->mPrivateTypeInstance = initValue.mType->ToTypeInstance(); + + newScope.mInnerIsConditional = true; + newScope.mCloseNode = initExpr->mCloseBrace; + mModule->mCurMethodState->AddScope(&newScope); + mModule->NewScopeState(); + + BfLocalVariable* localDef = new BfLocalVariable(); + localDef->mName = "_"; + localDef->mResolvedType = initValue.mType; + localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; + if (initValue.IsAddr()) + { + localDef->mAddr = initValue.mValue; + } + else + { + localDef->mValue = initValue.mValue; + localDef->mIsSplat = initValue.IsSplat(); + } + if (!localDef->mResolvedType->IsVar()) + mModule->AddLocalVariableDef(localDef, true, true); + for (auto elementExpr : initExpr->mValues) { if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) @@ -11814,36 +11841,7 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) } else { - BfBlock* block = BfNodeDynCast(elementExpr); - bool handled = false; - - BfScopeData newScope; - - if (block != NULL) - { - newScope.mInnerIsConditional = true; - newScope.mCloseNode = block; - if (block->mCloseBrace != NULL) - newScope.mCloseNode = block->mCloseBrace; - mModule->mCurMethodState->AddScope(&newScope); - mModule->NewScopeState(); - - BfLocalVariable* localDef = new BfLocalVariable(); - localDef->mName = "_"; - localDef->mResolvedType = initValue.mType; - localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; - if (initValue.IsAddr()) - { - localDef->mAddr = initValue.mValue; - } - else - { - localDef->mValue = initValue.mValue; - localDef->mIsSplat = initValue.IsSplat(); - } - if (!localDef->mResolvedType->IsVar()) - mModule->AddLocalVariableDef(localDef, true, true); - } + BfBlock* block = BfNodeDynCast(elementExpr); auto autoComplete = GetAutoComplete(); if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(elementExpr))) @@ -11875,12 +11873,6 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments()); } - if (block != NULL) - { - mModule->RestoreScopeState(); - handled = true; - } - wasValidInitKind = true; } @@ -11889,6 +11881,7 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) mModule->Fail("Invalid initializer member declarator", initExpr); } } + mModule->RestoreScopeState(); if (initExpr->mValues.IsEmpty()) { diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 3628e3a7..12f2cfda 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -2884,6 +2884,9 @@ void BfModule::GetAccessAllowed(BfTypeInstance* checkType, bool &allowProtected, bool BfModule::CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* memberOwner, BfProject* memberProject, BfProtection memberProtection, BfTypeInstance* lookupStartType) { + if ((memberOwner != NULL) && (mCurMethodState != NULL) && (mCurMethodState->mPrivateTypeInstance == memberOwner)) + return true; + if (memberProtection == BfProtection_Hidden) return false; if (memberProtection == BfProtection_Public) @@ -22233,6 +22236,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mCurMethodState->mHeadScope.mAstBlock = bodyBlock; mCurMethodState->mHeadScope.mCloseNode = bodyBlock->mCloseBrace; VisitCodeBlock(bodyBlock); + BF_ASSERT(mCurMethodState->mCurScope == &mCurMethodState->mHeadScope); } else if (auto expressionBody = BfNodeDynCast(methodDef->mBody)) { diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 17c5e110..e51ae059 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1059,6 +1059,7 @@ public: BfConstResolveState* mConstResolveState; BfMethodInstance* mMethodInstance; BfHotDataReferenceBuilder* mHotDataReferenceBuilder; + BfTypeInstance* mPrivateTypeInstance; BfIRFunction mIRFunction; BfIRBlock mIRHeadBlock; BfIRBlock mIRInitBlock; @@ -1133,6 +1134,7 @@ public: mPrevMethodState = NULL; mConstResolveState = NULL; mHotDataReferenceBuilder = NULL; + mPrivateTypeInstance = NULL; mHeadScope.mIsScopeHead = true; mCurScope = &mHeadScope; mTailScope = &mHeadScope;