public AggregateType GetAggregate(AggregateSymbol agg, AggregateType atsOuter, TypeArray typeArgs)
{
Debug.Assert(agg.GetTypeManager() == this);
Debug.Assert(atsOuter == null || atsOuter.getAggregate() == agg.Parent, "");
if (typeArgs == null)
{
typeArgs = BSYMMGR.EmptyTypeArray();
}
Debug.Assert(agg.GetTypeVars().Count == typeArgs.Count);
Name name = _BSymmgr.GetNameFromPtrs(typeArgs, atsOuter);
Debug.Assert(name != null);
AggregateType pAggregate = _typeTable.LookupAggregate(name, agg);
if (pAggregate == null)
{
pAggregate = _typeFactory.CreateAggregateType(
name,
agg,
typeArgs,
atsOuter
);
Debug.Assert(!pAggregate.fConstraintsChecked && !pAggregate.fConstraintError);
pAggregate.SetErrors(false);
_typeTable.InsertAggregate(name, agg, pAggregate);
// If we have a generic type definition, then we need to set the
// base class to be our current base type, and use that to calculate
// our agg type and its base, then set it to be the generic version of the
// base type. This is because:
//
// Suppose we have Foo<T> : IFoo<T>
//
// Initially, the BaseType will be IFoo<Foo.T>, which gives us the substitution
// that we want to use for our agg type's base type. However, in the Symbol chain,
// we want the base type to be IFoo<IFoo.T>. Thats why we need to do this little trick.
//
// If we don't have a generic type definition, then we just need to set our base
// class. This is so that if we have a base type that's generic, we'll be
// getting the correctly instantiated base type.
var baseType = pAggregate.AssociatedSystemType?.BaseType;
if (baseType != null)
{
// Store the old base class.
AggregateType oldBaseType = agg.GetBaseClass();
agg.SetBaseClass(_symbolTable.GetCTypeFromType(baseType) as AggregateType);
pAggregate.GetBaseClass(); // Get the base type for the new agg type we're making.
agg.SetBaseClass(oldBaseType);
}
}
else
{
Debug.Assert(!pAggregate.HasErrors());
}
Debug.Assert(pAggregate.getAggregate() == agg);
Debug.Assert(pAggregate.GetTypeArgsThis() != null && pAggregate.GetTypeArgsAll() != null);
Debug.Assert(pAggregate.GetTypeArgsThis() == typeArgs);
return(pAggregate);
}