mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Fixed errors for circular data references in member attributes
This commit is contained in:
parent
07a0972366
commit
3486251254
5 changed files with 124 additions and 61 deletions
|
@ -2066,6 +2066,7 @@ BfExprEvaluator::BfExprEvaluator(BfModule* module)
|
|||
mIsHeapReference = false;
|
||||
mResultIsTempComposite = false;
|
||||
mAllowReadOnlyReference = false;
|
||||
mInsidePendingNullable = false;
|
||||
mReceivingValue = NULL;
|
||||
}
|
||||
|
||||
|
@ -2167,6 +2168,7 @@ void BfExprEvaluator::Evaluate(BfAstNode* astNode, bool propogateNullConditional
|
|||
if (!propogateNullConditional)
|
||||
mModule->mCurMethodState->mPendingNullConditional = NULL;
|
||||
}
|
||||
mInsidePendingNullable = pendingNullCond != NULL;
|
||||
|
||||
astNode->Accept(this);
|
||||
GetResult();
|
||||
|
@ -5634,6 +5636,11 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType
|
|||
bool isLet = variableDeclaration->mTypeRef->IsExact<BfLetTypeReference>();
|
||||
bool isVar = variableDeclaration->mTypeRef->IsExact<BfVarTypeReference>();
|
||||
|
||||
if (mModule->mCurMethodState->mPendingNullConditional != NULL)
|
||||
{
|
||||
mModule->Fail("Variables cannot be declared in method arguments inside null conditional expressions", variableDeclaration);
|
||||
}
|
||||
|
||||
if ((!isLet) && (!isVar))
|
||||
{
|
||||
mModule->Fail("Only 'ref' or 'var' variables can be declared in method arguments", variableDeclaration);
|
||||
|
@ -12238,6 +12245,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
argExprEvaluators.push_back(new BfExprEvaluator(mModule));
|
||||
BfExprEvaluator* exprEvaluator = argExprEvaluators.back();
|
||||
exprEvaluator->mResolveGenericParam = false;
|
||||
exprEvaluator->mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator->mBfEvalExprFlags | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr);
|
||||
if (argExpr != NULL)
|
||||
exprEvaluator->Evaluate(argExpr, false, false, true);
|
||||
auto argValue = exprEvaluator->mResult;
|
||||
|
@ -12634,6 +12642,37 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
{
|
||||
// Already handled
|
||||
}
|
||||
else if (newLocalVar->mIsSplat)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
auto checkMethodState = mModule->mCurMethodState;
|
||||
while ((checkMethodState != NULL) && (!found))
|
||||
{
|
||||
for (auto localVar : checkMethodState->mLocals)
|
||||
{
|
||||
if (localVar == newLocalVar)
|
||||
continue;
|
||||
if (newLocalVar->mValue != localVar->mValue)
|
||||
continue;
|
||||
|
||||
String name = newLocalVar->mName;
|
||||
name += "$alias$";
|
||||
name += localVar->mName;
|
||||
|
||||
auto fakeValue = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 0);
|
||||
auto diType = mModule->mBfIRBuilder->DbgGetType(mModule->GetPrimitiveType(BfTypeCode_Int32));
|
||||
auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope,
|
||||
newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType);
|
||||
mModule->mBfIRBuilder->DbgInsertValueIntrinsic(fakeValue, diVariable);
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
checkMethodState = checkMethodState->mPrevMethodState;
|
||||
}
|
||||
}
|
||||
else if (mModule->IsTargetingBeefBackend())
|
||||
{
|
||||
mModule->UpdateSrcPos(methodDeclaration->mNameNode);
|
||||
|
@ -16635,7 +16674,13 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
|
|||
return;
|
||||
}
|
||||
|
||||
if (mInsidePendingNullable)
|
||||
{
|
||||
// 'out' inside null conditionals never actually causes a definite assignment...
|
||||
}
|
||||
else
|
||||
MarkResultAssigned();
|
||||
|
||||
MarkResultUsed();
|
||||
ResolveGenericType();
|
||||
mResult = BfTypedValue(mResult.mValue, mModule->CreateRefType(mResult.mType, BfRefType::RefKind_Out));
|
||||
|
|
|
@ -308,6 +308,7 @@ public:
|
|||
bool mIsHeapReference;
|
||||
bool mResultIsTempComposite;
|
||||
bool mAllowReadOnlyReference;
|
||||
bool mInsidePendingNullable;
|
||||
|
||||
public:
|
||||
BfExprEvaluator(BfModule* module);
|
||||
|
|
|
@ -14327,7 +14327,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
|||
}
|
||||
else
|
||||
{
|
||||
AssertErrorState();
|
||||
// Failed
|
||||
}
|
||||
auto assignValue = GetFieldInitializerValue(fieldInst);
|
||||
if ((fieldAddr) && (assignValue))
|
||||
|
|
|
@ -57,6 +57,7 @@ BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfGenericTypeInstan
|
|||
}
|
||||
|
||||
BfTypeState typeState;
|
||||
typeState.mPrevState = mContext->mCurTypeState;
|
||||
typeState.mTypeInstance = genericTypeInst;
|
||||
typeState.mCurTypeDef = partialTypeDef;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
@ -101,6 +102,7 @@ BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfGenericTypeInstan
|
|||
bool BfModule::BuildGenericParams(BfType* resolvedTypeRef)
|
||||
{
|
||||
BfTypeState typeState;
|
||||
typeState.mPrevState = mContext->mCurTypeState;
|
||||
typeState.mBuildingGenericParams = true;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
|
@ -1500,6 +1502,12 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
// into an errored state
|
||||
SetAndRestoreValue<bool> prevReportErrors(mReportErrors, reportErrors);
|
||||
|
||||
if (typeInstance->mIsFinishingType)
|
||||
{
|
||||
// This type already failed
|
||||
return true;
|
||||
}
|
||||
|
||||
CheckCircularDataError();
|
||||
|
||||
bool underlyingTypeDeferred = false;
|
||||
|
@ -2095,7 +2103,9 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
if (partialTypeDef->mTypeDeclaration->mAttributes == NULL)
|
||||
continue;
|
||||
BfTypeState typeState;
|
||||
typeState.mPrevState = mContext->mCurTypeState;
|
||||
typeState.mCurTypeDef = partialTypeDef;
|
||||
typeState.mTypeInstance = typeInstance;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
if (typeInstance->mCustomAttributes == NULL)
|
||||
|
@ -2187,60 +2197,6 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
int mTypeArrayIdx;
|
||||
};
|
||||
|
||||
for (auto propDef : typeDef->mProperties)
|
||||
{
|
||||
if (!typeInstance->IsTypeMemberIncluded(propDef->mDeclaringType))
|
||||
continue;
|
||||
|
||||
if (propDef->mFieldDeclaration != NULL)
|
||||
{
|
||||
BfTypeState typeState;
|
||||
typeState.mCurTypeDef = propDef->mDeclaringType;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
if (propDef->mFieldDeclaration->mAttributes != NULL)
|
||||
{
|
||||
auto customAttrs = GetCustomAttributes(propDef->mFieldDeclaration->mAttributes, BfAttributeTargets_Property);
|
||||
delete customAttrs;
|
||||
}
|
||||
|
||||
if (propDef->mFieldDeclaration->mAttributes != NULL)
|
||||
{
|
||||
auto customAttrs = GetCustomAttributes(propDef->mFieldDeclaration->mAttributes, BfAttributeTargets_Property);
|
||||
delete customAttrs;
|
||||
}
|
||||
|
||||
auto propDecl = (BfPropertyDeclaration*)propDef->mFieldDeclaration;
|
||||
if (propDecl->mExplicitInterface != NULL)
|
||||
{
|
||||
if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
|
||||
mCompiler->mResolvePassData->mAutoComplete->CheckTypeRef(propDecl->mExplicitInterface, false);
|
||||
auto explicitInterface = ResolveTypeRef(propDecl->mExplicitInterface, BfPopulateType_Declaration);
|
||||
if (explicitInterface != NULL)
|
||||
{
|
||||
bool interfaceFound = false;
|
||||
for (auto ifaceInst : typeInstance->mInterfaces)
|
||||
interfaceFound |= ifaceInst.mInterfaceType == explicitInterface;
|
||||
if (!interfaceFound)
|
||||
{
|
||||
Fail("Containing class has not declared to implement this interface", propDecl->mExplicitInterface, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (propDef->mMethods.IsEmpty())
|
||||
{
|
||||
auto nameNode = ((BfPropertyDeclaration*)propDef->mFieldDeclaration)->mNameNode;
|
||||
|
||||
if (nameNode != NULL)
|
||||
{
|
||||
Fail(StrFormat("Property or indexer '%s.%s' must have at least one accessor", TypeToString(typeInstance).c_str(), propDef->mName.c_str()),
|
||||
nameNode, true); // CS0548
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BfSizedVector<DeferredResolveEntry, 8> deferredVarResolves;
|
||||
|
||||
for (auto field : typeDef->mFields)
|
||||
|
@ -2417,7 +2373,7 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
|
||||
BF_ASSERT(mContext->mCurTypeState == &typeState);
|
||||
|
||||
BF_ASSERT(!typeInstance->mIsFinishingType);
|
||||
//BF_ASSERT(!typeInstance->mIsFinishingType);
|
||||
typeInstance->mIsFinishingType = true;
|
||||
|
||||
// No re-entry is allowed below here -- we will run all the way to the end at this point
|
||||
|
@ -2427,6 +2383,63 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
|
||||
if (!resolvedTypeRef->IsBoxed())
|
||||
{
|
||||
for (auto propDef : typeDef->mProperties)
|
||||
{
|
||||
if (!typeInstance->IsTypeMemberIncluded(propDef->mDeclaringType))
|
||||
continue;
|
||||
|
||||
if (propDef->mFieldDeclaration != NULL)
|
||||
{
|
||||
BfTypeState typeState;
|
||||
typeState.mPrevState = mContext->mCurTypeState;
|
||||
typeState.mCurTypeDef = propDef->mDeclaringType;
|
||||
typeState.mCurFieldDef = propDef;
|
||||
typeState.mTypeInstance = typeInstance;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
if (propDef->mFieldDeclaration->mAttributes != NULL)
|
||||
{
|
||||
auto customAttrs = GetCustomAttributes(propDef->mFieldDeclaration->mAttributes, BfAttributeTargets_Property);
|
||||
delete customAttrs;
|
||||
}
|
||||
|
||||
if (propDef->mFieldDeclaration->mAttributes != NULL)
|
||||
{
|
||||
auto customAttrs = GetCustomAttributes(propDef->mFieldDeclaration->mAttributes, BfAttributeTargets_Property);
|
||||
delete customAttrs;
|
||||
}
|
||||
|
||||
auto propDecl = (BfPropertyDeclaration*)propDef->mFieldDeclaration;
|
||||
if (propDecl->mExplicitInterface != NULL)
|
||||
{
|
||||
if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
|
||||
mCompiler->mResolvePassData->mAutoComplete->CheckTypeRef(propDecl->mExplicitInterface, false);
|
||||
auto explicitInterface = ResolveTypeRef(propDecl->mExplicitInterface, BfPopulateType_Declaration);
|
||||
if (explicitInterface != NULL)
|
||||
{
|
||||
bool interfaceFound = false;
|
||||
for (auto ifaceInst : typeInstance->mInterfaces)
|
||||
interfaceFound |= ifaceInst.mInterfaceType == explicitInterface;
|
||||
if (!interfaceFound)
|
||||
{
|
||||
Fail("Containing class has not declared to implement this interface", propDecl->mExplicitInterface, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (propDef->mMethods.IsEmpty())
|
||||
{
|
||||
auto nameNode = ((BfPropertyDeclaration*)propDef->mFieldDeclaration)->mNameNode;
|
||||
|
||||
if (nameNode != NULL)
|
||||
{
|
||||
Fail(StrFormat("Property or indexer '%s.%s' must have at least one accessor", TypeToString(typeInstance).c_str(), propDef->mName.c_str()),
|
||||
nameNode, true); // CS0548
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isGlobalContainer = typeDef->IsGlobalsContainer();
|
||||
|
||||
if (typeInstance->mBaseType != NULL)
|
||||
|
@ -2478,7 +2491,10 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
if ((fieldDef != NULL) && (fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mAttributes != NULL))
|
||||
{
|
||||
BfTypeState typeState;
|
||||
typeState.mPrevState = mContext->mCurTypeState;
|
||||
typeState.mCurFieldDef = fieldDef;
|
||||
typeState.mCurTypeDef = fieldDef->mDeclaringType;
|
||||
typeState.mTypeInstance = typeInstance;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->mFieldDeclaration->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
|
||||
|
@ -2959,6 +2975,7 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
continue;
|
||||
|
||||
BfTypeState typeState;
|
||||
typeState.mPrevState = mContext->mCurTypeState;
|
||||
typeState.mCurTypeDef = propDef->mDeclaringType;
|
||||
typeState.mTypeInstance = typeInstance;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue