예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        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);
                }
            }
        }