bool DefineBaseTypes ()
{
iface_exprs = ResolveBaseTypes (out base_type_expr);
if (partial_parts != null) {
iface_exprs = GetNormalPartialBases ();
}
var cycle = CheckRecursiveDefinition (this);
if (cycle != null) {
Report.SymbolRelatedToPreviousError (cycle);
if (this is Interface) {
Report.Error (529, Location,
"Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
GetSignatureForError (), cycle.GetSignatureForError ());
iface_exprs = null;
} else {
Report.Error (146, Location,
"Circular base class dependency involving `{0}' and `{1}'",
GetSignatureForError (), cycle.GetSignatureForError ());
base_type = null;
}
}
if (iface_exprs != null) {
foreach (TypeExpr iface in iface_exprs) {
// Prevents a crash, the interface might not have been resolved: 442144
if (iface == null)
continue;
var iface_type = iface.Type;
if (!spec.AddInterface (iface_type))
continue;
if (iface_type.IsGeneric && spec.Interfaces != null) {
foreach (var prev_iface in iface_exprs) {
if (prev_iface == iface)
break;
if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface.Type))
continue;
Report.Error (695, Location,
"`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
}
}
TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
// Ensure the base is always setup
var compiled_iface = iface_type.MemberDefinition as Interface;
if (compiled_iface != null) {
// TODO: Need DefineBaseType only
compiled_iface.DefineType ();
}
if (iface_type.Interfaces != null) {
var base_ifaces = new List<TypeSpec> (iface_type.Interfaces);
for (int i = 0; i < base_ifaces.Count; ++i) {
var ii_iface_type = base_ifaces[i];
if (spec.AddInterface (ii_iface_type)) {
TypeBuilder.AddInterfaceImplementation (ii_iface_type.GetMetaInfo ());
if (ii_iface_type.Interfaces != null)
base_ifaces.AddRange (ii_iface_type.Interfaces);
}
}
}
}
}
if (Kind == MemberKind.Interface) {
spec.BaseType = TypeManager.object_type;
return true;
}
if (base_type != null) {
spec.BaseType = base_type;
// Set base type after type creation
TypeBuilder.SetParent (base_type.GetMetaInfo ());
} else {
TypeBuilder.SetParent (null);
}
return true;
}