From 5a5287bc8b058078130f1423744a7b1461865a4c Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 23 May 2020 17:25:47 -0700 Subject: [PATCH] Fixed generic alias and generic delegate issues --- IDEHelper/Compiler/BfCompiler.cpp | 3 +- IDEHelper/Compiler/BfContext.cpp | 8 +- IDEHelper/Compiler/BfContext.h | 1 + IDEHelper/Compiler/BfExprEvaluator.cpp | 16 +- IDEHelper/Compiler/BfModule.cpp | 33 +- IDEHelper/Compiler/BfModule.h | 7 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 709 ++++++++++++--------- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 253 ++++---- IDEHelper/Compiler/BfResolvedTypeUtils.h | 68 +- IDEHelper/Tests/src/Aliases.bf | 38 ++ 10 files changed, 702 insertions(+), 434 deletions(-) create mode 100644 IDEHelper/Tests/src/Aliases.bf diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 7a6c136c..a659af74 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -4881,7 +4881,8 @@ void BfCompiler::PopulateReified() auto typeInst = type->ToTypeInstance(); - if ((typeInst != NULL) && (typeInst->IsGenericTypeInstance()) && (!typeInst->IsUnspecializedType())) + if ((typeInst != NULL) && (typeInst->IsGenericTypeInstance()) && (!typeInst->IsUnspecializedType()) && + (!typeInst->IsDelegateFromTypeRef()) && (!typeInst->IsFunctionFromTypeRef())) { auto unspecializedType = module->GetUnspecializedTypeInstance(typeInst); if (!unspecializedType->mIsReified) diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 224b42cc..6ffbbef9 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -758,8 +758,9 @@ BfType * BfContext::FindTypeById(int typeId) void BfContext::AddTypeToWorkList(BfType* type) { + BF_ASSERT((type->mRebuildFlags & BfTypeRebuildFlag_InTempPool) == 0); if ((type->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 0) - { + { type->mRebuildFlags = (BfTypeRebuildFlags)(type->mRebuildFlags | BfTypeRebuildFlag_AddedToWorkList); BfTypeProcessRequest* typeProcessRequest = mPopulateTypeWorkList.Alloc(); @@ -2221,9 +2222,10 @@ void BfContext::GenerateModuleName_Type(BfType* type, String& name) if (type->IsDelegateFromTypeRef() || type->IsFunctionFromTypeRef()) { - auto delegateType = (BfDelegateType*)type; + auto typeInst = type->ToTypeInstance(); + auto delegateInfo = type->GetDelegateInfo(); - auto methodDef = delegateType->mTypeDef->mMethods[0]; + auto methodDef = typeInst->mTypeDef->mMethods[0]; if (type->IsDelegateFromTypeRef()) name += "DELEGATE_"; diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index da37626a..08efa290 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -382,6 +382,7 @@ public: BfAllocPool mConcreteInterfaceTypePool; BfAllocPool mConstExprValueTypePool; BfAllocPool mDelegateTypePool; + BfAllocPool mGenericDelegateTypePool; BfPrimitiveType* mPrimitiveTypes[BfTypeCode_Length]; BfPrimitiveType* mPrimitiveStructTypes[BfTypeCode_Length]; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 47a7e43e..7d6edaf9 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -562,9 +562,9 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp BfType* origPrevParamType = prevParamType; if ((genericArgumentsSubstitute != NULL) && (paramType->IsUnspecializedType())) - paramType = mModule->ResolveGenericType(paramType, *genericArgumentsSubstitute, allowSpecializeFail); + paramType = mModule->ResolveGenericType(paramType, NULL, genericArgumentsSubstitute, allowSpecializeFail); if ((prevGenericArgumentsSubstitute != NULL) && (prevParamType->IsUnspecializedType())) - prevParamType = mModule->ResolveGenericType(prevParamType, *prevGenericArgumentsSubstitute, allowSpecializeFail); + prevParamType = mModule->ResolveGenericType(prevParamType, NULL, prevGenericArgumentsSubstitute, allowSpecializeFail); if ((wasGenericParam) || (prevWasGenericParam)) { @@ -957,7 +957,7 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B } if ((genericArgumentsSubstitute != NULL) && (expectType->IsUnspecializedType())) - expectType = mModule->ResolveGenericType(expectType, *genericArgumentsSubstitute, true); + expectType = mModule->ResolveGenericType(expectType, NULL, genericArgumentsSubstitute, true); } exprEvaluator.mExpectingType = expectType; @@ -1067,13 +1067,13 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfGenericParamInstance* generi { auto leftType = checkOpConstraint.mLeftType; if ((leftType != NULL) && (leftType->IsUnspecializedType())) - leftType = mModule->ResolveGenericType(leftType, *methodGenericArgs); + leftType = mModule->ResolveGenericType(leftType, NULL, methodGenericArgs); if (leftType != NULL) leftType = mModule->FixIntUnknown(leftType); auto rightType = checkOpConstraint.mRightType; if ((rightType != NULL) && (rightType->IsUnspecializedType())) - rightType = mModule->ResolveGenericType(rightType, *methodGenericArgs); + rightType = mModule->ResolveGenericType(rightType, NULL, methodGenericArgs); if (rightType != NULL) rightType = mModule->FixIntUnknown(rightType); @@ -1309,7 +1309,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst if ((checkType != NULL) && (genericArgumentsSubstitute != NULL) && (checkType->IsUnspecializedType())) { - checkType = mModule->ResolveGenericType(origCheckType, *genericArgumentsSubstitute); + checkType = mModule->ResolveGenericType(origCheckType, NULL, genericArgumentsSubstitute); } if (wantType->IsUnspecializedType()) @@ -1453,7 +1453,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst auto wantType = methodInstance->GetParamType(paramIdx); if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType())) { - auto resolvedType = mModule->ResolveGenericType(wantType, *genericArgumentsSubstitute); + auto resolvedType = mModule->ResolveGenericType(wantType, NULL, genericArgumentsSubstitute); if (resolvedType == NULL) goto NoMatch; wantType = resolvedType; @@ -6306,7 +6306,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp if (isUnboundCall) { - if (mModule->mCurMethodInstance->mIsUnspecialized) + if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized)) { auto varType = mModule->GetPrimitiveType(BfTypeCode_Var); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index bc419ab8..d16d90ff 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -6861,7 +6861,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS { BfType* convCheckConstraint = genericParamInst->mTypeConstraint; if ((convCheckConstraint->IsUnspecializedType()) && (methodGenericArgs != NULL)) - convCheckConstraint = ResolveGenericType(convCheckConstraint, *methodGenericArgs); + convCheckConstraint = ResolveGenericType(convCheckConstraint, NULL, methodGenericArgs); if ((checkArgType->IsMethodRef()) && (convCheckConstraint->IsDelegate())) { auto methodRefType = (BfMethodRefType*)checkArgType; @@ -6932,7 +6932,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS { BfType* convCheckConstraint = checkConstraint; if (convCheckConstraint->IsUnspecializedType()) - convCheckConstraint = ResolveGenericType(convCheckConstraint, *methodGenericArgs); + convCheckConstraint = ResolveGenericType(convCheckConstraint, NULL, methodGenericArgs); BfTypeInstance* typeConstraintInst = convCheckConstraint->ToTypeInstance(); @@ -6973,13 +6973,13 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS { auto leftType = checkOpConstraint.mLeftType; if ((leftType != NULL) && (leftType->IsUnspecializedType())) - leftType = ResolveGenericType(leftType, *methodGenericArgs); + leftType = ResolveGenericType(leftType, NULL, methodGenericArgs); if (leftType != NULL) leftType = FixIntUnknown(leftType); auto rightType = checkOpConstraint.mRightType; if ((rightType != NULL) && (rightType->IsUnspecializedType())) - rightType = ResolveGenericType(rightType, *methodGenericArgs); + rightType = ResolveGenericType(rightType, NULL, methodGenericArgs); if (rightType != NULL) rightType = FixIntUnknown(rightType); @@ -8792,16 +8792,27 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp bool isStructPtr = typedVal.mType->IsStructPtr(); if (fromStructTypeInstance == NULL) { - auto primType = (BfPrimitiveType*)typedVal.mType; - fromStructTypeInstance = GetWrappedStructType(typedVal.mType); + auto primType = (BfPrimitiveType*)typedVal.mType; + + if ((typedVal.mType->IsPointer()) && (toTypeInstance->IsInstanceOf(mCompiler->mIHashableTypeDef))) + { + // Can always do IHashable + alreadyCheckedCast = true; + } + + if ((!typedVal.mType->IsPointer()) || (toTypeInstance == mContext->mBfObjectType)) + fromStructTypeInstance = GetWrappedStructType(typedVal.mType); if (isStructPtr) { - if ((toTypeInstance != NULL) && (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance))) + if ((toTypeInstance != NULL) && (fromStructTypeInstance != NULL) && (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance))) alreadyCheckedCast = true; fromStructTypeInstance = typedVal.mType->GetUnderlyingType()->ToTypeInstance(); } + + if ((fromStructTypeInstance == NULL) && (alreadyCheckedCast)) + fromStructTypeInstance = GetWrappedStructType(typedVal.mType); } if (fromStructTypeInstance == NULL) return BfTypedValue(); @@ -8810,7 +8821,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed()); if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (alreadyCheckedCast) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance))) - { + { if (mBfIRBuilder->mIgnoreWrites) return BfTypedValue(mBfIRBuilder->GetFakeVal(), (toType != NULL) ? toType : CreateBoxedType(typedVal.mType)); @@ -9307,7 +9318,7 @@ String BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags BfType* type = methodInst->mMethodInstanceGroup->mOwner; if ((methodGenericArgs != NULL) && (type->IsUnspecializedType())) - type = ResolveGenericType(type, *methodGenericArgs); + type = ResolveGenericType(type, NULL, methodGenericArgs); String methodName; if ((methodNameFlags & BfMethodNameFlag_OmitTypeName) == 0) { @@ -9453,7 +9464,7 @@ String BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags } if (type->IsUnspecializedType()) - type = ResolveGenericType(type, *methodGenericArgs); + type = ResolveGenericType(type, NULL, methodGenericArgs); } if ((methodGenericArgs == NULL) && (mCurMethodInstance == NULL) && (mCurTypeInstance == NULL)) @@ -9486,7 +9497,7 @@ String BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags typeNameFlags = BfTypeNameFlag_ResolveGenericParamNames; BfType* type = methodInst->GetParamType(paramIdx); if ((methodGenericArgs != NULL) && (type->IsUnspecializedType())) - type = ResolveGenericType(type, *methodGenericArgs); + type = ResolveGenericType(type, NULL, methodGenericArgs); methodName += TypeToString(type, typeNameFlags); methodName += " "; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 4ae37b8e..90dee76b 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -81,7 +81,8 @@ enum BfCastFlags BfCastFlags_FromCompiler = 0x40, // Not user specified BfCastFlags_Force = 0x80, BfCastFlags_PreferAddr = 0x100, - BfCastFlags_WarnOnBox = 0x200 + BfCastFlags_WarnOnBox = 0x200, + BfCastFlags_IsCastCheck = 0x400 }; enum BfCastResultFlags @@ -1646,7 +1647,7 @@ public: BfType* FixIntUnknown(BfType* type); void FixIntUnknown(BfTypedValue& typedVal); void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs); - BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef); + BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType = NULL); BfType* ResolveType(BfType* lookupType, BfPopulateType populateType = BfPopulateType_Data); void ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized); String GenericParamSourceToString(const BfGenericParamSource& genericParamSource); @@ -1677,7 +1678,7 @@ public: void EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scope, BfIRBlock doneBlock = BfIRBlock()); void MarkScopeLeft(BfScopeData* scopeData); BfGenericParamType* GetGenericParamType(BfGenericParamKind paramKind, int paramIdx); - BfType* ResolveGenericType(BfType* unspecializedType, const BfTypeVector& methodGenericArguments, bool allowFail = false); + BfType* ResolveGenericType(BfType* unspecializedType, BfTypeVector* typeGenericArguments, BfTypeVector* methodGenericArguments, bool allowFail = false); bool IsUnboundGeneric(BfType* type); BfGenericParamInstance* GetGenericTypeParamInstance(int paramIdx); BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 2dafe86f..5c55810c 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -98,6 +98,7 @@ BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfGenericTypeInstan if (genericParam->mTypeConstraint != NULL) AddDependency(genericParam->mTypeConstraint, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint); } + return genericExEntry; } @@ -123,7 +124,7 @@ bool BfModule::BuildGenericParams(BfType* resolvedTypeRef) { auto genericParamInstance = new BfGenericTypeParamInstance(typeDef, paramIdx); genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx); - genericTypeInst->mGenericParams.push_back(genericParamInstance); + genericTypeInst->mGenericParams.push_back(genericParamInstance); } if (!typeDef->mPartials.empty()) @@ -193,7 +194,7 @@ bool BfModule::BuildGenericParams(BfType* resolvedTypeRef) if (genericParam->mTypeConstraint != NULL) AddDependency(genericParam->mTypeConstraint, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint); } - + return true; } @@ -423,6 +424,10 @@ bool BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType) if (resolvedTypeRef->IsGenericTypeInstance()) { auto genericTypeInst = (BfGenericTypeInstance*)resolvedTypeRef; + //BF_ASSERT(genericTypeInst->mGenericParams.size() <= genericTypeInst->mTypeGenericArguments.size()); +// BF_ASSERT((genericTypeInst->mGenericParams.size() == 0) || +// (genericTypeInst->mGenericParams.size() == genericTypeInst->mTypeGenericArguments.size())); + for (auto typeGenericArg : genericTypeInst->mTypeGenericArguments) BF_ASSERT((typeGenericArg->mRebuildFlags & BfTypeRebuildFlag_Deleted) == 0); } @@ -908,7 +913,10 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType if (resolvedTypeRef->IsTypeAlias()) { auto typeAlias = (BfTypeInstance*)resolvedTypeRef; - SetAndRestoreValue prevCurType(mCurTypeInstance, typeAlias); + 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; @@ -920,7 +928,7 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType if (!CheckCircularDataError()) { if (typeAliasDecl->mAliasToType != NULL) - aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias); + aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias); } if (aliasToType != NULL) @@ -1728,7 +1736,9 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy BfLogSysM("Adding generic dependency of %p for type %p\n", genericType, genericTypeInstance); } } - if (genericTypeInstance->IsSpecializedType()) + if ((genericTypeInstance->IsSpecializedType()) && + (!genericTypeInstance->IsDelegateFromTypeRef()) && + (!genericTypeInstance->IsFunctionFromTypeRef())) { // This ensures we rebuild the unspecialized type whenever the specialized type rebuilds. This is important // for generic type binding @@ -5397,12 +5407,16 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& generic genericInstType = mContext->mGenericTypeAliasPool.Get(); else genericInstType = mContext->mGenericTypeInstancePool.Get(); + BF_ASSERT(genericInstType->mGenericParams.size() == 0); + BF_ASSERT((genericInstType->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 0); + genericInstType->mRebuildFlags = (BfTypeRebuildFlags)(genericInstType->mRebuildFlags & ~BfTypeRebuildFlag_InTempPool); genericInstType->mContext = mContext; auto typeRef = mContext->mTypeDefTypeRefPool.Get(); typeRef->mTypeDef = typeDef; genericInstType->mTypeDef = typeDef; genericInstType->mIsUnspecialized = false; genericInstType->mTypeGenericArguments.clear(); + genericInstType->mTypeFailed = false; for (auto genericArg : genericArgs) { genericInstType->mIsUnspecialized |= genericArg->IsGenericParam(); @@ -5419,9 +5433,38 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& generic } } - auto resolvedType = ResolveType(genericInstType, populateType); - if (resolvedType != genericInstType) + BfType* resolvedType = NULL; + + bool failed = false; +// if (typeDef->mTypeCode == BfTypeCode_TypeAlias) +// { +// auto aliasType = (BfGenericTypeAliasType*)genericInstType; +// aliasType->mAliasToType = NULL; +// auto typeAliasDecl = (BfTypeAliasDeclaration*)typeDef->mTypeDeclaration; +// SetAndRestoreValue prevTypeInstance(mCurTypeInstance, aliasType); +// SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); +// BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState); +// typeState.mCurTypeDef = typeDef; +// SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); +// if (typeAliasDecl->mAliasToType != NULL) +// aliasType->mAliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType); +// +// resolvedType = ResolveType(genericInstType, BfPopulateType_IdentityNoRemapAlias); +// if ((resolvedType != NULL) && (populateType >= BfPopulateType_Declaration)) +// PopulateType(resolvedType, populateType); +// } +// else { + resolvedType = ResolveType(genericInstType, populateType); + } + + + if (resolvedType != genericInstType) + { + BF_ASSERT(genericInstType->mGenericParams.size() == 0); + BF_ASSERT((genericInstType->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 0); + genericInstType->mRebuildFlags = (BfTypeRebuildFlags)(genericInstType->mRebuildFlags | BfTypeRebuildFlag_InTempPool); + if (typeDef->mTypeCode == BfTypeCode_TypeAlias) mContext->mGenericTypeAliasPool.GiveBack((BfGenericTypeAliasType*)genericInstType); else @@ -5434,8 +5477,11 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& generic int checkIdx = 0; -BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef) +BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType) { + if (outType != NULL) + *outType = NULL; + BfTypeReference* typeRef = genericTypeRef->mElementType; int numGenericParams = genericTypeRef->GetGenericArgCount(); @@ -5512,49 +5558,7 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic if (wasGenericParam) Fail("Cannot use generic param as generic instance type", typeRef); } - - //if (mCurTypeInstance != NULL) - //{ - // String findName; - // if (directStrTypeDef != NULL) - // findName = directStrTypeDef->mTypeName; - // else - // findName = namedTypeRef->mNameNode->ToString(); - // auto outerTypeInstance = mCurTypeInstance; - - // for (int pass = 0; pass < 2; pass++) - // { - // bool isFailurePass = pass == 1; - // bool allowPrivate = true; - // bool allowProtected = true; - - // auto checkOuterType = outerTypeInstance; - // while (checkOuterType != NULL) - // { - // for (auto checkType : checkOuterType->mTypeDef->mNestedTypes) - // { - // if ((!isFailurePass) && (!CheckProtection(checkType->mProtection, allowProtected, allowPrivate))) - // continue; - - // if (checkType->mName->mString == findName) - // { - // if (isFailurePass) - // { - // // This is the one error we don't ignore when ignoreErrors is set - // Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", TypeToString(checkOuterType).c_str(), BfTypeUtils::TypeToString(namedTypeRef).c_str()), namedTypeRef); // CS0122 - // } - - // return checkType; - // } - // } - // allowPrivate = false; - // if (checkOuterType == mContext->mBfObjectType) - // break; - // checkOuterType = GetBaseType(checkOuterType); - // } - // } - //} - + if (typeDef == NULL) { TypeRefNotFound(typeRef); @@ -5568,6 +5572,8 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic auto type = ResolveTypeRef(qualifiedTypeRef, BfPopulateType_TypeDef); if (type == NULL) return NULL; + if (outType != NULL) + *outType = type; auto typeInst = type->ToTypeInstance(); if (typeInst != NULL) return typeInst->mTypeDef; @@ -5577,19 +5583,23 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic return NULL; } -BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVector& methodGenericArguments, bool allowFail) +BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* typeGenericArguments, BfTypeVector* methodGenericArguments, bool allowFail) { if (unspecializedType->IsGenericParam()) { auto genericParam = (BfGenericParamType*)unspecializedType; - if (genericParam->mGenericParamKind == BfGenericParamKind_Method) + if ((genericParam->mGenericParamKind == BfGenericParamKind_Type) && (typeGenericArguments != NULL)) { - if (genericParam->mGenericParamIdx < (int)methodGenericArguments.size()) - { - return methodGenericArguments[genericParam->mGenericParamIdx]; - } + if (genericParam->mGenericParamIdx < (int)typeGenericArguments->size()) + return (*typeGenericArguments)[genericParam->mGenericParamIdx]; BF_ASSERT(allowFail); } + if ((genericParam->mGenericParamKind == BfGenericParamKind_Method) && (methodGenericArguments != NULL)) + { + if (genericParam->mGenericParamIdx < (int)methodGenericArguments->size()) + return (*methodGenericArguments)[genericParam->mGenericParamIdx]; + BF_ASSERT(allowFail); + } return unspecializedType; } @@ -5599,10 +5609,10 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect if (unspecializedType->IsUnknownSizedArray()) { auto* arrayType = (BfUnknownSizedArrayType*)unspecializedType; - auto elementType = ResolveGenericType(arrayType->mElementType, methodGenericArguments, allowFail); + auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, allowFail); if (elementType == NULL) return NULL; - auto sizeType = ResolveGenericType(arrayType->mElementCountSource, methodGenericArguments, allowFail); + auto sizeType = ResolveGenericType(arrayType->mElementCountSource, typeGenericArguments, methodGenericArguments, allowFail); if (sizeType == NULL) return NULL; if (sizeType->IsConstExprValue()) @@ -5615,7 +5625,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect if (unspecializedType->IsSizedArray()) { auto* arrayType = (BfSizedArrayType*)unspecializedType; - auto elementType = ResolveGenericType(arrayType->mElementType, methodGenericArguments, allowFail); + auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, allowFail); if (elementType == NULL) return NULL; return CreateSizedArrayType(elementType, (int)arrayType->mElementCount); @@ -5624,7 +5634,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect if (unspecializedType->IsRef()) { auto refType = (BfRefType*)unspecializedType; - auto elementType = ResolveGenericType(refType->GetUnderlyingType(), methodGenericArguments, allowFail); + auto elementType = ResolveGenericType(refType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail); if (elementType == NULL) return NULL; return CreateRefType(elementType, refType->mRefKind); @@ -5633,7 +5643,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect if (unspecializedType->IsPointer()) { auto ptrType = (BfPointerType*)unspecializedType; - auto elementType = ResolveGenericType(ptrType->GetUnderlyingType(), methodGenericArguments, allowFail); + auto elementType = ResolveGenericType(ptrType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail); if (elementType == NULL) return NULL; return CreatePointerType(elementType); @@ -5642,33 +5652,12 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect if (unspecializedType->IsArray()) { auto arrayType = (BfArrayType*)unspecializedType; - auto elementType = ResolveGenericType(arrayType->GetUnderlyingType(), methodGenericArguments, allowFail); + auto elementType = ResolveGenericType(arrayType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail); if (elementType == NULL) return NULL; return CreateArrayType(elementType, arrayType->mDimensions); } - if (unspecializedType->IsGenericTypeInstance()) - { - auto genericTypeInst = (BfGenericTypeInstance*)unspecializedType; - - BfTypeVector genericArgs; - for (auto genericArg : genericTypeInst->mTypeGenericArguments) - { - if (genericArg->IsUnspecializedType()) - { - auto resolvedArg = ResolveGenericType(genericArg, methodGenericArguments, allowFail); - if (resolvedArg == NULL) - return NULL; - genericArgs.push_back(resolvedArg); - } - else - genericArgs.push_back(genericArg); - } - - return ResolveTypeDef(genericTypeInst->mTypeDef, genericArgs); - } - if (unspecializedType->IsTuple()) { auto tupleType = (BfTupleType*)unspecializedType; @@ -5681,7 +5670,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect { names.push_back(fieldInstance.GetFieldDef()->mName); auto origGenericArg = fieldInstance.mResolvedType; - auto newGenericArg = ResolveGenericType(origGenericArg, methodGenericArguments, allowFail); + auto newGenericArg = ResolveGenericType(origGenericArg, typeGenericArguments, methodGenericArguments, allowFail); if (newGenericArg == NULL) return NULL; if (newGenericArg != origGenericArg) @@ -5694,24 +5683,88 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect return CreateTupleType(genericArgs, names); } - if (unspecializedType->IsDelegate()) + if ((unspecializedType->IsDelegateFromTypeRef()) || (unspecializedType->IsFunctionFromTypeRef())) { - BfDelegateType* unspecializedDelegateType = (BfDelegateType*)unspecializedType; - BfDelegateType* delegateType = mContext->mDelegateTypePool.Get(); + BfTypeInstance* unspecializedDelegateType = (BfTypeInstance*)unspecializedType; + BfGenericTypeInstance* unspecializedGenericDelegateType = unspecializedType->ToGenericTypeInstance(); + BfDelegateInfo* unspecializedDelegateInfo = unspecializedType->GetDelegateInfo(); + bool wantGeneric = false; + bool isUnspecialized = false; + auto _CheckType = [&](BfType* type) + { + if (type->IsGenericParam()) + wantGeneric = true; + if (type->IsUnspecializedType()) + isUnspecialized = true; + }; + bool failed = false; - auto returnType = ResolveGenericType(unspecializedDelegateType->mReturnType, methodGenericArguments, allowFail); + bool hasTypeGenerics = false; + auto returnType = ResolveGenericType(unspecializedDelegateInfo->mReturnType, typeGenericArguments, methodGenericArguments, allowFail); if (returnType == NULL) return NULL; + _CheckType(returnType); + if (returnType->IsGenericParam()) + hasTypeGenerics |= ((BfGenericParamType*)returnType)->mGenericParamKind == BfGenericParamKind_Type; + Array paramTypes; + for (auto param : unspecializedDelegateInfo->mParams) + { + auto paramType = ResolveGenericType(param, typeGenericArguments, methodGenericArguments, allowFail); + if (paramType == NULL) + return NULL; + paramTypes.Add(paramType); + _CheckType(paramType); + } + + if (unspecializedGenericDelegateType == NULL) + wantGeneric = false; + + BfTypeInstance* delegateType = NULL; + auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance(); + + if (wantGeneric) + { + Array genericArgs; + for (auto genericArg : unspecializedGenericDelegateType->mTypeGenericArguments) + { + BfType* resolvedArg = NULL; + if (genericArg->IsUnspecializedType()) + { + auto resolvedArg = ResolveGenericType(genericArg, typeGenericArguments, methodGenericArguments, allowFail); + if (resolvedArg == NULL) + return NULL; + } + else + genericArgs.push_back(genericArg); + } + + auto dlgType = mContext->mGenericDelegateTypePool.Get(); + dlgType->mIsUnspecialized = false; + dlgType->mIsUnspecializedVariation = false; + dlgType->mTypeGenericArguments = genericArgs; + for (auto typeGenericArg : genericArgs) + { + if ((typeGenericArg->IsGenericParam()) || (typeGenericArg->IsUnspecializedType())) + dlgType->mIsUnspecialized = true; + } + CheckUnspecializedGenericType(dlgType, BfPopulateType_Identity); + delegateType = dlgType; + } + else + { + auto dlgType = mContext->mDelegateTypePool.Get(); + dlgType->mIsUnspecializedType = isUnspecialized; + dlgType->mIsUnspecializedTypeVariation = isUnspecialized; + delegateType = dlgType; + } - auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance(); - - delegateType->mIsUnspecializedType = false; - delegateType->mIsUnspecializedTypeVariation = false; if (delegateType->mTypeDef != NULL) delete delegateType->mTypeDef; - delegateType->mParams.Clear(); + BfDelegateInfo* delegateInfo = delegateType->GetDelegateInfo(); + delegateInfo->mParams.Clear(); + BfTypeDef* typeDef = new BfTypeDef(); @@ -5730,7 +5783,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect methodDef->mIsStatic = !typeDef->mIsDelegate; auto directTypeRef = BfAstNode::ZeroedAlloc(); - delegateType->mDirectAllocNodes.push_back(directTypeRef); + delegateInfo->mDirectAllocNodes.push_back(directTypeRef); if (typeDef->mIsDelegate) directTypeRef->Init(delegateType); else @@ -5738,40 +5791,27 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect typeDef->mBaseTypes.push_back(directTypeRef); directTypeRef = BfAstNode::ZeroedAlloc(); - delegateType->mDirectAllocNodes.push_back(directTypeRef); + delegateInfo->mDirectAllocNodes.push_back(directTypeRef); directTypeRef->Init(returnType); methodDef->mReturnTypeRef = directTypeRef; - delegateType->mReturnType = returnType; + delegateInfo->mReturnType = returnType; AddDependency(directTypeRef->mType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); BfMethodDef* unspecializedInvokeMethodDef = unspecializedDelegateType->mTypeDef->GetMethodByName("Invoke"); int paramIdx = 0; - for (auto param : unspecializedDelegateType->mParams) + for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++) { - auto paramType = ResolveGenericType(param, methodGenericArguments, allowFail); - if (paramType == NULL) - { - failed = true; - break; - } + auto paramType = paramTypes[paramIdx]; BfParameterDef* unspecializedParamDef = unspecializedInvokeMethodDef->mParams[paramIdx]; - if (paramType->IsUnspecializedType()) - delegateType->mIsUnspecializedType = true; - if (paramType->IsUnspecializedTypeVariation()) - delegateType->mIsUnspecializedTypeVariation = true; if (!paramType->IsReified()) delegateType->mIsReified = false; - if (paramType->IsGenericParam()) - { - delegateType->mIsUnspecializedTypeVariation = true; - } - + auto directTypeRef = BfAstNode::ZeroedAlloc(); - delegateType->mDirectAllocNodes.push_back(directTypeRef); + delegateInfo->mDirectAllocNodes.push_back(directTypeRef); directTypeRef->Init(paramType); BfParameterDef* paramDef = new BfParameterDef(); @@ -5781,7 +5821,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect methodDef->mParams.push_back(paramDef); paramIdx++; - delegateType->mParams.Add(paramType); + delegateInfo->mParams.Add(paramType); AddDependency(paramType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); } @@ -5801,14 +5841,37 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect resolvedType = ResolveType(delegateType, BfPopulateType_Identity); if (resolvedType != delegateType) { - mContext->mDelegateTypePool.GiveBack(delegateType); - //mContext->mTypeDefTypeRefPool.GiveBack(typeRef); + if (delegateType->IsGenericTypeInstance()) + mContext->mGenericDelegateTypePool.GiveBack((BfGenericDelegateType*)delegateType); + else + mContext->mDelegateTypePool.GiveBack((BfDelegateType*)delegateType); } BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType()); return resolvedType; } + if (unspecializedType->IsGenericTypeInstance()) + { + auto genericTypeInst = (BfGenericTypeInstance*)unspecializedType; + + BfTypeVector genericArgs; + for (auto genericArg : genericTypeInst->mTypeGenericArguments) + { + if (genericArg->IsUnspecializedType()) + { + auto resolvedArg = ResolveGenericType(genericArg, typeGenericArguments, methodGenericArguments, allowFail); + if (resolvedArg == NULL) + return NULL; + genericArgs.push_back(resolvedArg); + } + else + genericArgs.push_back(genericArg); + } + + return ResolveTypeDef(genericTypeInst->mTypeDef, genericArgs); + } + return unspecializedType; } @@ -6091,8 +6154,8 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy } else if (resolvedTypeRef->IsDelegateFromTypeRef() || resolvedTypeRef->IsFunctionFromTypeRef()) { - auto delegateType = (BfDelegateType*)resolvedTypeRef; - auto invokeMethod = GetDelegateInvokeMethod(delegateType); + auto delegateInfo = resolvedTypeRef->GetDelegateInfo(); + auto invokeMethod = GetDelegateInvokeMethod(resolvedTypeRef->ToTypeInstance()); AddDependency(invokeMethod->mReturnType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference); for (auto& param : invokeMethod->mParams) @@ -6357,7 +6420,35 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric BfTypeLookupEntry* typeLookupEntryPtr = NULL; BfTypeLookupResult* resultPtr = NULL; if (typeInstance->mLookupResults.TryAdd(typeLookupEntry, &typeLookupEntryPtr, &resultPtr)) - { + { + if (!typeInstance->IsTypeAlias()) + { + BF_ASSERT(useTypeDef->mTypeCode != BfTypeCode_TypeAlias); + } + +#ifdef _DEBUG + if (typeInstance->mTypeId == 2727) + { + NOP; + } + + if ((typeInstance->IsTypeAlias()) || (useTypeDef->mTypeCode == BfTypeCode_TypeAlias)) + { + if (useTypeDef != typeInstance->mTypeDef) + { + NOP; + } +// if (useTypeDef->mName != typeInstance->mTypeDef->mName) +// { +// if ((mCurMethodInstance == NULL) || (!mCurMethodInstance->mIsForeignMethodDef) || +// (useTypeDef->mName != mCurMethodInstance->mMethodInfoEx->mForeignType->mTypeDef->mName)) +// { +// BF_DBG_FATAL("Name mismatch"); +// } +// } + } +#endif + typeLookupEntryPtr->mAtomUpdateIdx = typeLookupEntry.mName.GetAtomUpdateIdx(); // FindTypeDefRaw may re-enter when finding base types, so we need to expect that resultPtr can change @@ -7355,6 +7446,12 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } } + + if (typeRef->ToString() == "ClassA.AliasA3") + { + NOP; + } + BfResolvedTypeSet::LookupContext lookupCtx; lookupCtx.mRootTypeRef = typeRef; lookupCtx.mRootTypeDef = typeDef; @@ -7436,10 +7533,9 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } CheckUnspecializedGenericType(genericTypeInst, populateType); - resolvedEntry->mValue = genericTypeInst; - BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash); populateModule->InitType(genericTypeInst, populateType); + BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash); return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags); } } @@ -7464,8 +7560,22 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } resolvedEntry->mValue = typeInst; - BF_ASSERT(BfResolvedTypeSet::Hash(typeInst, &lookupCtx) == resolvedEntry->mHash); + +#ifdef _DEBUG + int typeRefash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); +#endif + populateModule->InitType(typeInst, populateType); + + if (BfResolvedTypeSet::Hash(typeInst, &lookupCtx) != resolvedEntry->mHash) + { + int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); + int typeHash = BfResolvedTypeSet::Hash(typeInst, &lookupCtx); + BF_ASSERT(refHash == typeHash); + } + { + BF_ASSERT(BfResolvedTypeSet::Hash(typeInst, &lookupCtx) == resolvedEntry->mHash); + } return ResolveTypeResult(typeRef, typeInst, populateType, resolveFlags); } else if (auto arrayTypeRef = BfNodeDynCast(typeRef)) @@ -7565,63 +7675,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula int wantNumGenericParams = genericTypeInstRef->GetGenericArgCount(); BfTypeDef* ambiguousTypeDef = NULL; - BfTypeDef* typeDef = ResolveGenericInstanceDef(genericTypeInstRef); - - BfGenericTypeInstance* genericTypeInst; - if ((typeDef != NULL) && (typeDef->mTypeCode == BfTypeCode_TypeAlias)) - { - auto typeAliasType = new BfGenericTypeAliasType(); - genericTypeInst = typeAliasType; - } - else - genericTypeInst = new BfGenericTypeInstance(); - genericTypeInst->mContext = mContext; - - if (ambiguousTypeDef != NULL) - ShowAmbiguousTypeError(typeRef, typeDef, ambiguousTypeDef); - if (typeDef == NULL) - { - Fail("Unable to resolve type", typeRef); - delete genericTypeInst; - mContext->mResolvedTypes.RemoveEntry(resolvedEntry); - return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); - } - - BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Deleted); - - if (typeDef->mGenericParamDefs.size() == 0) - { - Fail("Not a generic type", typeRef); - delete genericTypeInst; - mContext->mResolvedTypes.RemoveEntry(resolvedEntry); - return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); - } - - int startDefGenericParamIdx = 0; - genericTypeInst->mTypeDef = typeDef; - - if (mCurTypeInstance != NULL) - { - // Copy generic params for our parent type if the current type instance shares that parent type - //auto outerType = mSystem->GetOuterTypeNonPartial(typeDef); - auto outerType = typeDef->mOuterType; - BfTypeDef* commonOuterType = FindCommonOuterType(mCurTypeInstance->mTypeDef, outerType); - if ((commonOuterType) && (mCurTypeInstance->IsGenericTypeInstance())) - { - startDefGenericParamIdx = (int)commonOuterType->mGenericParamDefs.size(); - auto parentTypeInstance = (BfGenericTypeInstance*)mCurTypeInstance; - if (parentTypeInstance->IsTypeAlias()) - parentTypeInstance = (BfGenericTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance(); - for (int i = 0; i < startDefGenericParamIdx; i++) - { - genericTypeInst->mGenericParams.push_back(parentTypeInstance->mGenericParams[i]->AddRef()); - genericTypeInst->mTypeGenericArguments.push_back(parentTypeInstance->mTypeGenericArguments[i]); - auto typeGenericArg = genericTypeInst->mTypeGenericArguments[i]; - genericTypeInst->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType(); - } - } - } - Array genericArguments; std::function _GetTypeRefs = [&](BfTypeReference* typeRef) { @@ -7638,15 +7691,109 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula { for (auto genericArg : genericTypeRef->mGenericArguments) genericArguments.push_back(genericArg); - } + } }; _GetTypeRefs(genericTypeInstRef); - int wantedGenericParams = (int)typeDef->mGenericParamDefs.size() - startDefGenericParamIdx; + BfTypeVector genericArgs; + + BfType* type = NULL; + BfTypeDef* typeDef = ResolveGenericInstanceDef(genericTypeInstRef, &type); + if(ambiguousTypeDef != NULL) + ShowAmbiguousTypeError(typeRef, typeDef, ambiguousTypeDef); + if (typeDef == NULL) + { + Fail("Unable to resolve type", typeRef); + mContext->mResolvedTypes.RemoveEntry(resolvedEntry); + return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); + } + + auto outerType = typeDef->mOuterType; + BfTypeDef* commonOuterType = NULL; + if (mCurTypeInstance != NULL) + { + // Copy generic params for our parent type if the current type instance shares that parent type + auto outerType = typeDef->mOuterType; + commonOuterType = FindCommonOuterType(mCurTypeInstance->mTypeDef, outerType); + if ((commonOuterType) && (mCurTypeInstance->IsGenericTypeInstance())) + { + int startDefGenericParamIdx = (int)commonOuterType->mGenericParamDefs.size(); + auto parentTypeInstance = (BfGenericTypeInstance*)mCurTypeInstance; + if (parentTypeInstance->IsTypeAlias()) + parentTypeInstance = (BfGenericTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance(); + for (int i = 0; i < startDefGenericParamIdx; i++) + genericArgs.push_back(parentTypeInstance->mTypeGenericArguments[i]); + } + } + + for (auto genericArgRef : genericArguments) + { + auto genericArg = ResolveTypeRef(genericArgRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericMethodParamConstValue); + if (genericArg == NULL) + { + mContext->mResolvedTypes.RemoveEntry(resolvedEntry); + return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); + } + genericArgs.Add(genericArg); + } + + BfGenericTypeInstance* genericTypeInst; + if ((type != NULL) && + ((type->IsDelegateFromTypeRef()) || (type->IsFunctionFromTypeRef()))) + { + mContext->mResolvedTypes.RemoveEntry(resolvedEntry); + return ResolveGenericType(type, &genericArgs, NULL); + } + else if ((typeDef != NULL) && (typeDef->mTypeCode == BfTypeCode_TypeAlias)) + { + auto typeAliasType = new BfGenericTypeAliasType(); + genericTypeInst = typeAliasType; + } + else + genericTypeInst = new BfGenericTypeInstance(); + genericTypeInst->mContext = mContext; + + + BF_ASSERT(typeDef->mDefState != BfTypeDef::DefState_Deleted); + + int genericParamCount = (int)typeDef->mGenericParamDefs.size(); + if ((type != NULL) && (type->IsGenericTypeInstance())) + { + // Is a generic type for sure... + // We need this case for generic methods + genericParamCount = (int)((BfGenericTypeInstance*)type)->mTypeGenericArguments.size(); + } + else if (typeDef->mGenericParamDefs.size() == 0) + { + Fail("Not a generic type", typeRef); + delete genericTypeInst; + mContext->mResolvedTypes.RemoveEntry(resolvedEntry); + return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); + } + + int startDefGenericParamIdx = 0; + genericTypeInst->mTypeDef = typeDef; + + if ((commonOuterType != NULL) && (mCurTypeInstance->IsGenericTypeInstance())) + { + auto parentTypeInstance = (BfGenericTypeInstance*)mCurTypeInstance; + if (parentTypeInstance->IsTypeAlias()) + parentTypeInstance = (BfGenericTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance(); + for (int i = 0; i < startDefGenericParamIdx; i++) + { + genericTypeInst->mGenericParams.push_back(parentTypeInstance->mGenericParams[i]->AddRef()); + genericTypeInst->mTypeGenericArguments.push_back(parentTypeInstance->mTypeGenericArguments[i]); + auto typeGenericArg = genericTypeInst->mTypeGenericArguments[i]; + genericTypeInst->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType(); + } + } + + + int wantedGenericParams = genericParamCount - startDefGenericParamIdx; int genericArgDiffCount = (int)genericArguments.size() - wantedGenericParams; if (genericArgDiffCount != 0) { - int innerWantedGenericParams = (int)typeDef->mGenericParamDefs.size(); + int innerWantedGenericParams = genericParamCount; if (typeDef->mOuterType != NULL) innerWantedGenericParams -= (int)typeDef->mOuterType->mGenericParamDefs.size(); ShowGenericArgCountError(genericTypeInstRef, innerWantedGenericParams); @@ -7658,14 +7805,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula int genericParamIdx = 0; for (auto genericArgRef : genericArguments) { - auto genericArg = ResolveTypeRef(genericArgRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericMethodParamConstValue); - if (genericArg == NULL) - { - delete genericTypeInst; - mContext->mResolvedTypes.RemoveEntry(resolvedEntry); - return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); - } - + auto genericArg = genericArgs[genericParamIdx + startDefGenericParamIdx]; genericTypeInst->mTypeGenericArguments.push_back(genericArg); genericTypeInst->mTypeGenericArgumentRefs.push_back(genericArgRef); genericParamIdx++; @@ -7674,9 +7814,22 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula resolvedEntry->mValue = genericTypeInst; CheckUnspecializedGenericType(genericTypeInst, populateType); - - BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash); populateModule->InitType(genericTypeInst, populateType); + +#ifdef _DEBUG + if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash) + { + int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); + int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx); + BF_ASSERT(refHash == typeHash); + } + if (!BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx)) + { + BF_ASSERT(BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx)); + } +#endif + + BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash); return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags); } else if (auto tupleTypeRef = BfNodeDynCast(typeRef)) @@ -7806,18 +7959,67 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula return ResolveTypeResult(typeRef, refType, populateType, resolveFlags); } else if (auto delegateTypeRef = BfNodeDynCast(typeRef)) - { + { + bool wantGeneric = false; + bool isUnspecialized = false; + auto _CheckType = [&](BfType* type) + { + if (type->IsGenericParam()) + wantGeneric = true; + if (type->IsUnspecializedType()) + isUnspecialized = true; + }; + auto returnType = ResolveTypeRef(delegateTypeRef->mReturnType); if (returnType == NULL) + returnType = GetPrimitiveType(BfTypeCode_Var); + _CheckType(returnType); + + Array paramTypes; + for (auto param : delegateTypeRef->mParams) { - mContext->mResolvedTypes.RemoveEntry(resolvedEntry); - return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); + auto paramType = ResolveTypeRef(param->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowRef); + if (paramType == NULL) + paramType = GetPrimitiveType(BfTypeCode_Var); + paramTypes.Add(paramType); + _CheckType(paramType); } + if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsGenericTypeInstance())) + wantGeneric = false; + auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance(); - BfDelegateType* delegateType = new BfDelegateType(); - + BfDelegateInfo* delegateInfo = NULL; + BfTypeInstance* delegateType = NULL; + if (wantGeneric) + { + BfGenericTypeInstance* genericTypeInst = new BfGenericDelegateType(); + delegateType = genericTypeInst; + delegateInfo = delegateType->GetDelegateInfo(); + + if (mCurTypeInstance->IsGenericTypeInstance()) + { + auto parentTypeInstance = (BfGenericTypeInstance*)mCurTypeInstance; + for (int i = 0; i < parentTypeInstance->mGenericParams.size(); i++) + { + genericTypeInst->mGenericParams.push_back(parentTypeInstance->mGenericParams[i]->AddRef()); + genericTypeInst->mTypeGenericArguments.push_back(parentTypeInstance->mTypeGenericArguments[i]); + auto typeGenericArg = genericTypeInst->mTypeGenericArguments[i]; + genericTypeInst->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType(); + } + CheckUnspecializedGenericType(genericTypeInst, populateType); + } + } + else + { + auto dlgType = new BfDelegateType(); + delegateInfo = dlgType->GetDelegateInfo(); + dlgType->mIsUnspecializedType = isUnspecialized; + dlgType->mIsUnspecializedTypeVariation = isUnspecialized; + delegateType = dlgType; + } + Val128 hashContext; BfTypeDef* typeDef = new BfTypeDef(); @@ -7843,7 +8045,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula methodDef->mIsStatic = !typeDef->mIsDelegate; auto directTypeRef = BfAstNode::ZeroedAlloc(); - delegateType->mDirectAllocNodes.push_back(directTypeRef); + delegateInfo->mDirectAllocNodes.push_back(directTypeRef); if (typeDef->mIsDelegate) directTypeRef->Init(delegateType); else @@ -7851,38 +8053,32 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula typeDef->mBaseTypes.push_back(directTypeRef); directTypeRef = BfAstNode::ZeroedAlloc(); - delegateType->mDirectAllocNodes.push_back(directTypeRef); + delegateInfo->mDirectAllocNodes.push_back(directTypeRef); directTypeRef->Init(returnType); methodDef->mReturnTypeRef = directTypeRef; - delegateType->mReturnType = returnType; + delegateInfo->mReturnType = returnType; AddDependency(directTypeRef->mType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); auto hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx); - - int paramIdx = 0; - for (auto param : delegateTypeRef->mParams) + + for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++) { - auto paramType = ResolveTypeRef(param->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowRef); + auto param = delegateTypeRef->mParams[paramIdx]; + auto paramType = paramTypes[paramIdx]; if (paramType == NULL) paramType = GetPrimitiveType(BfTypeCode_Var); + String paramName; if (param->mNameNode != NULL) paramName = param->mNameNode->ToString(); - if (paramType->IsUnspecializedType()) - delegateType->mIsUnspecializedType = true; - if (paramType->IsUnspecializedTypeVariation()) - delegateType->mIsUnspecializedTypeVariation = true; if (!paramType->IsReified()) delegateType->mIsReified = false; - if (paramType->IsGenericParam()) - { - delegateType->mIsUnspecializedTypeVariation = true; - } + auto directTypeRef = BfAstNode::ZeroedAlloc(); - delegateType->mDirectAllocNodes.push_back(directTypeRef); + delegateInfo->mDirectAllocNodes.push_back(directTypeRef); directTypeRef->Init(paramType); BfParameterDef* paramDef = new BfParameterDef(); @@ -7890,9 +8086,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula paramDef->mTypeRef = directTypeRef; paramDef->mName = paramName; methodDef->mParams.push_back(paramDef); - paramIdx++; - - delegateType->mParams.Add(paramType); + + delegateInfo->mParams.Add(paramType); AddDependency(paramType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); } @@ -7916,9 +8111,10 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula // int typeHash = BfResolvedTypeSet::Hash(delegateType, &lookupCtx); // BF_ASSERT(refHash == typeHash); // } -// #endif +// #endif BF_ASSERT(BfResolvedTypeSet::Hash(delegateType, &lookupCtx) == resolvedEntry->mHash); + return ResolveTypeResult(typeRef, delegateType, populateType, resolveFlags); } else if (auto genericParamTypeRef = BfNodeDynCast(typeRef)) @@ -8040,6 +8236,8 @@ BfTypeInstance* BfModule::GetUnspecializedTypeInstance(BfTypeInstance* typeInst) if (!typeInst->IsGenericTypeInstance()) return typeInst; + BF_ASSERT((!typeInst->IsDelegateFromTypeRef()) && (!typeInst->IsFunctionFromTypeRef())); + auto genericTypeInst = (BfGenericTypeInstance*)typeInst; auto result = ResolveTypeDef(genericTypeInst->mTypeDef, BfPopulateType_Declaration); BF_ASSERT((result != NULL) && (result->IsUnspecializedType())); @@ -8143,7 +8341,7 @@ bool BfModule::CanCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFl BP_ZONE("BfModule::CanCast"); SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true); - return CastToValue(NULL, typedVal, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail)); + return CastToValue(NULL, typedVal, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail | BfCastFlags_IsCastCheck)); } bool BfModule::AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting) @@ -10240,7 +10438,8 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF { SetAndRestoreValue prevTypeInstance(mCurTypeInstance); - auto delegateType = (BfDelegateType*)resolvedType; + auto delegateType = (BfTypeInstance*)resolvedType; + auto delegateInfo = resolvedType->GetDelegateInfo(); if (mCurTypeInstance == delegateType) { @@ -10267,7 +10466,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF str += "delegate "; else str += "function "; - DoTypeToString(str, delegateType->mReturnType); + DoTypeToString(str, delegateInfo->mReturnType, typeNameFlags, genericMethodNameOverrides); str += "("; for (int paramIdx = 0; paramIdx < methodDef->mParams.size(); paramIdx++) { @@ -10276,7 +10475,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF auto paramDef = methodDef->mParams[paramIdx]; BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType)); - DoTypeToString(str, delegateType->mParams[paramIdx], innerFlags, genericMethodNameOverrides); + DoTypeToString(str, delegateInfo->mParams[paramIdx], innerFlags, genericMethodNameOverrides); if (!paramDef->mName.IsEmpty()) { @@ -10309,9 +10508,6 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF else if (resolvedType->IsTypeInstance()) { BfTypeInstance* typeInstance = (BfTypeInstance*)resolvedType; - - //auto checkTypeInst = typeInstance; - //auto checkTypeDef = typeInstance->mTypeDef; bool omitNamespace = (typeNameFlags & BfTypeNameFlag_OmitNamespace) != 0; if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0) @@ -10333,38 +10529,6 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF } } - //_AddTypeName(typeInstance->mTypeDef, 0); - - //std::function _AddTypeName = [&](StringImpl& str, BfTypeInstance*& checkTypeInst, BfTypeDef* checkTypeDef, int depth, BfTypeNameFlags typeNameFlags) - -// BfTypeDef* endTypeDef = NULL; -// if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0) -// { -// auto checkTypeInst = typeInstance; -// auto checkTypeDef = typeInstance->mTypeDef; -// -// auto outerTypeInst = GetOuterType(checkTypeInst); -// if (outerTypeInst == NULL) -// return; -// checkTypeInst = outerTypeInst; -// -// auto checkCurTypeInst = mCurTypeInstance; // Only used for ReduceName -// BfTypeDef* checkCurTypeDef = NULL; -// if (checkCurTypeInst != NULL) -// checkCurTypeDef = checkCurTypeInst->mTypeDef; -// -// while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth) -// { -// checkCurTypeInst = GetOuterType(checkCurTypeInst); -// checkCurTypeDef = checkCurTypeInst->mTypeDef; -// } -// -// if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst)) -// endTypeDef = checkCurTypeDef; -// } - - - SizedArray typeDefStack; BfTypeDef* endTypeDef = NULL; @@ -10430,37 +10594,6 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF int depth = (int)typeDefStack.size() - 1; typeDefStack.pop_back(); -// if (depth > 0) -// { -// if ((typeNameFlags & BfTypeNameFlag_OmitOuterType) != 0) -// return; -// -// if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0) -// { -// auto outerTypeInst = GetOuterType(checkTypeInst); -// if (outerTypeInst == NULL) -// return; -// checkTypeInst = outerTypeInst; -// -// while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth) -// { -// checkCurTypeInst = GetOuterType(checkCurTypeInst); -// checkCurTypeDef = checkCurTypeInst->mTypeDef; -// } -// -// if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst)) -// return; // Found outer type -// } -// } - -// auto parentTypeDef = checkTypeDef->mOuterType; -// if (parentTypeDef != NULL) -// { -// //_AddTypeName(parentTypeDef, depth + 1); -// typeDefStack.Add(parentTypeDef); -// continue; -// } - if (checkTypeDef->IsGlobalsContainer()) { if ((typeNameFlags & BfTypeNameFlag_AddGlobalContainerName) != 0) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index c580e2ab..ff2be436 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -1907,9 +1907,7 @@ void BfClosureType::Finish() BfDelegateType::~BfDelegateType() { - delete mTypeDef; - for (auto directAllocNode : mDirectAllocNodes) - delete directAllocNode; + delete mTypeDef; } ////////////////////////////////////////////////////////////////////////// @@ -2129,6 +2127,19 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef) { //BP_ZONE("BfResolvedTypeSet::Hash"); +// if (type->IsTypeAlias()) +// { +// auto underlyingType = type->GetUnderlyingType(); +// BF_ASSERT(underlyingType != NULL); +// if (underlyingType == NULL) +// { +// ctx->mFailed = true; +// return 0; +// } +// return Hash(underlyingType, ctx, allowRef); +// } +// else + if (type->IsBoxed()) { BfBoxedType* boxedType = (BfBoxedType*)type; @@ -2142,21 +2153,22 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef) return (elemHash << 5) - elemHash; } else if (type->IsDelegateFromTypeRef() || type->IsFunctionFromTypeRef()) - { - auto delegateType = (BfDelegateType*)type; - + { + auto typeInst = (BfTypeInstance*)type; int hashVal = HASH_DELEGATE; - hashVal = ((hashVal ^ (Hash(delegateType->mReturnType, ctx))) << 5) - hashVal; + auto delegateInfo = type->GetDelegateInfo(); - auto methodDef = delegateType->mTypeDef->mMethods[0]; + hashVal = ((hashVal ^ (Hash(delegateInfo->mReturnType, ctx))) << 5) - hashVal; + + auto methodDef = typeInst->mTypeDef->mMethods[0]; BF_ASSERT(methodDef->mName == "Invoke"); - BF_ASSERT(delegateType->mParams.size() == methodDef->mParams.size()); + BF_ASSERT(delegateInfo->mParams.size() == methodDef->mParams.size()); - for (int paramIdx = 0; paramIdx < delegateType->mParams.size(); paramIdx++) + for (int paramIdx = 0; paramIdx < delegateInfo->mParams.size(); paramIdx++) { // Parse attributes? - hashVal = ((hashVal ^ (Hash(delegateType->mParams[paramIdx], ctx))) << 5) - hashVal; + hashVal = ((hashVal ^ (Hash(delegateInfo->mParams[paramIdx], ctx))) << 5) - hashVal; String paramName = methodDef->mParams[paramIdx]->mName; int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length()); hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal; @@ -2313,61 +2325,28 @@ static int HashNode(BfAstNode* node) return (int)Hash64(nameStr, node->GetSrcLength()); } +int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags) +{ + bool isHeadType = typeRef == ctx->mRootTypeRef; + + BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None; + if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0) + resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue); + + auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, resolveFlags); + if (resolvedType == NULL) + { + ctx->mFailed = true; + return 0; + } + return Hash(resolvedType, ctx); +} + int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags) { -// if (auto typeDefTypeRef = BfNodeDynCast(typeRef)) -// { -// if (typeDefTypeRef->mTypeDef != NULL) -// { -// int hashVal = typeDefTypeRef->mTypeDef->mHash; -// -// if (typeDefTypeRef->mTypeDef->mGenericParamDefs.size() != 0) -// { -// auto checkTypeInstance = ctx->mModule->mCurTypeInstance; -// if (checkTypeInstance->IsBoxed()) -// checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance(); -// -// //if (!module->TypeHasParent(module->mCurTypeInstance->mTypeDef, typeDefTypeRef->mTypeDef->mParentType)) -// auto outerType = ctx->mModule->mSystem->GetOuterTypeNonPartial(typeDefTypeRef->mTypeDef); -// BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, outerType); -// //BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->GetActiveTypeDef(), typeDefTypeRef->mTypeDef->mOuterType); -// if ((commonOuterType == NULL) || (commonOuterType->mGenericParamDefs.size() == 0)) -// { -// ctx->mModule->Fail("Generic arguments expected", typeDefTypeRef); -// ctx->mFailed = true; -// return 0; -// } -// -// BF_ASSERT(checkTypeInstance->IsGenericTypeInstance()); -// auto curGenericTypeInst = (BfGenericTypeInstance*)checkTypeInstance; -// //int numParentGenericParams = (int)typeDefTypeRef->mTypeDef->mGenericParams.size(); -// int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); -// for (int i = 0; i < numParentGenericParams; i++) -// { -// hashVal = ((hashVal ^ (Hash(curGenericTypeInst->mTypeGenericArguments[i], ctx))) << 5) - hashVal; -// } -// } -// -// return hashVal; -// } -// -// bool isHeadType = typeRef == ctx->mRootTypeRef; -// -// BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None; -// if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0) -// resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue); -// -// auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, resolveFlags); -// if (resolvedType == NULL) -// { -// ctx->mFailed = true; -// return 0; -// } -// return Hash(resolvedType, ctx); -// } - - if ((typeRef == ctx->mRootTypeRef) && (ctx->mRootTypeDef != NULL)) - { + if ((typeRef == ctx->mRootTypeRef) && (ctx->mRootTypeDef != NULL) && + ((typeRef->IsNamedTypeReference()) || (BfNodeIsA(typeRef)))) + { BfTypeDef* typeDef = ctx->mRootTypeDef; int hashVal = typeDef->mHash; @@ -2401,24 +2380,48 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash if (typeRef->IsNamedTypeReference()) { - bool isHeadType = typeRef == ctx->mRootTypeRef; - - BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None; - if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0) - resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue); - - auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, resolveFlags); - if (resolvedType == NULL) - { - ctx->mFailed = true; - return 0; - } - return Hash(resolvedType, ctx); + return DirectHash(typeRef, ctx, flags); } else if (auto genericInstTypeRef = BfNodeDynCastExact(typeRef)) { //BfType* type = NULL; BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(genericInstTypeRef); + + if (elementTypeDef == NULL) + { + ctx->mFailed = true; + return 0; + } + + // Don't translate aliases for the root type, just element types + if (ctx->mRootTypeRef == typeRef) + { + BF_ASSERT((ctx->mRootTypeDef == NULL) || (ctx->mRootTypeDef == elementTypeDef)); + ctx->mRootTypeDef = elementTypeDef; + } + else if (elementTypeDef->mTypeCode == BfTypeCode_TypeAlias) + { + BfTypeVector genericArgs; + for (auto genericArgTypeRef : genericInstTypeRef->mGenericArguments) + { + auto argType = ctx->mModule->ResolveTypeRef(genericArgTypeRef, BfPopulateType_Identity); + if (argType != NULL) + genericArgs.Add(argType); + else + ctx->mFailed = true; + } + + if (!ctx->mFailed) + { + auto resolvedType = ctx->mModule->ResolveTypeDef(elementTypeDef, genericArgs); + if ((resolvedType != NULL) && (resolvedType->IsTypeAlias())) + { + auto underlyingType = resolvedType->GetUnderlyingType(); + return Hash(underlyingType, ctx, flags); + } + } + } + int hashVal; /*if (type != NULL) { @@ -2426,17 +2429,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash } else */ { - if (elementTypeDef == NULL) - { - ctx->mFailed = true; - return 0; - } - - if (ctx->mRootTypeRef == typeRef) - { - BF_ASSERT((ctx->mRootTypeDef == NULL) || (ctx->mRootTypeDef == elementTypeDef)); - ctx->mRootTypeDef = elementTypeDef; - } + hashVal = elementTypeDef->mHash; } @@ -2810,22 +2803,22 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) if (!rhs->IsDelegateFromTypeRef() && !rhs->IsFunctionFromTypeRef()) return false; if (lhs->IsDelegate() != rhs->IsDelegate()) - return false; - BfDelegateType* lhsDelegateType = (BfDelegateType*)lhs; - BfDelegateType* rhsDelegateType = (BfDelegateType*)rhs; - if (lhsDelegateType->mTypeDef->mIsDelegate != rhsDelegateType->mTypeDef->mIsDelegate) + return false; + BfDelegateInfo* lhsDelegateInfo = lhs->GetDelegateInfo(); + BfDelegateInfo* rhsDelegateInfo = rhs->GetDelegateInfo(); + if (lhsInst->mTypeDef->mIsDelegate != rhsInst->mTypeDef->mIsDelegate) return false; - auto lhsMethodDef = lhsDelegateType->mTypeDef->mMethods[0]; - auto rhsMethodDef = rhsDelegateType->mTypeDef->mMethods[0]; + auto lhsMethodDef = lhsInst->mTypeDef->mMethods[0]; + auto rhsMethodDef = rhsInst->mTypeDef->mMethods[0]; - if (lhsDelegateType->mReturnType != rhsDelegateType->mReturnType) + if (lhsDelegateInfo->mReturnType != rhsDelegateInfo->mReturnType) return false; - if (lhsDelegateType->mParams.size() != rhsDelegateType->mParams.size()) + if (lhsDelegateInfo->mParams.size() != rhsDelegateInfo->mParams.size()) return false; - for (int paramIdx = 0; paramIdx < lhsDelegateType->mParams.size(); paramIdx++) + for (int paramIdx = 0; paramIdx < lhsDelegateInfo->mParams.size(); paramIdx++) { - if (lhsDelegateType->mParams[paramIdx] != rhsDelegateType->mParams[paramIdx]) + if (lhsDelegateInfo->mParams[paramIdx] != rhsDelegateInfo->mParams[paramIdx]) return false; if (lhsMethodDef->mParams[paramIdx]->mName != rhsMethodDef->mParams[paramIdx]->mName) return false; @@ -3104,8 +3097,11 @@ BfType* BfResolvedTypeSet::LookupContext::ResolveTypeRef(BfTypeReference* typeRe return mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue); } -BfTypeDef* BfResolvedTypeSet::LookupContext::ResolveToTypeDef(BfTypeReference* typeReference) +BfTypeDef* BfResolvedTypeSet::LookupContext::ResolveToTypeDef(BfTypeReference* typeReference, BfType** outType) { + if (outType != NULL) + *outType = NULL; + if (typeReference == mRootTypeRef) return mRootTypeDef; @@ -3114,9 +3110,11 @@ BfTypeDef* BfResolvedTypeSet::LookupContext::ResolveToTypeDef(BfTypeReference* t return typeDefTypeRef->mTypeDef; } - auto type = mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue); + auto type = mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue); if (type == NULL) return NULL; + if (outType != NULL) + *outType = type; if (type->IsPrimitiveType()) return ((BfPrimitiveType*)type)->mTypeDef; auto typeInst = type->ToTypeInstance(); @@ -3125,9 +3123,26 @@ BfTypeDef* BfResolvedTypeSet::LookupContext::ResolveToTypeDef(BfTypeReference* t return typeInst->mTypeDef; } -bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx) +bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx) +{ + auto rhsType = ctx->mModule->ResolveTypeDef(rhsTypeDef, BfPopulateType_Identity); + if (rhsType == NULL) + { + ctx->mFailed = true; + return false; + } + + return BfResolvedTypeSet::Equals(lhs, rhsType, ctx); +} + +bool BfResolvedTypeSet::EqualsNoAlias(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx) { //BP_ZONE("BfResolvedTypeSet::Equals"); + +// if ((rhs == ctx->mRootTypeRef) && (ctx->mRootTypeDef != NULL) && (ctx->mRootTypeDef->mTypeCode == BfTypeCode_TypeAlias)) +// { +// return lhs == ctx->mResolvedType; +// } if (ctx->mRootTypeRef != rhs) { @@ -3138,7 +3153,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* } } - if (rhs->IsNamedTypeReference()) + if (rhs->IsNamedTypeReference()) { if ((ctx->mRootTypeRef != rhs) || (ctx->mRootTypeDef == NULL)) { @@ -3198,9 +3213,9 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* auto rhsDelegateType = BfNodeDynCastExact(rhs); if (rhsDelegateType == NULL) return false; - BfDelegateType* lhsDelegateType = (BfDelegateType*)lhs; + BfDelegateInfo* lhsDelegateType = lhs->GetDelegateInfo(); - BfMethodInstance* lhsInvokeMethodInstance = ctx->mModule->GetRawMethodInstanceAtIdx(lhsDelegateType->ToTypeInstance(), 0, "Invoke"); + BfMethodInstance* lhsInvokeMethodInstance = ctx->mModule->GetRawMethodInstanceAtIdx(lhs->ToTypeInstance(), 0, "Invoke"); if ((lhs->IsDelegate()) != (rhsDelegateType->mTypeToken->GetToken() == BfToken_Delegate)) return false; @@ -3227,9 +3242,13 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* if (lhs->IsGenericTypeInstance()) { - auto rhsTypeDef = ctx->ResolveToTypeDef(rhs); - if (rhsTypeDef == NULL) - return false; + BfType* rhsType = NULL; + auto rhsTypeDef = ctx->ResolveToTypeDef(rhs, &rhsType); + if (rhsTypeDef == NULL) + return false; + + if (rhsType != NULL) + return lhs == rhsType; BfGenericTypeInstance* lhsGenericType = (BfGenericTypeInstance*) lhs; return GenericTypeEquals(lhsGenericType, &lhsGenericType->mTypeGenericArguments, rhs, rhsTypeDef, ctx); @@ -3329,6 +3348,8 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* BfPrimitiveType* lhsPrimType = (BfPrimitiveType*)lhs; auto rhsTypeDef = ctx->ResolveToTypeDef(rhs); +// if (rhsTypeDef->mTypeCode == BfTypeCode_TypeAlias) +// return Equals(lhs, rhs, rhsTypeDef, ctx); return lhsPrimType->mTypeDef == rhsTypeDef; } else if (lhs->IsPointer()) @@ -3483,6 +3504,22 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* return false; } +bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx) +{ + if (EqualsNoAlias(lhs, rhs, ctx)) + return true; + +// if (lhs->IsTypeAlias()) +// { +// auto underylingType = lhs->GetUnderlyingType(); +// BF_ASSERT(underylingType != NULL); +// if (underylingType != NULL) +// return Equals(underylingType, rhs, ctx); +// } + + return false; +} + void BfResolvedTypeSet::RemoveEntry(BfResolvedTypeSet::Entry* entry) { int hashIdx = (entry->mHash & 0x7FFFFFFF) % mHashSize; @@ -3833,7 +3870,7 @@ String BfTypeUtils::TypeToString(BfTypeReference* typeRef) return name; } - BF_DBG_FATAL("Not implemented"); + //BF_DBG_FATAL("Not implemented"); return typeRef->ToString(); } diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index beaa365d..11dc0a77 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -374,6 +374,7 @@ enum BfTypeRebuildFlags BfTypeRebuildFlag_SpecializedByAutocompleteMethod = 0x200, BfTypeRebuildFlag_UnderlyingTypeDeferred = 0x400, BfTypeRebuildFlag_TypeDataSaved = 0x800, + BfTypeRebuildFlag_InTempPool = 0x1000 }; class BfTypeDIReplaceCallback; @@ -388,6 +389,26 @@ enum BfTypeDefineState : uint8 BfTypeDefineState_DefinedAndMethodsSlotted, }; +class BfDelegateInfo +{ +public: + Array mDirectAllocNodes; + BfType* mReturnType; + Array mParams; + +public: + BfDelegateInfo() + { + mReturnType = NULL; + } + + ~BfDelegateInfo() + { + for (auto directAllocNode : mDirectAllocNodes) + delete directAllocNode; + } +}; + class BfType { public: @@ -469,6 +490,7 @@ public: virtual bool IsFunction() { return false; } virtual bool IsDelegateFromTypeRef() { return false; } virtual bool IsFunctionFromTypeRef() { return false; } + virtual BfDelegateInfo* GetDelegateInfo() { return NULL; } virtual bool IsValueType() { return false; } virtual bool IsValueTypeOrValueTypePtr() { return false; } virtual bool IsWrappableType() { return false; } @@ -1968,21 +1990,16 @@ public: class BfDelegateType : public BfTypeInstance { -public: - Array mDirectAllocNodes; - // These depend on the params in Invoke +public: + BfDelegateInfo mDelegateInfo; bool mIsUnspecializedType; - bool mIsUnspecializedTypeVariation; - - BfType* mReturnType; - Array mParams; + bool mIsUnspecializedTypeVariation; public: BfDelegateType() { mIsUnspecializedType = false; - mIsUnspecializedTypeVariation = false; - mReturnType = NULL; + mIsUnspecializedTypeVariation = false; } ~BfDelegateType(); @@ -1996,6 +2013,30 @@ public: virtual bool IsUnspecializedType() override { return mIsUnspecializedType; } virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedTypeVariation; } + + virtual BfDelegateInfo* GetDelegateInfo() { return &mDelegateInfo; } +}; + +class BfGenericDelegateType : public BfGenericTypeInstance +{ +public: + BfDelegateInfo mDelegateInfo; + +public: + BfGenericDelegateType() + { + + } + + virtual bool IsOnDemand() override { return true; } + + virtual bool IsDelegate() override { return mTypeDef->mIsDelegate; } + virtual bool IsDelegateFromTypeRef() override { return mTypeDef->mIsDelegate; } + + virtual bool IsFunction() override { return !mTypeDef->mIsDelegate; } + virtual bool IsFunctionFromTypeRef() override { return !mTypeDef->mIsDelegate; } + + virtual BfDelegateInfo* GetDelegateInfo() override { return &mDelegateInfo; } //virtual bool IsReified() override { return mIsReified; } }; @@ -2303,7 +2344,7 @@ public: public: BfModule* mModule; BfTypeReference* mRootTypeRef; - BfTypeDef* mRootTypeDef; + BfTypeDef* mRootTypeDef; BfType* mResolvedType; bool mFailed; @@ -2311,14 +2352,14 @@ public: LookupContext() { mRootTypeRef = NULL; - mRootTypeDef = NULL; + mRootTypeDef = NULL; mModule = NULL; mResolvedType = NULL; mFailed = false; } BfType* ResolveTypeRef(BfTypeReference* typeReference); - BfTypeDef* ResolveToTypeDef(BfTypeReference* typeReference); + BfTypeDef* ResolveToTypeDef(BfTypeReference* typeReference, BfType** outType = NULL); }; public: @@ -2327,9 +2368,12 @@ public: static bool GenericTypeEquals(BfGenericTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx); static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash); static int Hash(BfType* type, LookupContext* ctx, bool allowRef = false); + static int DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None); static int Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None); static bool Equals(BfType* lhs, BfType* rhs, LookupContext* ctx); + static bool EqualsNoAlias(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx); static bool Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx); + static bool Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx); public: BfResolvedTypeSet() diff --git a/IDEHelper/Tests/src/Aliases.bf b/IDEHelper/Tests/src/Aliases.bf new file mode 100644 index 00000000..336778ca --- /dev/null +++ b/IDEHelper/Tests/src/Aliases.bf @@ -0,0 +1,38 @@ +#pragma warning disable 168 + +using System.Collections; +using System; + +namespace Tests +{ + class Aliases + { + class ClassA + { + public typealias AliasA0 = int32; + public typealias AliasA1 = List; + public typealias AliasA2 = Dictionary; + + public typealias AliasA3 = delegate T(); + public typealias AliasA4 = delegate T(T2 val); + + public delegate T Zag(); + } + + [Test] + public static void TestBasics() + { + ClassA.AliasA0 a0 = default; + a0 = 123; + + ClassA.AliasA1 list = scope List(); + Dictionary dict = scope ClassA.AliasA2(); + + delegate double() dlg = default; + ClassA.AliasA3 dlg2 = dlg; + + delegate double(char8) dlg3 = default; + ClassA.AliasA4 dlg4 = dlg3; + } + } +}