public override void ResolveWithCurrentContext(ResolveContext rc) { base.ResolveWithCurrentContext(rc); // modifiers check if (ResolvedTypeDefinition.IsSealed && ResolvedTypeDefinition.IsAbstract) { rc.Report.Error(152, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError()); } if ((mod_flags & Modifiers.STATIC) == Modifiers.STATIC && (mod_flags & Modifiers.SEALED) == Modifiers.SEALED) { rc.Report.Error(153, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError()); } // classes cannot derive from a special type if (ResolvedBaseType.IsKnownType(KnownTypeCode.Delegate) || ResolvedBaseType.IsKnownType(KnownTypeCode.MulticastDelegate) || ResolvedBaseType.IsKnownType(KnownTypeCode.Enum) || ResolvedBaseType.IsKnownType(KnownTypeCode.ValueType)) { rc.Report.Error(195, Location, "`{0}' cannot derive from special class `{1}'", GetSignatureForError(), ResolvedBaseType.ToString()); } // members check if (IsStatic) { if (PrimaryConstructorParameters != null) { rc.Report.Error(154, Location, "`{0}': Static classes cannot have primary constructor", GetSignatureForError()); PrimaryConstructorParameters = null; } } }
void ResolveBaseTypes(ResolveContext rc) { int i = 0; List <IType> checked_types = new List <IType>(); if (Kind == TypeKind.Class || Kind == TypeKind.Interface || Kind == TypeKind.Struct) { foreach (var bt in rc.CurrentTypeDefinition.DirectBaseTypes) { // duplicate check if (checked_types.Contains(bt)) { rc.Report.Error(158, Location, "Duplicate base class `{0}' for type definition `{1}'", bt.ToString(), ResolvedTypeDefinition.ToString()); continue; } checked_types.Add(bt); // type parameter check if (bt is TypeParameterSpec) { rc.Report.Error(193, Location, "`{0}': Cannot derive from type parameter `{1}'", GetSignatureForError(), bt.Name); continue; } // static class derive only from object if (IsStatic && !bt.IsKnownType(KnownTypeCode.Object)) { rc.Report.Error(194, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object", GetSignatureForError(), bt.ToString()); } // multiple inheritance check if (bt.Kind == TypeKind.Class) { if (ResolvedBaseType != null && ResolvedBaseType != bt) { rc.Report.Error(159, Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')", GetSignatureForError(), bt.ToString(), ResolvedBaseType.ToString()); } // base class is first check else if (i > 0 && Kind == TypeKind.Class && (!bt.IsKnownType(KnownTypeCode.Object) && !bt.IsKnownType(KnownTypeCode.ValueType))) { rc.Report.Error(160, Location, "`{0}': Base class must be specified as first, `{1}' is not a the first base class", GetSignatureForError(), bt.ToString()); } ResolvedBaseType = bt; } else if (bt.Kind != TypeKind.Interface) // not an interface check { rc.Report.Error(161, Location, "Type `{0}' is not an interface", bt.ToString()); } // if its an interface check the base interfaces if (Kind == TypeKind.Interface && !ResolvedTypeDefinition.IsAccessibleAs(bt)) { rc.Report.Error(162, Location, "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'", bt.ToString(), GetSignatureForError()); } // circular dependency check CheckCircular(ResolvedTypeDefinition, ResolvedTypeDefinition, bt, rc); // sealed or static check if ((bt as IEntity).IsSealed) { rc.Report.Error(163, Location, "`{0}' is a sealed or a static class.", bt.ToString()); } // Type parameter unification check if (bt.IsParameterized) { var unify = checked_types.Where(x => (x.IsParameterized && x.FullName == bt.FullName)).FirstOrDefault(); if (CanBeUnified(unify, bt)) { rc.Report.Error(183, Location, "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions", GetSignatureForError(), bt.ToString(), unify.ToString()); } } i++; } // check class accessibility if (Kind == TypeKind.Class && ResolvedBaseType != null && !ResolvedTypeDefinition.IsAccessibleAs(ResolvedBaseType)) { rc.Report.Error(162, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'", ResolvedBaseType.ToString(), ResolvedTypeDefinition.ToString()); } // cannot derive from an attribute if (ResolvedBaseType != null && ResolvedBaseType.IsKnownType(KnownTypeCode.Attribute) && ResolvedTypeDefinition.IsParameterized) { rc.Report.Error(155, Location, "A generic type cannot derive from `{0}' because it is an attribute class", ResolvedBaseType.ToString()); } } else if (Kind == TypeKind.Enum) { // only primitive integral types ResolvedBaseType = rc.CurrentTypeDefinition.DirectBaseTypes.FirstOrDefault(); if (ResolvedBaseType != null && !ResolvedBaseType.IsKnownType(KnownTypeCode.Enum)) { if (!ResolvedBaseType.IsKnownType(KnownTypeCode.Byte) && !ResolvedBaseType.IsKnownType(KnownTypeCode.SByte) && !ResolvedBaseType.IsKnownType(KnownTypeCode.Int16) && !ResolvedBaseType.IsKnownType(KnownTypeCode.UInt16) && !ResolvedBaseType.IsKnownType(KnownTypeCode.Int32) && !ResolvedBaseType.IsKnownType(KnownTypeCode.UInt32) && !ResolvedBaseType.IsKnownType(KnownTypeCode.Int64) && !ResolvedBaseType.IsKnownType(KnownTypeCode.UInt64)) { rc.Report.Error(164, Location, "Type `{0}' is not sbyte,byte,short,ushort,int,uint,long,ulong", ResolvedBaseType.ToString()); } } } if (ResolvedBaseType == null) { if (Kind == TypeKind.Class) { ResolvedBaseType = KnownTypeReference.Object.Resolve(rc.CurrentTypeResolveContext); } else if (Kind == TypeKind.Struct) { ResolvedBaseType = KnownTypeReference.ValueType.Resolve(rc.CurrentTypeResolveContext); } else if (Kind == TypeKind.Enum) { ResolvedBaseType = KnownTypeReference.Enum.Resolve(rc.CurrentTypeResolveContext); } else if (Kind == TypeKind.Delegate) { ResolvedBaseType = KnownTypeReference.MulticastDelegate.Resolve(rc.CurrentTypeResolveContext); } } }