mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 12:02:21 +02:00
Overhaul generic type reference lookup
This commit is contained in:
parent
e5f280de32
commit
fefed0948e
5 changed files with 304 additions and 118 deletions
|
@ -1127,7 +1127,6 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
|
||||||
if (typeInst->IsGenericTypeInstance())
|
if (typeInst->IsGenericTypeInstance())
|
||||||
{
|
{
|
||||||
auto genericTypeInstance = (BfTypeInstance*)typeInst;
|
auto genericTypeInstance = (BfTypeInstance*)typeInst;
|
||||||
genericTypeInstance->mGenericTypeInfo->mTypeGenericArgumentRefs.Clear();
|
|
||||||
for (auto genericParam : genericTypeInstance->mGenericTypeInfo->mGenericParams)
|
for (auto genericParam : genericTypeInstance->mGenericTypeInfo->mGenericParams)
|
||||||
genericParam->Release();
|
genericParam->Release();
|
||||||
genericTypeInstance->mGenericTypeInfo->mInitializedGenericParams = false;
|
genericTypeInstance->mGenericTypeInfo->mInitializedGenericParams = false;
|
||||||
|
|
|
@ -7901,7 +7901,7 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic
|
||||||
if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
|
if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
|
||||||
{
|
{
|
||||||
BfAutoParentNodeEntry autoParentNodeEntry(this, genericTypeRef);
|
BfAutoParentNodeEntry autoParentNodeEntry(this, genericTypeRef);
|
||||||
auto type = ResolveTypeRef(qualifiedTypeRef, BfPopulateType_TypeDef, BfResolveTypeRefFlag_None, numGenericParams);
|
auto type = ResolveTypeRef(qualifiedTypeRef, BfPopulateType_TypeDef, resolveFlags, numGenericParams);
|
||||||
if (type == NULL)
|
if (type == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (outType != NULL)
|
if (outType != NULL)
|
||||||
|
@ -8946,7 +8946,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
||||||
if ((populateType > BfPopulateType_IdentityNoRemapAlias) && (!ResolveTypeResult_Validate(typeRef, resolvedTypeRef)))
|
if ((populateType > BfPopulateType_IdentityNoRemapAlias) && (!ResolveTypeResult_Validate(typeRef, resolvedTypeRef)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (populateType != BfPopulateType_IdentityNoRemapAlias)
|
if ((populateType != BfPopulateType_TypeDef) && (populateType != BfPopulateType_IdentityNoRemapAlias))
|
||||||
{
|
{
|
||||||
while ((resolvedTypeRef != NULL) && (resolvedTypeRef->IsTypeAlias()))
|
while ((resolvedTypeRef != NULL) && (resolvedTypeRef->IsTypeAlias()))
|
||||||
{
|
{
|
||||||
|
@ -10789,36 +10789,48 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
}
|
}
|
||||||
else if (auto genericTypeInstRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
|
else if (auto genericTypeInstRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
|
||||||
{
|
{
|
||||||
int wantNumGenericParams = genericTypeInstRef->GetGenericArgCount();
|
BfTypeReference* outerTypeRef = NULL;
|
||||||
BfTypeDef* ambiguousTypeDef = NULL;
|
|
||||||
|
|
||||||
Array<BfAstNode*> genericArguments;
|
Array<BfAstNode*> genericArguments;
|
||||||
std::function<void(BfTypeReference*)> _GetTypeRefs = [&](BfTypeReference* typeRef)
|
|
||||||
|
BfTypeReference* checkTypeRef = genericTypeInstRef;
|
||||||
|
int checkIdx = 0;
|
||||||
|
|
||||||
|
while (checkTypeRef != NULL)
|
||||||
{
|
{
|
||||||
//TODO:GENERICS
|
checkIdx++;
|
||||||
if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
|
if (checkIdx >= 3)
|
||||||
{
|
{
|
||||||
_GetTypeRefs(elementedTypeRef->mElementType);
|
outerTypeRef = checkTypeRef;
|
||||||
}
|
break;
|
||||||
else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
|
|
||||||
{
|
|
||||||
_GetTypeRefs(qualifiedTypeRef->mLeft);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
|
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(checkTypeRef))
|
||||||
{
|
{
|
||||||
for (auto genericArg : genericTypeRef->mGenericArguments)
|
for (auto genericArg : genericTypeRef->mGenericArguments)
|
||||||
genericArguments.push_back(genericArg);
|
genericArguments.push_back(genericArg);
|
||||||
|
checkTypeRef = genericTypeRef->mElementType;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(checkTypeRef))
|
||||||
|
{
|
||||||
|
checkTypeRef = elementedTypeRef->mElementType;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkTypeRef))
|
||||||
|
{
|
||||||
|
checkTypeRef = qualifiedTypeRef->mLeft;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
_GetTypeRefs(genericTypeInstRef);
|
|
||||||
|
|
||||||
BfTypeVector genericArgs;
|
BfTypeVector genericArgs;
|
||||||
|
|
||||||
BfType* type = NULL;
|
BfType* type = NULL;
|
||||||
BfTypeDef* typeDef = ResolveGenericInstanceDef(genericTypeInstRef, &type, resolveFlags);
|
BfTypeDef* typeDef = ResolveGenericInstanceDef(genericTypeInstRef, &type, resolveFlags);
|
||||||
if(ambiguousTypeDef != NULL)
|
|
||||||
ShowAmbiguousTypeError(typeRef, typeDef, ambiguousTypeDef);
|
|
||||||
if (typeDef == NULL)
|
if (typeDef == NULL)
|
||||||
{
|
{
|
||||||
Fail("Unable to resolve type", typeRef);
|
Fail("Unable to resolve type", typeRef);
|
||||||
|
@ -10826,13 +10838,26 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypeInstance* outerTypeInstance = mCurTypeInstance;
|
BfTypeInstance* outerTypeInstance = NULL;
|
||||||
|
|
||||||
auto outerType = typeDef->mOuterType;
|
|
||||||
BfTypeDef* commonOuterType = NULL;
|
BfTypeDef* commonOuterType = NULL;
|
||||||
|
|
||||||
int startDefGenericParamIdx = 0;
|
int startDefGenericParamIdx = 0;
|
||||||
|
|
||||||
|
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);
|
commonOuterType = BfResolvedTypeSet::FindRootCommonOuterType(outerType, &lookupCtx, outerTypeInstance);
|
||||||
|
}
|
||||||
|
|
||||||
if ((commonOuterType) && (outerTypeInstance->IsGenericTypeInstance()))
|
if ((commonOuterType) && (outerTypeInstance->IsGenericTypeInstance()))
|
||||||
{
|
{
|
||||||
startDefGenericParamIdx = (int)commonOuterType->mGenericParamDefs.size();
|
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->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->GetGenericDepth() + 1);
|
||||||
genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
|
genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
|
||||||
genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef);
|
|
||||||
|
|
||||||
genericParamIdx++;
|
genericParamIdx++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2492,7 +2492,6 @@ bool BfTypeInstance::IsTypeMemberIncluded(BfTypeDef* typeDef, BfTypeDef* activeT
|
||||||
void BfGenericTypeInfo::ReportMemory(MemReporter* memReporter)
|
void BfGenericTypeInfo::ReportMemory(MemReporter* memReporter)
|
||||||
{
|
{
|
||||||
memReporter->Add(sizeof(BfGenericTypeInfo));
|
memReporter->Add(sizeof(BfGenericTypeInfo));
|
||||||
memReporter->AddVec(mTypeGenericArgumentRefs, false);
|
|
||||||
memReporter->AddVec(mTypeGenericArguments, false);
|
memReporter->AddVec(mTypeGenericArguments, false);
|
||||||
memReporter->AddVec(mGenericParams, false);
|
memReporter->AddVec(mGenericParams, false);
|
||||||
memReporter->AddVec(mProjectsReferenced, 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)
|
void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hashVal, int hashSeed)
|
||||||
{
|
{
|
||||||
if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
|
|
||||||
{
|
|
||||||
HashGenericArguments(elementedTypeRef->mElementType, ctx, hashVal, hashSeed);
|
|
||||||
}
|
|
||||||
else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
|
|
||||||
{
|
|
||||||
HashGenericArguments(qualifiedTypeRef->mLeft, ctx, hashVal, hashSeed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
|
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
|
||||||
{
|
{
|
||||||
for (int genericIdx = 0; genericIdx < BF_MAX(genericTypeRef->mGenericArguments.mSize, genericTypeRef->mCommas.mSize + 1); genericIdx++)
|
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;
|
BfAstNode* genericArgTypeRef = NULL;
|
||||||
if (genericIdx < genericTypeRef->mGenericArguments.mSize)
|
if (genericIdx < genericTypeRef->mGenericArguments.mSize)
|
||||||
|
@ -3352,18 +3342,62 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int hashVal;
|
bool fullyQualified = false;
|
||||||
/*if (type != NULL)
|
int hashVal = elementTypeDef->mHash;
|
||||||
{
|
|
||||||
hashVal = Hash(type, ctx);
|
|
||||||
}
|
|
||||||
else */
|
|
||||||
{
|
|
||||||
|
|
||||||
|
BfTypeInstance* outerType = NULL;
|
||||||
|
|
||||||
hashVal = elementTypeDef->mHash;
|
if (genericInstTypeRef->ToString() == "ClassA<T>.AliasA6<float>")
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<BfElementedTypeRef>(checkTypeRef))
|
||||||
|
{
|
||||||
|
checkTypeRef = elementedTypeRef->mElementType;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkTypeRef))
|
||||||
|
{
|
||||||
|
checkTypeRef = qualifiedTypeRef->mLeft;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fullyQualified)
|
||||||
|
{
|
||||||
|
if (outerType != NULL)
|
||||||
|
{
|
||||||
|
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?
|
// Do we need to add generic arguments from an in-context outer class?
|
||||||
if ((elementTypeDef->mOuterType != NULL) && (ctx->mModule->mCurTypeInstance != NULL))
|
if ((elementTypeDef->mOuterType != NULL) && (ctx->mModule->mCurTypeInstance != NULL))
|
||||||
{
|
{
|
||||||
|
@ -3382,6 +3416,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa
|
||||||
hashVal = HASH_MIX(hashVal, Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1));
|
hashVal = HASH_MIX(hashVal, Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HashGenericArguments(genericInstTypeRef, ctx, hashVal, hashSeed);
|
HashGenericArguments(genericInstTypeRef, ctx, hashVal, hashSeed);
|
||||||
|
|
||||||
|
@ -4056,10 +4091,12 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
|
||||||
return 0;
|
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");
|
//BP_ZONE("BfResolvedTypeSet::GenericTypeEquals");
|
||||||
|
|
||||||
|
if (!skipElement)
|
||||||
|
{
|
||||||
if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(rhs))
|
if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(rhs))
|
||||||
{
|
{
|
||||||
if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, elementedTypeRef->mElementType, ctx, genericParamOffset))
|
if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, elementedTypeRef->mElementType, ctx, genericParamOffset))
|
||||||
|
@ -4072,6 +4109,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType
|
||||||
if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, qualifiedTypeRef->mLeft, ctx, genericParamOffset))
|
if (!GenericTypeEquals(lhsGenericType, lhsTypeGenericArguments, qualifiedTypeRef->mLeft, ctx, genericParamOffset))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (auto genericTypeRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(rhs))
|
if (auto genericTypeRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(rhs))
|
||||||
{
|
{
|
||||||
|
@ -4122,11 +4160,66 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType
|
||||||
|
|
||||||
bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx)
|
bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx)
|
||||||
{
|
{
|
||||||
BfTypeInstance* rootOuterTypeInstance = ctx->mModule->mCurTypeInstance;
|
int genericParamOffset = 0;
|
||||||
|
bool isFullyQualified = false;
|
||||||
|
BfTypeInstance* outerType = NULL;
|
||||||
|
|
||||||
|
if (auto genericInstTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(rhs))
|
||||||
|
{
|
||||||
|
int checkIdx = 0;
|
||||||
|
auto checkTypeRef = genericInstTypeRef->mElementType;
|
||||||
|
while (checkTypeRef != NULL)
|
||||||
|
{
|
||||||
|
checkIdx++;
|
||||||
|
if (checkIdx >= 2)
|
||||||
|
{
|
||||||
|
isFullyQualified = true;
|
||||||
|
|
||||||
|
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 (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(checkTypeRef))
|
||||||
|
{
|
||||||
|
checkTypeRef = elementedTypeRef->mElementType;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(checkTypeRef))
|
||||||
|
{
|
||||||
|
checkTypeRef = qualifiedTypeRef->mLeft;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BfTypeInstance* rootOuterTypeInstance = NULL;
|
||||||
|
auto rhsGenericTypeInstRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(rhs);
|
||||||
|
|
||||||
|
if (!isFullyQualified)
|
||||||
|
{
|
||||||
|
rootOuterTypeInstance = ctx->mModule->mCurTypeInstance;
|
||||||
if ((rhsTypeDef == ctx->mRootTypeDef) && (ctx->mRootOuterTypeInstance != NULL))
|
if ((rhsTypeDef == ctx->mRootTypeDef) && (ctx->mRootOuterTypeInstance != NULL))
|
||||||
rootOuterTypeInstance = ctx->mRootOuterTypeInstance;
|
rootOuterTypeInstance = ctx->mRootOuterTypeInstance;
|
||||||
|
|
||||||
auto rhsGenericTypeInstRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(rhs);
|
|
||||||
if (rhsGenericTypeInstRef == NULL)
|
if (rhsGenericTypeInstRef == NULL)
|
||||||
{
|
{
|
||||||
if (auto rhsNullableTypeRef = BfNodeDynCastExact<BfNullableTypeRef>(rhs))
|
if (auto rhsNullableTypeRef = BfNodeDynCastExact<BfNullableTypeRef>(rhs))
|
||||||
|
@ -4154,11 +4247,11 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType
|
||||||
if (checkTypeInstance->IsBoxed())
|
if (checkTypeInstance->IsBoxed())
|
||||||
checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance();
|
checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance();
|
||||||
BF_ASSERT(checkTypeInstance->IsGenericTypeInstance());
|
BF_ASSERT(checkTypeInstance->IsGenericTypeInstance());
|
||||||
int numParentGenericParams = (int) commonOuterType->mGenericParamDefs.size();
|
int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
|
||||||
auto curTypeInstance = (BfTypeInstance*)checkTypeInstance;
|
auto curTypeInstance = (BfTypeInstance*)checkTypeInstance;
|
||||||
if (lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size() != numParentGenericParams)
|
if (lhsGenericType->mGenericTypeInfo->mTypeGenericArguments.size() != numParentGenericParams)
|
||||||
return false;
|
return false;
|
||||||
for (int i = 0; i < (int) numParentGenericParams; i++)
|
for (int i = 0; i < (int)numParentGenericParams; i++)
|
||||||
if ((*lhsTypeGenericArguments)[i] != curTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i])
|
if ((*lhsTypeGenericArguments)[i] != curTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i])
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -4173,6 +4266,10 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rhsGenericTypeInstRef == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(rhsGenericTypeInstRef, NULL, ctx->mResolveFlags);
|
BfTypeDef* elementTypeDef = ctx->mModule->ResolveGenericInstanceDef(rhsGenericTypeInstRef, NULL, ctx->mResolveFlags);
|
||||||
if (elementTypeDef == NULL)
|
if (elementTypeDef == NULL)
|
||||||
|
@ -4180,8 +4277,6 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType
|
||||||
if (elementTypeDef->GetDefinition() != lhsGenericType->mTypeDef->GetDefinition())
|
if (elementTypeDef->GetDefinition() != lhsGenericType->mTypeDef->GetDefinition())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int genericParamOffset = 0;
|
|
||||||
|
|
||||||
// Do we need to add generic arguments from an in-context outer class?
|
// Do we need to add generic arguments from an in-context outer class?
|
||||||
if ((elementTypeDef->mOuterType != NULL) && (rootOuterTypeInstance != NULL) && (rootOuterTypeInstance->IsGenericTypeInstance()))
|
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 false;
|
||||||
|
|
||||||
return genericParamOffset == (int)lhsTypeGenericArguments->size();
|
return genericParamOffset == (int)lhsTypeGenericArguments->size();
|
||||||
|
|
|
@ -1861,7 +1861,6 @@ class BfGenericTypeInfo
|
||||||
public:
|
public:
|
||||||
typedef Array<BfGenericTypeParamInstance*> GenericParamsVector;
|
typedef Array<BfGenericTypeParamInstance*> GenericParamsVector;
|
||||||
|
|
||||||
Array<BfAstNode*> mTypeGenericArgumentRefs;
|
|
||||||
BfTypeVector mTypeGenericArguments;
|
BfTypeVector mTypeGenericArguments;
|
||||||
GenericParamsVector mGenericParams;
|
GenericParamsVector mGenericParams;
|
||||||
BfGenericExtensionInfo* mGenericExtensionInfo;
|
BfGenericExtensionInfo* mGenericExtensionInfo;
|
||||||
|
@ -2635,7 +2634,7 @@ public:
|
||||||
public:
|
public:
|
||||||
static BfTypeDef* FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outCheckTypeInstance);
|
static BfTypeDef* FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outCheckTypeInstance);
|
||||||
static BfVariant EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType);
|
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 bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx);
|
||||||
static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash, int hashSeed);
|
static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash, int hashSeed);
|
||||||
static int DoHash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed);
|
static int DoHash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace LibA
|
namespace LibA
|
||||||
{
|
{
|
||||||
|
@ -341,6 +342,72 @@ namespace Tests
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ClassH<T, T2>
|
||||||
|
{
|
||||||
|
public class Inner<T3>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OuterB<T>
|
||||||
|
{
|
||||||
|
public class Inner<T2>
|
||||||
|
{
|
||||||
|
public class MoreInner<T3>
|
||||||
|
{
|
||||||
|
public static Inner<int8> sVal;
|
||||||
|
public static Inner<int8>.MoreInner<int16> sVal2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Inner<T>.MoreInner<T> sVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
class OuterA<T, T2>
|
||||||
|
{
|
||||||
|
public typealias AliasA = OuterB<uint8>;
|
||||||
|
public typealias AliasB<T3> = OuterB<T3>;
|
||||||
|
|
||||||
|
public class Inner<T3>
|
||||||
|
{
|
||||||
|
public class MoreInner<T4>
|
||||||
|
{
|
||||||
|
public static Inner<int8> sVal;
|
||||||
|
public static Inner<int8>.MoreInner<int16> sVal2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MoreInnerB
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InnerB
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OuterA<int,float>.Inner<int16> sVal;
|
||||||
|
public static Inner<int16> sVal2;
|
||||||
|
public static AliasA.Inner<int16> sVal3;
|
||||||
|
public static OuterA<T, T2>.InnerB sVal4;
|
||||||
|
public static Inner<int16>.MoreInnerB sVal5;
|
||||||
|
}
|
||||||
|
|
||||||
|
class OuterC
|
||||||
|
{
|
||||||
|
static void Do()
|
||||||
|
{
|
||||||
|
OuterA<int8, int16>.AliasA.Inner<int32> val1 = scope OuterB<uint8>.Inner<int32>();
|
||||||
|
OuterA<int8, int16>.AliasB<uint8>.Inner<int32> val1b = scope OuterB<uint8>.Inner<int32>();
|
||||||
|
OuterA<int8, int16>.AliasA.Inner<int32>.MoreInner<uint32> val2 = scope OuterB<uint8>.Inner<int32>.MoreInner<uint32>();
|
||||||
|
OuterB<int8>.Inner<int8>.MoreInner<int8> val3 = OuterB<int8>.sVal;
|
||||||
|
System.Collections.Dictionary<int, float> dict;
|
||||||
|
OuterA<int8, int16>.Inner<int16>.MoreInnerB val4 = OuterA<int8, int16>.sVal5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -415,6 +482,11 @@ namespace Tests
|
||||||
Test.Assert(Conv<int...>(12.34f) == 12);
|
Test.Assert(Conv<int...>(12.34f) == 12);
|
||||||
Test.Assert(Conv<int,?>(12.34f) == 12);
|
Test.Assert(Conv<int,?>(12.34f) == 12);
|
||||||
//MethodH(scope List<int>());
|
//MethodH(scope List<int>());
|
||||||
|
|
||||||
|
var specializedType = typeof(Dictionary<int, float>.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<int>.value > val;
|
b = Foo<int>.value > val;
|
||||||
b = Foo<int>.Inner<float>.value2 < 1.2f;
|
b = Foo<int>.Inner<float>.value2 < 1.2f;
|
||||||
b = Foo<int>.Inner<float>.value2 > 2.3f;
|
b = Foo<int>.Inner<float>.value2 > 2.3f;
|
||||||
|
|
||||||
var t = typeof(Array2<>);
|
|
||||||
t = typeof(Dictionary<,>.Enumerator);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue