From 9697c2a682254ad9146bbb127b20724bb7261856 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 1 Nov 2021 14:44:05 -0700 Subject: [PATCH] Fixed data cycle detection for sized arrays --- IDEHelper/Compiler/BfAutoComplete.cpp | 8 ++-- IDEHelper/Compiler/BfCompiler.cpp | 2 +- IDEHelper/Compiler/BfContext.h | 9 ++-- IDEHelper/Compiler/BfExprEvaluator.cpp | 12 ++--- IDEHelper/Compiler/BfModule.cpp | 14 +++--- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 57 ++++++++++++++---------- 6 files changed, 56 insertions(+), 46 deletions(-) diff --git a/IDEHelper/Compiler/BfAutoComplete.cpp b/IDEHelper/Compiler/BfAutoComplete.cpp index 8a5d6c89..ed8b4210 100644 --- a/IDEHelper/Compiler/BfAutoComplete.cpp +++ b/IDEHelper/Compiler/BfAutoComplete.cpp @@ -1424,9 +1424,9 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress } } - if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mTypeInstance != NULL)) + if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mType != NULL)) { - BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mTypeInstance); + BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mType); BfGlobalLookup globalLookup; globalLookup.mKind = BfGlobalLookup::Kind_All; @@ -1790,9 +1790,9 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken checkTypeInst = mModule->GetOuterType(checkTypeInst); } - if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mTypeInstance != NULL)) + if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mType != NULL)) { - BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mTypeInstance); + BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mType); BfGlobalLookup globalLookup; globalLookup.mKind = BfGlobalLookup::Kind_All; diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index fd9acff9..0b798939 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -4268,7 +4268,7 @@ void BfCompiler::ProcessAutocompleteTempType() #endif SetAndRestoreValue prevType(module->mCurTypeInstance, typeInst); - typeState.mTypeInstance = typeInst; + typeState.mType = typeInst; BfGenericExtensionEntry* genericExEntry = NULL; bool hadTempExtensionInfo = false; diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index 4a7622ec..a85a308d 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -138,7 +138,7 @@ public: public: BfTypeState* mPrevState; - BfTypeInstance* mTypeInstance; + BfType* mType; BfTypeDef* mGlobalContainerCurUserTypeDef; Array mGlobalContainers; // All global containers that are visible @@ -157,7 +157,7 @@ public: BfTypeState() { mPrevState = NULL; - mTypeInstance = NULL; + mType = NULL; mGlobalContainerCurUserTypeDef = NULL; mPopulateType = BfPopulateType_Identity; @@ -172,14 +172,15 @@ public: mResolveKind = ResolveKind_None; } - BfTypeState(BfTypeInstance* typeInstance, BfTypeState* prevState = NULL) + BfTypeState(BfType* type, BfTypeState* prevState = NULL) { mPrevState = prevState; - mTypeInstance = typeInstance; + mType = type; mGlobalContainerCurUserTypeDef = NULL; mPopulateType = BfPopulateType_Declaration; mCurBaseTypeRef = NULL; + mCurBaseType = NULL; mCurFieldDef = NULL; mCurAttributeTypeRef = NULL; mCurTypeDef = NULL; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index e8ef78d7..899f9a26 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -2483,7 +2483,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe while (checkTypeState != NULL) { if ((checkTypeState->mResolveKind == BfTypeState::ResolveKind_ResolvingVarType) && - (checkTypeState->mTypeInstance == typeInstance)) + (checkTypeState->mType == typeInstance)) isResolvingVarField = true; checkTypeState = checkTypeState->mPrevState; } @@ -3979,7 +3979,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI { if (checkTypeState->mCurFieldDef != NULL) { - if (checkTypeState->mTypeInstance == mModule->mCurTypeInstance) + if (checkTypeState->mType == mModule->mCurTypeInstance) resolvingFieldDef = checkTypeState->mCurFieldDef; } checkTypeState = checkTypeState->mPrevState; @@ -4046,7 +4046,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI if (!thisValue.HasType()) { - if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mTypeInstance == mModule->mCurTypeInstance) && + if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mType == mModule->mCurTypeInstance) && (mModule->mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes)) { // Can't do static lookups yet @@ -4311,7 +4311,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar { // Don't allow lookups yet if ((mModule->mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes) && - (startCheckType == mModule->mContext->mCurTypeState->mTypeInstance)) + (startCheckType == mModule->mContext->mCurTypeState->mType)) return BfTypedValue(); } @@ -4479,7 +4479,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mCurFieldDef != NULL)) { // If we're initializing another const field then also set it as having const eval - auto resolvingFieldInstance = &mModule->mContext->mCurTypeState->mTypeInstance->mFieldInstances[mModule->mContext->mCurTypeState->mCurFieldDef->mIdx]; + auto resolvingFieldInstance = &mModule->mContext->mCurTypeState->mType->ToTypeInstance()->mFieldInstances[mModule->mContext->mCurTypeState->mCurFieldDef->mIdx]; if (resolvingFieldInstance->GetFieldDef()->mIsConst) resolvingFieldInstance->mHadConstEval = true; } @@ -15319,7 +15319,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if ((methodMatcher.mBestMethodDef == NULL) && (target.mType == NULL) && (mModule->mContext->mCurTypeState != NULL)) { - BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mTypeInstance); + BF_ASSERT(mModule->mCurTypeInstance == mModule->mContext->mCurTypeState->mType); BfGlobalLookup globalLookup; globalLookup.mKind = BfGlobalLookup::Kind_Method; globalLookup.mName = name; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 5e30a337..f0696de2 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -2998,7 +2998,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers String errorString = error; bool isWhileSpecializing = false; if (!AddErrorContext(errorString, refNode, isWhileSpecializing)) - return false; + return NULL; BfError* bfError = NULL; if (isWhileSpecializing) @@ -3143,7 +3143,7 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re String warningString = warning; bool isWhileSpecializing = false; if (!AddErrorContext(warningString, refNode, isWhileSpecializing)) - return false; + return NULL; bool deferWarning = isWhileSpecializing; if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL)) @@ -4093,7 +4093,7 @@ BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInsta SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState); - SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState, mContext->mCurTypeState->mTypeInstance != typeInstance); + SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState, mContext->mCurTypeState->mType != typeInstance); auto typeDef = typeInstance->mTypeDef; @@ -4140,7 +4140,7 @@ BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInsta { BfTypeState typeState; typeState.mPrevState = mContext->mCurTypeState; - typeState.mTypeInstance = typeInstance; + typeState.mType = typeInstance; typeState.mCurFieldDef = field; typeState.mResolveKind = BfTypeState::ResolveKind_ResolvingVarType; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); @@ -4291,7 +4291,7 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, ceExecuteId = mCompiler->mCEMachine->mExecuteId; BfTypeState typeState; - typeState.mTypeInstance = mCurTypeInstance; + typeState.mType = mCurTypeInstance; typeState.mCurTypeDef = fieldDef->mDeclaringType; typeState.mCurFieldDef = fieldDef; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); @@ -10360,7 +10360,7 @@ BfOperatorInfo* BfModule::GetOperatorInfo(BfTypeInstance* typeInstance, BfOperat SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); BfTypeState typeState; - typeState.mTypeInstance = typeInstance; + typeState.mType = typeInstance; typeState.mCurTypeDef = operatorDef->mDeclaringType; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); @@ -22239,7 +22239,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool else { BfTypeState typeState; - typeState.mTypeInstance = mCurTypeInstance; + typeState.mType = mCurTypeInstance; typeState.mCurTypeDef = methodDef->mDeclaringType; //typeState.mCurMethodDef = methodDef; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 6c1b16a4..1bc23869 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -60,7 +60,7 @@ BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfTypeInstance* gen BfTypeState typeState; typeState.mPrevState = mContext->mCurTypeState; - typeState.mTypeInstance = genericTypeInst; + typeState.mType = genericTypeInst; typeState.mCurTypeDef = partialTypeDef; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); @@ -123,7 +123,7 @@ bool BfModule::InitGenericParams(BfType* resolvedTypeRef) BfTypeState typeState; typeState.mPrevState = mContext->mCurTypeState; typeState.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams; - typeState.mTypeInstance = resolvedTypeRef->ToTypeInstance(); + typeState.mType = resolvedTypeRef; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); BF_ASSERT(mCurMethodInstance == NULL); @@ -162,7 +162,7 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef) BfTypeState typeState; typeState.mPrevState = mContext->mCurTypeState; typeState.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams; - typeState.mTypeInstance = resolvedTypeRef->ToTypeInstance(); + typeState.mType = resolvedTypeRef; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); Array deferredResolveTypes; @@ -925,11 +925,12 @@ bool BfModule::CheckCircularDataError() { if (checkTypeState->mPopulateType == BfPopulateType_Declaration) return hadError; - if ((checkIdx > 0) && (checkTypeState->mCurBaseTypeRef == NULL) && (checkTypeState->mCurAttributeTypeRef == NULL) && (checkTypeState->mCurFieldDef == NULL)) + if ((checkIdx > 0) && (checkTypeState->mCurBaseTypeRef == NULL) && (checkTypeState->mCurAttributeTypeRef == NULL) && (checkTypeState->mCurFieldDef == NULL) && + ((checkTypeState->mType == NULL) || (checkTypeState->mType->IsTypeInstance()))) return hadError; } - if ((checkTypeState->mTypeInstance == mCurTypeInstance) && (checkIdx > 0)) + if ((checkTypeState->mType == mCurTypeInstance) && (checkIdx > 0)) break; checkTypeState = checkTypeState->mPrevState; checkIdx++; @@ -949,7 +950,8 @@ bool BfModule::CheckCircularDataError() continue; } - if ((checkTypeState->mCurAttributeTypeRef == NULL) && (checkTypeState->mCurBaseTypeRef == NULL) && (checkTypeState->mCurFieldDef == NULL) ) + if ((checkTypeState->mCurAttributeTypeRef == NULL) && (checkTypeState->mCurBaseTypeRef == NULL) && (checkTypeState->mCurFieldDef == NULL) && + ((checkTypeState->mType == NULL) || (checkTypeState->mType->IsTypeInstance()))) return hadError; // We only get one chance to fire off these errors, they can't be ignored. @@ -964,21 +966,27 @@ bool BfModule::CheckCircularDataError() { Fail(StrFormat("Base type '%s' causes a data cycle", BfTypeUtils::TypeToString(checkTypeState->mCurBaseTypeRef).c_str()), checkTypeState->mCurBaseTypeRef, true); } - else if (checkTypeState->mCurFieldDef->mFieldDeclaration != NULL) + else if ((checkTypeState->mCurFieldDef != NULL) && (checkTypeState->mCurFieldDef->mFieldDeclaration != NULL)) { - Fail(StrFormat("Field '%s.%s' causes a data cycle", TypeToString(checkTypeState->mTypeInstance).c_str(), checkTypeState->mCurFieldDef->mName.c_str()), + Fail(StrFormat("Field '%s.%s' causes a data cycle", TypeToString(checkTypeState->mType).c_str(), checkTypeState->mCurFieldDef->mName.c_str()), checkTypeState->mCurFieldDef->mFieldDeclaration->mTypeRef, true); } + else if (checkTypeState->mCurFieldDef != NULL) + { + Fail(StrFormat("Field '%s.%s' causes a data cycle", TypeToString(checkTypeState->mType).c_str(), checkTypeState->mCurFieldDef->mName.c_str())); + } else { - Fail(StrFormat("Field '%s.%s' causes a data cycle", TypeToString(checkTypeState->mTypeInstance).c_str(), checkTypeState->mCurFieldDef->mName.c_str())); + Fail(StrFormat("Type '%s' causes a data cycle", TypeToString(checkTypeState->mType).c_str())); } - auto module = GetModuleFor(checkTypeState->mTypeInstance); + auto typeInstance = checkTypeState->mType->ToTypeInstance(); + + auto module = GetModuleFor(checkTypeState->mType); if (module != NULL) - module->TypeFailed(checkTypeState->mTypeInstance); - else - checkTypeState->mTypeInstance->mTypeFailed = true; + module->TypeFailed(typeInstance); + else if (typeInstance != NULL) + typeInstance->mTypeFailed = true; checkTypeState = checkTypeState->mPrevState; } @@ -1189,9 +1197,10 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType if (elementType->IsValueType()) { resolvedTypeRef->mDefineState = BfTypeDefineState_ResolvingBaseType; - BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState); - typeState.mPopulateType = populateType; + BfTypeState typeState(arrayType, mContext->mCurTypeState); + typeState.mPopulateType = BfPopulateType_Data; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); + SetAndRestoreValue prevTypeInstance(mCurTypeInstance, NULL); if (!CheckCircularDataError()) { @@ -3509,7 +3518,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy BfTypeState typeState; typeState.mPrevState = mContext->mCurTypeState; typeState.mResolveKind = BfTypeState::ResolveKind_Attributes; - typeState.mTypeInstance = typeInstance; + typeState.mType = typeInstance; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); // This allows us to avoid reentrancy when checking for inner types @@ -3969,7 +3978,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeState.mPrevState = mContext->mCurTypeState; typeState.mCurTypeDef = propDef->mDeclaringType; typeState.mCurFieldDef = propDef; - typeState.mTypeInstance = typeInstance; + typeState.mType = typeInstance; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); BfAttributeTargets target = BfAttributeTargets_Property; @@ -4078,7 +4087,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeState.mPrevState = mContext->mCurTypeState; typeState.mCurFieldDef = fieldDef; typeState.mCurTypeDef = fieldDef->mDeclaringType; - typeState.mTypeInstance = typeInstance; + typeState.mType = typeInstance; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->mFieldDeclaration->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field); @@ -4584,7 +4593,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy BfTypeState typeState; typeState.mPrevState = mContext->mCurTypeState; typeState.mCurTypeDef = propDef->mDeclaringType; - typeState.mTypeInstance = typeInstance; + typeState.mType = typeInstance; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); ResolveTypeRef(propDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowRef); } @@ -6937,7 +6946,7 @@ BfTypeInstance* BfModule::GetBaseType(BfTypeInstance* typeInst) auto checkTypeState = mContext->mCurTypeState; while (checkTypeState != NULL) { - if (checkTypeState->mTypeInstance == typeInst) + if (checkTypeState->mType == typeInst) return NULL; checkTypeState = checkTypeState->mPrevState; } @@ -8125,7 +8134,7 @@ bool BfModule::ResolveTypeResult_Validate(BfTypeReference* typeRef, BfType* reso if (curGenericTypeInstance->mGenericTypeInfo->mHadValidateErrors) doValidate = false; } - if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mCurBaseTypeRef != NULL) && (!mContext->mCurTypeState->mTypeInstance->IsTypeAlias())) // We validate constraints for base types later + if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mCurBaseTypeRef != NULL) && (!mContext->mCurTypeState->mType->IsTypeAlias())) // We validate constraints for base types later doValidate = false; } @@ -8564,9 +8573,9 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene if (mContext->mCurTypeState != NULL) { if (mContext->mCurTypeState->mCurBaseTypeRef != NULL) - skipCheckBaseType = mContext->mCurTypeState->mTypeInstance; + skipCheckBaseType = mContext->mCurTypeState->mType->ToTypeInstance(); if (mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_BuildingGenericParams) - skipCheckBaseType = mContext->mCurTypeState->mTypeInstance; + skipCheckBaseType = mContext->mCurTypeState->mType->ToTypeInstance(); } BfTypeDefLookupContext lookupCtx; @@ -13119,7 +13128,7 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType auto typeState = mContext->mCurTypeState; while (typeState != NULL) { - if ((typeState->mTypeInstance == srcType) && (typeState->mCurBaseType != NULL)) + if ((typeState->mType == srcType) && (typeState->mCurBaseType != NULL)) { return TypeIsSubTypeOf(typeState->mCurBaseType, wantType, checkAccessibility); }