diff --git a/IDEHelper/Compiler/BfAutoComplete.cpp b/IDEHelper/Compiler/BfAutoComplete.cpp index 313e4bf7..9cf8f3da 100644 --- a/IDEHelper/Compiler/BfAutoComplete.cpp +++ b/IDEHelper/Compiler/BfAutoComplete.cpp @@ -1245,6 +1245,9 @@ void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttrib if ((AddEntry(AutoCompleteEntry("valuetype", systemTypeDef->mName->mString.mPtr), filter)) && (mIsGetDefinition)) showTypeDef = systemTypeDef; } + AddEntry(AutoCompleteEntry("valuetype", "SelfBase"), filter); + AddEntry(AutoCompleteEntry("valuetype", "SelfOuter"), filter); + if (showTypeDef != NULL) { auto showType = mModule->ResolveTypeDef(showTypeDef); diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 882b1efb..449398c9 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1734,6 +1734,7 @@ public: void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind); void DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers); void DoCEEmit(BfMethodInstance* methodInstance); + void DoPopulateType_TypeAlias(BfTypeInstance* typeAlias); void DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance); void DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data); static BfModule* GetModuleFor(BfType* type); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 499ccc6f..57aa3171 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -1104,81 +1104,11 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType return; } - if (resolvedTypeRef->IsTypeAlias()) + if (resolvedTypeRef->IsTypeAlias()) { - auto typeAlias = (BfTypeInstance*)resolvedTypeRef; - SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); - SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); - SetAndRestoreValue prevMethodState(mCurMethodState, NULL); - BF_ASSERT(mCurMethodInstance == NULL); - auto typeDef = typeAlias->mTypeDef; - auto typeAliasDecl = (BfTypeAliasDeclaration*)typeDef->mTypeDeclaration; - BfType* aliasToType = NULL; - - resolvedTypeRef->mDefineState = BfTypeDefineState_ResolvingBaseType; - BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState); - typeState.mPopulateType = populateType; - typeState.mCurBaseTypeRef = typeAliasDecl->mAliasToType; - SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); - if (!CheckCircularDataError()) - { - if (typeAliasDecl->mAliasToType != NULL) - aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias); - } - - if (aliasToType != NULL) - { - if (aliasToType->IsConstExprValue()) - { - Fail(StrFormat("Illegal alias to type '%s'", TypeToString(aliasToType).c_str()), typeAlias->mTypeDef->GetRefNode()); - aliasToType = NULL; - } - } - - if (aliasToType != NULL) - { - AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom); - } - else - mContext->mFailTypes.Add(typeAlias); - - if (typeAlias->mTypeFailed) - aliasToType = NULL; - - ((BfTypeAliasType*)resolvedTypeRef)->mAliasToType = aliasToType; - - if (aliasToType != NULL) - { - resolvedTypeRef->mSize = aliasToType->mSize; - resolvedTypeRef->mAlign = aliasToType->mAlign; - - if (auto aliasToTypeInst = aliasToType->ToTypeInstance()) - { - typeAlias->mInstSize = aliasToTypeInst->mInstSize; - typeAlias->mInstAlign = aliasToTypeInst->mInstAlign; - } - else - { - typeAlias->mInstSize = aliasToType->mSize; - typeAlias->mInstAlign = aliasToType->mAlign; - } - } - else - { - resolvedTypeRef->mSize = 0; - resolvedTypeRef->mAlign = 1; - typeAlias->mInstSize = 0; - typeAlias->mInstAlign = 1; - } - resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted; - resolvedTypeRef->mRebuildFlags = BfTypeRebuildFlag_None; - if ((typeInstance->mCustomAttributes == NULL) && (typeDef->mTypeDeclaration != NULL) && (typeDef->mTypeDeclaration->mAttributes != NULL)) - typeInstance->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, BfAttributeTargets_Alias); - - if (typeAlias->mGenericTypeInfo != NULL) - DoPopulateType_SetGenericDependencies(typeAlias); - // Fall through so generic params are populated in DoPopulateType - } + // Always populate these all the way + populateType = BfPopulateType_Data; + } if (resolvedTypeRef->IsSizedArray()) { @@ -2427,6 +2357,80 @@ void BfModule::DoPopulateType_SetGenericDependencies(BfTypeInstance* genericType } } +void BfModule::DoPopulateType_TypeAlias(BfTypeInstance* typeAlias) +{ + SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeAlias); + SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); + SetAndRestoreValue prevMethodState(mCurMethodState, NULL); + BF_ASSERT(mCurMethodInstance == NULL); + auto typeDef = typeAlias->mTypeDef; + auto typeAliasDecl = (BfTypeAliasDeclaration*)typeDef->mTypeDeclaration; + BfType* aliasToType = NULL; + + typeAlias->mDefineState = BfTypeDefineState_ResolvingBaseType; + BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState); + typeState.mPopulateType = BfPopulateType_Data; + typeState.mCurBaseTypeRef = typeAliasDecl->mAliasToType; + SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); + if (!CheckCircularDataError()) + { + if (typeAliasDecl->mAliasToType != NULL) + aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias); + } + + if (aliasToType != NULL) + { + if (aliasToType->IsConstExprValue()) + { + Fail(StrFormat("Illegal alias to type '%s'", TypeToString(aliasToType).c_str()), typeAlias->mTypeDef->GetRefNode()); + aliasToType = NULL; + } + } + + if (aliasToType != NULL) + { + AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom); + } + else + mContext->mFailTypes.Add(typeAlias); + + if (typeAlias->mTypeFailed) + aliasToType = NULL; + + ((BfTypeAliasType*)typeAlias)->mAliasToType = aliasToType; + + if (aliasToType != NULL) + { + typeAlias->mSize = aliasToType->mSize; + typeAlias->mAlign = aliasToType->mAlign; + + if (auto aliasToTypeInst = aliasToType->ToTypeInstance()) + { + typeAlias->mInstSize = aliasToTypeInst->mInstSize; + typeAlias->mInstAlign = aliasToTypeInst->mInstAlign; + } + else + { + typeAlias->mInstSize = aliasToType->mSize; + typeAlias->mInstAlign = aliasToType->mAlign; + } + } + else + { + typeAlias->mSize = 0; + typeAlias->mAlign = 1; + typeAlias->mInstSize = 0; + typeAlias->mInstAlign = 1; + } + typeAlias->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted; + typeAlias->mRebuildFlags = BfTypeRebuildFlag_None; + if ((typeAlias->mCustomAttributes == NULL) && (typeDef->mTypeDeclaration != NULL) && (typeDef->mTypeDeclaration->mAttributes != NULL)) + typeAlias->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, BfAttributeTargets_Alias); + + if (typeAlias->mGenericTypeInfo != NULL) + DoPopulateType_SetGenericDependencies(typeAlias); +} + void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType) { auto typeInstance = resolvedTypeRef->ToTypeInstance(); @@ -2515,6 +2519,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (resolvedTypeRef->IsTypeAlias()) { + prevTypeState.Restore(); + DoPopulateType_TypeAlias(typeInstance); + typeInstance->mTypeIncomplete = false; resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted; return; @@ -8849,6 +8856,21 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } return ResolveTypeResult(typeRef, baseType, populateType, resolveFlags); } + else if (findName == "SelfOuter") + { + BfType* selfType = mCurTypeInstance; + if (selfType->IsBoxed()) + selfType = selfType->GetUnderlyingType(); + if ((resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam) != 0) + { + if ((selfType->IsSpecializedType()) || (selfType->IsUnspecializedTypeVariation())) + selfType = ResolveTypeDef(selfType->ToTypeInstance()->mTypeDef, populateType); + } + selfType = GetOuterType(mCurTypeInstance); + if (selfType == NULL) + Fail("'SelfOuter' type is not usable here", typeRef); + return ResolveTypeResult(typeRef, selfType, populateType, resolveFlags); + } else if (findName == "ExpectedType") { Fail("'ExpectedType' is not usable here", typeRef);