diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 133e9e08..3c675757 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -1127,7 +1127,6 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild if (typeInst->IsGenericTypeInstance()) { auto genericTypeInstance = (BfTypeInstance*)typeInst; - genericTypeInstance->mGenericTypeInfo->mTypeGenericArgumentRefs.Clear(); for (auto genericParam : genericTypeInstance->mGenericTypeInfo->mGenericParams) genericParam->Release(); genericTypeInstance->mGenericTypeInfo->mInitializedGenericParams = false; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index e022a1b6..ab3d706f 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -7901,7 +7901,7 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic if (auto qualifiedTypeRef = BfNodeDynCast(typeRef)) { BfAutoParentNodeEntry autoParentNodeEntry(this, genericTypeRef); - auto type = ResolveTypeRef(qualifiedTypeRef, BfPopulateType_TypeDef, BfResolveTypeRefFlag_None, numGenericParams); + auto type = ResolveTypeRef(qualifiedTypeRef, BfPopulateType_TypeDef, resolveFlags, numGenericParams); if (type == NULL) return NULL; if (outType != NULL) @@ -8946,7 +8946,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy if ((populateType > BfPopulateType_IdentityNoRemapAlias) && (!ResolveTypeResult_Validate(typeRef, resolvedTypeRef))) return NULL; - if (populateType != BfPopulateType_IdentityNoRemapAlias) + if ((populateType != BfPopulateType_TypeDef) && (populateType != BfPopulateType_IdentityNoRemapAlias)) { while ((resolvedTypeRef != NULL) && (resolvedTypeRef->IsTypeAlias())) { @@ -10789,50 +10789,75 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } else if (auto genericTypeInstRef = BfNodeDynCast(typeRef)) { - int wantNumGenericParams = genericTypeInstRef->GetGenericArgCount(); - BfTypeDef* ambiguousTypeDef = NULL; - + BfTypeReference* outerTypeRef = NULL; + Array genericArguments; - std::function _GetTypeRefs = [&](BfTypeReference* typeRef) + + BfTypeReference* checkTypeRef = genericTypeInstRef; + int checkIdx = 0; + + while (checkTypeRef != NULL) { - //TODO:GENERICS - if (auto elementedTypeRef = BfNodeDynCast(typeRef)) + checkIdx++; + if (checkIdx >= 3) { - _GetTypeRefs(elementedTypeRef->mElementType); - } - else if (auto qualifiedTypeRef = BfNodeDynCast(typeRef)) - { - _GetTypeRefs(qualifiedTypeRef->mLeft); + outerTypeRef = checkTypeRef; + break; } - if (auto genericTypeRef = BfNodeDynCast(typeRef)) - { + if (auto genericTypeRef = BfNodeDynCast(checkTypeRef)) + { for (auto genericArg : genericTypeRef->mGenericArguments) genericArguments.push_back(genericArg); + checkTypeRef = genericTypeRef->mElementType; + continue; } - }; - _GetTypeRefs(genericTypeInstRef); + if (auto elementedTypeRef = BfNodeDynCast(checkTypeRef)) + { + checkTypeRef = elementedTypeRef->mElementType; + continue; + } + + if (auto qualifiedTypeRef = BfNodeDynCast(checkTypeRef)) + { + checkTypeRef = qualifiedTypeRef->mLeft; + continue; + } + break; + } + BfTypeVector genericArgs; BfType* type = NULL; BfTypeDef* typeDef = ResolveGenericInstanceDef(genericTypeInstRef, &type, resolveFlags); - if(ambiguousTypeDef != NULL) - ShowAmbiguousTypeError(typeRef, typeDef, ambiguousTypeDef); if (typeDef == NULL) { - Fail("Unable to resolve type", typeRef); + Fail("Unable to resolve type", typeRef); mContext->mResolvedTypes.RemoveEntry(resolvedEntry); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } - BfTypeInstance* outerTypeInstance = mCurTypeInstance; - - auto outerType = typeDef->mOuterType; + BfTypeInstance* outerTypeInstance = NULL; BfTypeDef* commonOuterType = NULL; - int startDefGenericParamIdx = 0; - commonOuterType = BfResolvedTypeSet::FindRootCommonOuterType(outerType, &lookupCtx, outerTypeInstance); + + if (outerTypeRef != NULL) + { + BfType* outerType = lookupCtx.GetCachedResolvedType(outerTypeRef); + if (outerType != NULL) + { + outerTypeInstance = outerType->ToTypeInstance(); + commonOuterType = outerTypeInstance->mTypeDef; + } + } + else + { + outerTypeInstance = mCurTypeInstance; + auto outerType = typeDef->mOuterType; + commonOuterType = BfResolvedTypeSet::FindRootCommonOuterType(outerType, &lookupCtx, outerTypeInstance); + } + if ((commonOuterType) && (outerTypeInstance->IsGenericTypeInstance())) { startDefGenericParamIdx = (int)commonOuterType->mGenericParamDefs.size(); @@ -10936,7 +10961,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->GetGenericDepth() + 1); genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg); - genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef); genericParamIdx++; } diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 87d8169c..dfc93045 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -2492,7 +2492,6 @@ bool BfTypeInstance::IsTypeMemberIncluded(BfTypeDef* typeDef, BfTypeDef* activeT void BfGenericTypeInfo::ReportMemory(MemReporter* memReporter) { memReporter->Add(sizeof(BfGenericTypeInfo)); - memReporter->AddVec(mTypeGenericArgumentRefs, false); memReporter->AddVec(mTypeGenericArguments, false); memReporter->AddVec(mGenericParams, false); memReporter->AddVec(mProjectsReferenced, false); @@ -3133,20 +3132,11 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef, int void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hashVal, int hashSeed) { - if (auto elementedTypeRef = BfNodeDynCast(typeRef)) - { - HashGenericArguments(elementedTypeRef->mElementType, ctx, hashVal, hashSeed); - } - else if (auto qualifiedTypeRef = BfNodeDynCast(typeRef)) - { - HashGenericArguments(qualifiedTypeRef->mLeft, ctx, hashVal, hashSeed); - } - if (auto genericTypeRef = BfNodeDynCast(typeRef)) { for (int genericIdx = 0; genericIdx < BF_MAX(genericTypeRef->mGenericArguments.mSize, genericTypeRef->mCommas.mSize + 1); genericIdx++) { - bool allowUnboundGeneric = ((ctx->mResolveFlags & BfResolveTypeRefFlag_AllowUnboundGeneric) != 0) && (typeRef == ctx->mRootTypeRef); + bool allowUnboundGeneric = ((ctx->mResolveFlags & BfResolveTypeRefFlag_AllowUnboundGeneric) != 0) && (hashSeed == 0); BfAstNode* genericArgTypeRef = NULL; if (genericIdx < genericTypeRef->mGenericArguments.mSize) @@ -3351,35 +3341,80 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa } } } + + bool fullyQualified = false; + int hashVal = elementTypeDef->mHash; + + BfTypeInstance* outerType = NULL; - int hashVal; - /*if (type != NULL) + if (genericInstTypeRef->ToString() == "ClassA.AliasA6") { - hashVal = Hash(type, ctx); + NOP; } - else */ - { - - hashVal = elementTypeDef->mHash; + int checkIdx = 0; + auto checkTypeRef = genericInstTypeRef->mElementType; + while (checkTypeRef != NULL) + { + checkIdx++; + if (checkIdx >= 2) + { + fullyQualified = true; + if ((elementTypeDef->mOuterType != NULL) && (!elementTypeDef->mOuterType->mGenericParamDefs.IsEmpty())) + { + auto resolvedType = ctx->mModule->ResolveTypeRef(checkTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(ctx->mResolveFlags | BfResolveTypeRefFlag_IgnoreLookupError)); + if (resolvedType == NULL) + { + ctx->mFailed = true; + return hashVal; + } + ctx->SetCachedResolvedType(checkTypeRef, resolvedType); + outerType = resolvedType->ToTypeInstance(); + } + break; + } + + if (auto elementedTypeRef = BfNodeDynCast(checkTypeRef)) + { + checkTypeRef = elementedTypeRef->mElementType; + continue; + } + + if (auto qualifiedTypeRef = BfNodeDynCast(checkTypeRef)) + { + checkTypeRef = qualifiedTypeRef->mLeft; + continue; + } + break; } - // Do we need to add generic arguments from an in-context outer class? - if ((elementTypeDef->mOuterType != NULL) && (ctx->mModule->mCurTypeInstance != NULL)) - { - BfTypeInstance* checkTypeInstance = ctx->mModule->mCurTypeInstance; - BfTypeDef* commonOuterType; - if (typeRef == ctx->mRootTypeRef) - commonOuterType = FindRootCommonOuterType(elementTypeDef->mOuterType, ctx, checkTypeInstance); - else - commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, elementTypeDef->mOuterType); - - if ((commonOuterType != NULL) && (checkTypeInstance->IsGenericTypeInstance())) + if (fullyQualified) + { + if (outerType != NULL) { - auto parentTypeInstance = checkTypeInstance; - int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); - for (int i = 0; i < numParentGenericParams; i++) - hashVal = HASH_MIX(hashVal, Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1)); + for (auto genericArg : outerType->mGenericTypeInfo->mTypeGenericArguments) + hashVal = HASH_MIX(hashVal, Hash(genericArg, ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1)); + } + } + else + { + // Do we need to add generic arguments from an in-context outer class? + if ((elementTypeDef->mOuterType != NULL) && (ctx->mModule->mCurTypeInstance != NULL)) + { + BfTypeInstance* checkTypeInstance = ctx->mModule->mCurTypeInstance; + BfTypeDef* commonOuterType; + if (typeRef == ctx->mRootTypeRef) + commonOuterType = FindRootCommonOuterType(elementTypeDef->mOuterType, ctx, checkTypeInstance); + else + commonOuterType = ctx->mModule->FindCommonOuterType(ctx->mModule->mCurTypeInstance->mTypeDef, elementTypeDef->mOuterType); + + if ((commonOuterType != NULL) && (checkTypeInstance->IsGenericTypeInstance())) + { + auto parentTypeInstance = checkTypeInstance; + int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); + for (int i = 0; i < numParentGenericParams; i++) + hashVal = HASH_MIX(hashVal, Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1)); + } } } @@ -4056,21 +4091,24 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) return 0; } -bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset) +bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset, bool skipElement) { //BP_ZONE("BfResolvedTypeSet::GenericTypeEquals"); - if (auto elementedTypeRef = BfNodeDynCast(rhs)) + if (!skipElement) { - if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, elementedTypeRef->mElementType, ctx, genericParamOffset)) - return false; - //_GetTypeRefs(elementedTypeRef->mElementType); - } - else if (auto qualifiedTypeRef = BfNodeDynCastExact(rhs)) - { - //_GetTypeRefs(qualifiedTypeRef->mLeft); - if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, qualifiedTypeRef->mLeft, ctx, genericParamOffset)) - return false; + if (auto elementedTypeRef = BfNodeDynCast(rhs)) + { + if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, elementedTypeRef->mElementType, ctx, genericParamOffset)) + return false; + //_GetTypeRefs(elementedTypeRef->mElementType); + } + else if (auto qualifiedTypeRef = BfNodeDynCastExact(rhs)) + { + //_GetTypeRefs(qualifiedTypeRef->mLeft); + if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, qualifiedTypeRef->mLeft, ctx, genericParamOffset)) + return false; + } } if (auto genericTypeRef = BfNodeDynCastExact(rhs)) @@ -4122,66 +4160,123 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx) { - BfTypeInstance* rootOuterTypeInstance = ctx->mModule->mCurTypeInstance; - if ((rhsTypeDef == ctx->mRootTypeDef) && (ctx->mRootOuterTypeInstance != NULL)) - rootOuterTypeInstance = ctx->mRootOuterTypeInstance; + int genericParamOffset = 0; + bool isFullyQualified = false; + BfTypeInstance* outerType = NULL; - auto rhsGenericTypeInstRef = BfNodeDynCastExact(rhs); - if (rhsGenericTypeInstRef == NULL) + if (auto genericInstTypeRef = BfNodeDynCast(rhs)) { - if (auto rhsNullableTypeRef = BfNodeDynCastExact(rhs)) + int checkIdx = 0; + auto checkTypeRef = genericInstTypeRef->mElementType; + while (checkTypeRef != NULL) { - if (rhsNullableTypeRef != NULL) + checkIdx++; + if (checkIdx >= 2) { - if (lhsGenericType->mTypeDef != ctx->mModule->mContext->mCompiler->mNullableTypeDef) - return false; + isFullyQualified = true; - auto rhsElemType = ctx->mModule->ResolveTypeRef(rhsNullableTypeRef->mElementType, BfPopulateType_Identity, ctx->mResolveFlags); - return lhsGenericType->mGenericTypeInfo->mTypeGenericArguments[0] == rhsElemType; + BfType* checkType = ctx->GetCachedResolvedType(checkTypeRef); + if (checkType != NULL) + outerType = checkType->ToTypeInstance(); + + if (outerType != NULL) + { + BfTypeInstance* lhsCheckType = lhsGenericType; + while (lhsCheckType->mTypeDef->mNestDepth > outerType->mTypeDef->mNestDepth) + { + lhsCheckType = ctx->mModule->GetOuterType(lhsCheckType); + } + if (lhsCheckType != outerType) + return false; + + if (outerType->mGenericTypeInfo != NULL) + genericParamOffset = (int)outerType->mGenericTypeInfo->mTypeGenericArguments.mSize; + } + + break; } - } - if ((rhsTypeDef != NULL) && (rootOuterTypeInstance != NULL)) - { - // See if we're referring to an non-generic inner type where the outer type is generic - if (lhsGenericType->mTypeDef->GetDefinition() != rhsTypeDef->GetDefinition()) - return false; - - BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(rootOuterTypeInstance->mTypeDef, rhsTypeDef->mOuterType); - if (commonOuterType != NULL) + if (auto elementedTypeRef = BfNodeDynCast(checkTypeRef)) { - BfTypeInstance* checkTypeInstance = rootOuterTypeInstance; - if (checkTypeInstance->IsBoxed()) - checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance(); - BF_ASSERT(checkTypeInstance->IsGenericTypeInstance()); - int numParentGenericParams = (int) commonOuterType->mGenericParamDefs.size(); - auto curTypeInstance = (BfTypeInstance*)checkTypeInstance; - if (lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size() != numParentGenericParams) - return false; - for (int i = 0; i < (int) numParentGenericParams; i++) - if ((*lhsTypeGenericArguments)[i] != curTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]) - return false; - return true; + checkTypeRef = elementedTypeRef->mElementType; + continue; } - } - if (auto rhsQualifiedTypeRef = BfNodeDynCastExact(rhs)) - { - auto rhsRightType = ctx->mModule->ResolveTypeRef(rhs, BfPopulateType_Identity, ctx->mResolveFlags); - return rhsRightType == lhsGenericType; + if (auto qualifiedTypeRef = BfNodeDynCast(checkTypeRef)) + { + checkTypeRef = qualifiedTypeRef->mLeft; + continue; + } + break; } - - return false; } + BfTypeInstance* rootOuterTypeInstance = NULL; + auto rhsGenericTypeInstRef = BfNodeDynCastExact(rhs); + + if (!isFullyQualified) + { + rootOuterTypeInstance = ctx->mModule->mCurTypeInstance; + if ((rhsTypeDef == ctx->mRootTypeDef) && (ctx->mRootOuterTypeInstance != NULL)) + rootOuterTypeInstance = ctx->mRootOuterTypeInstance; + + if (rhsGenericTypeInstRef == NULL) + { + if (auto rhsNullableTypeRef = BfNodeDynCastExact(rhs)) + { + if (rhsNullableTypeRef != NULL) + { + if (lhsGenericType->mTypeDef != ctx->mModule->mContext->mCompiler->mNullableTypeDef) + return false; + + auto rhsElemType = ctx->mModule->ResolveTypeRef(rhsNullableTypeRef->mElementType, BfPopulateType_Identity, ctx->mResolveFlags); + return lhsGenericType->mGenericTypeInfo->mTypeGenericArguments[0] == rhsElemType; + } + } + + if ((rhsTypeDef != NULL) && (rootOuterTypeInstance != NULL)) + { + // See if we're referring to an non-generic inner type where the outer type is generic + if (lhsGenericType->mTypeDef->GetDefinition() != rhsTypeDef->GetDefinition()) + return false; + + BfTypeDef* commonOuterType = ctx->mModule->FindCommonOuterType(rootOuterTypeInstance->mTypeDef, rhsTypeDef->mOuterType); + if (commonOuterType != NULL) + { + BfTypeInstance* checkTypeInstance = rootOuterTypeInstance; + if (checkTypeInstance->IsBoxed()) + checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance(); + BF_ASSERT(checkTypeInstance->IsGenericTypeInstance()); + int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); + auto curTypeInstance = (BfTypeInstance*)checkTypeInstance; + if (lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size() != numParentGenericParams) + return false; + for (int i = 0; i < (int)numParentGenericParams; i++) + if ((*lhsTypeGenericArguments)[i] != curTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]) + return false; + return true; + } + } + + if (auto rhsQualifiedTypeRef = BfNodeDynCastExact(rhs)) + { + auto rhsRightType = ctx->mModule->ResolveTypeRef(rhs, BfPopulateType_Identity, ctx->mResolveFlags); + return rhsRightType == lhsGenericType; + } + + return false; + } + } + + if (rhsGenericTypeInstRef == NULL) + return true; + BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(rhsGenericTypeInstRef, NULL, ctx->mResolveFlags); if (elementTypeDef == NULL) return false; if (elementTypeDef->GetDefinition() != lhsGenericType->mTypeDef->GetDefinition()) return false; - int genericParamOffset = 0; - // Do we need to add generic arguments from an in-context outer class? if ((elementTypeDef->mOuterType != NULL) && (rootOuterTypeInstance != NULL) && (rootOuterTypeInstance->IsGenericTypeInstance())) { @@ -4199,7 +4294,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType } } - if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, rhs, ctx, genericParamOffset)) + if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, rhs, ctx, genericParamOffset, isFullyQualified)) return false; return genericParamOffset == (int)lhsTypeGenericArguments->size(); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index fc3ad699..110e34ed 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -1861,7 +1861,6 @@ class BfGenericTypeInfo public: typedef Array GenericParamsVector; - Array mTypeGenericArgumentRefs; BfTypeVector mTypeGenericArguments; GenericParamsVector mGenericParams; BfGenericExtensionInfo* mGenericExtensionInfo; @@ -2635,7 +2634,7 @@ public: public: static BfTypeDef* FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outCheckTypeInstance); static BfVariant EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType); - static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset); + static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset, bool skipElement = false); static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx); static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash, int hashSeed); static int DoHash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed); diff --git a/IDEHelper/Tests/src/Generics.bf b/IDEHelper/Tests/src/Generics.bf index af72a40c..d6c88192 100644 --- a/IDEHelper/Tests/src/Generics.bf +++ b/IDEHelper/Tests/src/Generics.bf @@ -2,6 +2,7 @@ using System; using System.Collections; +using System.Reflection; namespace LibA { @@ -341,6 +342,72 @@ namespace Tests } + class ClassH + { + public class Inner + { + + } + } + + class OuterB + { + public class Inner + { + public class MoreInner + { + public static Inner sVal; + public static Inner.MoreInner sVal2; + } + } + + public static Inner.MoreInner sVal; + } + + class OuterA + { + public typealias AliasA = OuterB; + public typealias AliasB = OuterB; + + public class Inner + { + public class MoreInner + { + public static Inner sVal; + public static Inner.MoreInner sVal2; + } + + public class MoreInnerB + { + + } + } + + public class InnerB + { + + } + + public static OuterA.Inner sVal; + public static Inner sVal2; + public static AliasA.Inner sVal3; + public static OuterA.InnerB sVal4; + public static Inner.MoreInnerB sVal5; + } + + class OuterC + { + static void Do() + { + OuterA.AliasA.Inner val1 = scope OuterB.Inner(); + OuterA.AliasB.Inner val1b = scope OuterB.Inner(); + OuterA.AliasA.Inner.MoreInner val2 = scope OuterB.Inner.MoreInner(); + OuterB.Inner.MoreInner val3 = OuterB.sVal; + System.Collections.Dictionary dict; + OuterA.Inner.MoreInnerB val4 = OuterA.sVal5; + } + } + [Test] public static void TestBasics() { @@ -415,6 +482,11 @@ namespace Tests Test.Assert(Conv(12.34f) == 12); Test.Assert(Conv(12.34f) == 12); //MethodH(scope List()); + + var specializedType = typeof(Dictionary.Enumerator) as SpecializedGenericType; + Test.Assert(specializedType.UnspecializedType == typeof(Dictionary<,>.Enumerator)); + var t = typeof(Array2<>); + t = typeof(ClassH<,>.Inner<>); } } @@ -487,9 +559,6 @@ namespace Tests b = Foo.value > val; b = Foo.Inner.value2 < 1.2f; b = Foo.Inner.value2 > 2.3f; - - var t = typeof(Array2<>); - t = typeof(Dictionary<,>.Enumerator); } } }