2007-12-06 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / mcs / class.cs
index 6a98c802b9e49a9f8429879e9976277616875c5c..9a6689ea67a82d5ce96082159ae2106e61968d9f 100644 (file)
@@ -41,7 +41,7 @@ using System.Security;
 using System.Security.Permissions;
 using System.Text;
 
-#if BOOTSTRAP_WITH_OLDLIB
+#if BOOTSTRAP_WITH_OLDLIB || NET_2_1
 using XmlElement = System.Object;
 #else
 using System.Xml;
@@ -2842,9 +2842,8 @@ namespace Mono.CSharp {
 
                        if ((events != null) && Report.WarningLevel >= 3) {
                                foreach (Event e in events){
-                                       if ((e.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
-                                               continue;
-
+                                       // Note: The event can be assigned from same class only, so we can report
+                                       // this warning for all accessibility modes
                                        if ((e.caching_flags & Flags.IsUsed) == 0)
                                                Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
                                }
@@ -3134,7 +3133,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (IsStatic) {
+                       if (PartialContainer.IsStaticClass) {
                                if (base_class.Type != TypeManager.object_type) {
                                        Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
                                                GetSignatureForError (), base_class.GetSignatureForError ());
@@ -3144,7 +3143,7 @@ namespace Mono.CSharp {
                                if (ifaces != null) {
                                        foreach (TypeExpr t in ifaces)
                                                Report.SymbolRelatedToPreviousError (t.Type);
-                                       Report.Error (714, Location, "`{0}': static classes cannot implement interfaces", GetSignatureForError ());
+                                       Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
                                }
                        }
 
@@ -3429,7 +3428,8 @@ namespace Mono.CSharp {
                                return false;
 
                        if ((caching_flags & Flags.MethodOverloadsExist) != 0) {
-                               if (!Parent.MemberCache.CheckExistingMembersOverloads (this, Name, Parameters))
+                               if (!Parent.MemberCache.CheckExistingMembersOverloads (this,
+                                       MemberName.IsGeneric ? MemberName.Basename : MemberName.MethodName, Parameters))
                                        return false;
 
                                // TODO: Find a better way how to check reserved accessors collision
@@ -3706,23 +3706,20 @@ namespace Mono.CSharp {
                        if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
                                //
                                // when overriding protected internal, the method can be declared
-                               // protected internal only within the same assembly
+                               // protected internal only within the same assembly or assembly
+                               // which has InternalsVisibleTo
                                //
-
                                if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
-                                       if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
-                                               //
-                                               // assemblies differ - report an error
-                                               //
-                                               
-                                               return false;
-                                       } else if (thisp != base_classp) {
+                                       if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly)
+                                               return TypeManager.IsFriendAssembly (base_method.DeclaringType.Assembly);
+
+                                       if (thisp != base_classp) {
                                                //
                                                // same assembly, but other attributes differ - report an error
                                                //
                                                
                                                return false;
-                                       };
+                                       }
                                } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
                                        //
                                        // if it's not "protected internal", it must be "protected"
@@ -4939,6 +4936,12 @@ namespace Mono.CSharp {
                        
                        Parent.MemberCache.AddMember (ConstructorBuilder, this);
                        TypeManager.AddMethod (ConstructorBuilder, this);
+                       
+                       // It's here only to report an error
+                       if ((ModFlags & Modifiers.METHOD_YIELDS) != 0) {
+                               member_type = TypeManager.void_type;
+                               Iterator.CreateIterator (this, Parent, null, ModFlags);
+                       }
 
                        return true;
                }
@@ -6030,52 +6033,53 @@ namespace Mono.CSharp {
                {
                }
 
+               bool CanBeVolatile ()
+               {
+#if GMCS_SOURCE                        
+                       if (TypeManager.IsGenericParameter (MemberType)) {
+                               GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (MemberType);
+                               if (constraints == null)
+                                       return false;
+
+                               return constraints.IsReferenceType;
+                       }
+#endif                 
+
+                       if (!MemberType.IsValueType)
+                               return true;
+
+                       if (MemberType.IsEnum)
+                               return true;
+
+                       if (MemberType == TypeManager.bool_type || MemberType == TypeManager.char_type ||
+                               MemberType == TypeManager.sbyte_type || MemberType == TypeManager.byte_type ||
+                               MemberType == TypeManager.short_type || MemberType == TypeManager.ushort_type ||
+                               MemberType == TypeManager.int32_type || MemberType == TypeManager.uint32_type ||
+                               MemberType == TypeManager.float_type)
+                               return true;
+
+                       return false;
+               }
+
                public override bool Define ()
                {
                        if (!base.Define ())
                                return false;
 
                        if ((ModFlags & Modifiers.VOLATILE) != 0){
-                               if (!MemberType.IsClass){
-                                       Type vt = MemberType;
-                                       
-                                       if (TypeManager.IsEnumType (vt))
-                                               vt = TypeManager.EnumToUnderlying (MemberType);
-
-                                       if (!((vt == TypeManager.bool_type) ||
-                                             (vt == TypeManager.sbyte_type) ||
-                                             (vt == TypeManager.byte_type) ||
-                                             (vt == TypeManager.short_type) ||
-                                             (vt == TypeManager.ushort_type) ||
-                                             (vt == TypeManager.int32_type) ||
-                                             (vt == TypeManager.uint32_type) ||    
-                                             (vt == TypeManager.char_type) ||
-                                             (vt == TypeManager.float_type) ||
-                                             (!vt.IsValueType))){
-                                               Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
-                                                       GetSignatureForError (), TypeManager.CSharpName (vt));
-                                               return false;
-                                       }
+                               if (!CanBeVolatile ()) {
+                                       Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
+                                               GetSignatureForError (), TypeManager.CSharpName (MemberType));
                                }
 
                                if ((ModFlags & Modifiers.READONLY) != 0){
                                        Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
                                                GetSignatureForError ());
-                                       return false;
                                }
                        }
 
                        FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
 
-                       if (Parent.PartialContainer.Kind == Kind.Struct && 
-                           ((fa & FieldAttributes.Static) == 0) &&
-                           MemberType == Parent.TypeBuilder &&
-                           !TypeManager.IsBuiltinType (MemberType)){
-                               Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
-                                             "' causes a cycle in the structure layout");
-                               return false;
-                       }
-
                        try {
                                FieldBuilder = Parent.TypeBuilder.DefineField (
                                        Name, MemberType, Modifiers.FieldAttr (ModFlags));
@@ -6091,6 +6095,14 @@ namespace Mono.CSharp {
                        if (initializer != null)
                                ((TypeContainer) Parent).RegisterFieldForInitialization (this,
                                        new FieldInitializer (FieldBuilder, initializer));
+
+                       if (Parent.PartialContainer.Kind == Kind.Struct && (fa & FieldAttributes.Static) == 0 &&
+                               MemberType == Parent.TypeBuilder && !TypeManager.IsBuiltinType (MemberType) && initializer == null) {
+                               Report.Error (523, Location, "Struct member `{0}' causes a cycle in the structure layout",
+                                       GetSignatureForError ());
+                               return false;
+                       }
+
                        return true;
                }
 
@@ -6900,7 +6912,7 @@ namespace Mono.CSharp {
                        Modifiers.SEALED |
                        Modifiers.OVERRIDE |
                        Modifiers.ABSTRACT |
-                       Modifiers.UNSAFE |
+                       Modifiers.UNSAFE |
                        Modifiers.EXTERN |
                        Modifiers.METHOD_YIELDS |
                        Modifiers.VIRTUAL;
@@ -6914,8 +6926,7 @@ namespace Mono.CSharp {
                        Field field = new Field (
                                Parent, Type,
                                Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & Modifiers.STATIC),
-                               CompilerGeneratedClass.MakeName (null, "CompilerGeneratedField"),
-                               null, Location);
+                           "<" + Name + ">k__BackingField", null, Location);
                        ((TypeContainer)Parent).AddField (field);
 
                        // Make get block
@@ -6947,12 +6958,14 @@ namespace Mono.CSharp {
                                is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
                                is_iface, name, attrs, define_set_first)
                {
-                       if (RootContext.Version >= LanguageVersion.LINQ &&
-                               !is_iface &&
-                               (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
+                       if (!is_iface && (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
                                get_block != null && get_block.Block == null &&
-                               set_block != null && set_block.Block == null)
+                               set_block != null && set_block.Block == null) {
+                               if (RootContext.Version <= LanguageVersion.ISO_2)
+                                       Report.FeatureIsNotAvailable (Location, "automatically implemented properties");
+                               
                                CreateAutomaticProperty (current_block, get_block, set_block);
+                       }
 
                        if (get_block == null)
                                Get = new GetMethod (this);
@@ -7239,9 +7252,7 @@ namespace Mono.CSharp {
                        if (!base.Define ())
                                return false;
 
-                       if (IsExplicitImpl)
-                               SetMemberIsUsed ();
-
+                       SetMemberIsUsed ();
                        return true;
                }
 
@@ -7373,6 +7384,9 @@ namespace Mono.CSharp {
                        if (TypeManager.IsGenericType (MemberType))
                                SetMemberIsUsed();
 
+                       if (Add.IsInterfaceImplementation)
+                               SetMemberIsUsed ();
+
                        FieldBuilder = Parent.TypeBuilder.DefineField (
                                Name, MemberType,
                                FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
@@ -7426,6 +7440,10 @@ namespace Mono.CSharp {
                                get { return null; }
                        }
 
+                       public bool IsInterfaceImplementation {
+                               get { return method_data.implementing != null; }
+                       }
+
                        public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
                        {
                                if (a.IsInternalMethodImplAttribute) {
@@ -7809,15 +7827,6 @@ namespace Mono.CSharp {
                        //
                        // Now name the parameters
                        //
-                       Parameter [] p = parameters.FixedParameters;
-                       if (p != null) {
-                               // TODO: should be done in parser and it needs to do cycle
-                               if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
-                                       CSharpParser.Error_ParameterModifierNotValid (Location);
-                                       return false;
-                               }
-                       }
-
                        PropertyBuilder = Parent.TypeBuilder.DefineProperty (
                                Name, PropertyAttributes.None, MemberType, parameters.Types);
 
@@ -7976,24 +7985,29 @@ namespace Mono.CSharp {
                        Type declaring_type = MethodData.DeclaringType;
                        Type return_type = MemberType;
                        Type first_arg_type = ParameterTypes [0];
+                       
+                       Type first_arg_type_unwrap = first_arg_type;
+                       if (TypeManager.IsNullableType (first_arg_type))
+                               first_arg_type_unwrap = TypeManager.GetTypeArguments (first_arg_type) [0];
+                       
+                       Type return_type_unwrap = return_type;
+                       if (TypeManager.IsNullableType (return_type))
+                               return_type_unwrap = TypeManager.GetTypeArguments (return_type) [0];                    
 
+                       //
                        // Rules for conversion operators
-                       
+                       //
                        if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
-                               if (first_arg_type == return_type && first_arg_type == declaring_type){
+                               if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type){
                                        Report.Error (555, Location,
                                                "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
                                        return false;
                                }
                                
                                Type conv_type;
-                               if (TypeManager.IsEqual (declaring_type, return_type)) {
-                                       conv_type = first_arg_type;
-                               } else if (TypeManager.IsEqual (declaring_type, first_arg_type)) {
-                                       conv_type = return_type;
-                               } else if (TypeManager.IsNullableTypeOf (return_type, declaring_type)) {
+                               if (TypeManager.IsEqual (declaring_type, return_type) || declaring_type == return_type_unwrap) {
                                        conv_type = first_arg_type;
-                               } else if (TypeManager.IsNullableTypeOf (first_arg_type, declaring_type)) {
+                               } else if (TypeManager.IsEqual (declaring_type, first_arg_type) || declaring_type == first_arg_type_unwrap) {
                                        conv_type = return_type;
                                } else {
                                        Report.Error (556, Location,