Explorar o código

Allow private member access in initializer block when subclassing

Brian Fiete hai 8 meses
pai
achega
971cecdd99

+ 29 - 36
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -11734,6 +11734,33 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
 		initValue = mModule->RemoveRef(initValue, false);
 	bool isFirstAdd = true;
 
+	SetAndRestoreValue<BfTypeInstance*> 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<BfBlock>(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<BfBlock>(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())
 	{	

+ 4 - 0
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<BfExpression>(methodDef->mBody))
 			{

+ 2 - 0
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;