2010-07-14 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / mcs / method.cs
index 1f52040a8df9ba77a767956a92e446d0a8fb6db1..2c0658f41b52a0d3e6f41ae4e48d7c5dedfe2228 100644 (file)
@@ -143,11 +143,14 @@ namespace Mono.CSharp {
 
                public override bool EnableOverloadChecks (MemberCore overload)
                {
-                       if (overload is MethodCore || overload is AbstractPropertyEventMethod) {
+                       if (overload is MethodCore) {
                                caching_flags |= Flags.MethodOverloadsExist;
                                return true;
                        }
 
+                       if (overload is AbstractPropertyEventMethod)
+                               return true;
+
                        return base.EnableOverloadChecks (overload);
                }
 
@@ -308,9 +311,6 @@ namespace Mono.CSharp {
                                state &= ~StateFlags.PendingMakeMethod;
                        }
 
-                       if (Kind == MemberKind.FakeMethod)
-                               throw new InternalErrorException ("Emitting fake method");
-
                        return metaInfo;
                }
 
@@ -927,42 +927,32 @@ namespace Mono.CSharp {
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
                }
 
-               protected override bool CheckForDuplications ()
-               {
-                       if (!base.CheckForDuplications ())
-                               return false;
-
-                       var ar = Parent.PartialContainer.Properties;
-                       if (ar != null) {
-                               for (int i = 0; i < ar.Count; ++i) {
-                                       PropertyBase pb = (PropertyBase) ar [i];
-                                       if (pb.AreAccessorsDuplicateImplementation (this))
-                                               return false;
-                               }
-                       }
-
-                       ar = Parent.PartialContainer.Indexers;
-                       if (ar != null) {
-                               for (int i = 0; i < ar.Count; ++i) {
-                                       PropertyBase pb = (PropertyBase) ar [i];
-                                       if (pb.AreAccessorsDuplicateImplementation (this))
-                                               return false;
-                               }
-                       }
-
-                       return true;
-               }
-
                protected virtual void DefineTypeParameters ()
                {
                        var tparams = CurrentTypeParameters;
 
                        TypeParameterSpec[] base_tparams = null;
+                       TypeParameterSpec[] base_decl_tparams = TypeParameterSpec.EmptyTypes;
+                       TypeSpec[] base_targs = TypeSpec.EmptyTypes;
                        if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
-                               if (base_method != null)
+                               if (base_method != null) {
                                        base_tparams = base_method.GenericDefinition.TypeParameters;
-                               else if (MethodData.implementing != null)
+                                       if (base_method.DeclaringType.IsGeneric) {
+                                               base_decl_tparams = base_method.DeclaringType.MemberDefinition.TypeParameters;
+                                               base_targs = Parent.BaseType.TypeArguments;
+                                       }
+                               } else if (MethodData.implementing != null) {
                                        base_tparams = MethodData.implementing.GenericDefinition.TypeParameters;
+                                       if (MethodData.implementing.DeclaringType.IsGeneric) {
+                                               base_decl_tparams = MethodData.implementing.DeclaringType.MemberDefinition.TypeParameters;
+                                               foreach (var iface in Parent.CurrentType.Interfaces) {
+                                                       if (iface == MethodData.implementing.DeclaringType) {
+                                                               base_targs = iface.TypeArguments;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
                        }
 
                        for (int i = 0; i < tparams.Length; ++i) {
@@ -977,11 +967,9 @@ namespace Mono.CSharp {
                                if (base_tparams != null) {
                                        var base_tparam = base_tparams[i];
                                        tp.Type.SpecialConstraint = base_tparam.SpecialConstraint;
-                                       tp.Type.TypeArguments = base_tparam.TypeArguments;
 
-                                       // TODO MemberCache: Inflate with different MVAR ?
-                                       tp.Type.Interfaces = base_tparam.Interfaces;
-                                       tp.Type.BaseType = base_tparam.BaseType;
+                                       var inflator = new TypeParameterInflator (CurrentType, base_decl_tparams, base_targs);
+                                       base_tparam.InflateConstraints (inflator, tp.Type);
                                } else if (MethodData.implementing != null) {
                                        var base_tp = MethodData.implementing.Constraints[i];
                                        if (!tp.Type.HasSameConstraintsImplementation (base_tp)) {
@@ -999,7 +987,7 @@ namespace Mono.CSharp {
                //
                public override bool Define ()
                {
-                       if (type_expr == TypeManager.system_void_expr && parameters.IsEmpty && Name == Destructor.MetadataName) {
+                       if (type_expr.Type == TypeManager.void_type && parameters.IsEmpty && MemberName.Arity == 0 && MemberName.Name == Destructor.MetadataName) {
                                Report.Warning (465, 1, Location, "Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
                        }
 
@@ -1739,14 +1727,13 @@ namespace Mono.CSharp {
                                                                Report.SymbolRelatedToPreviousError (implementing);
                                                                Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
                                                                        method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
-                                                               return false;
-                                                       }
-                                                       PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
-                                                       if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
-                                                               Report.SymbolRelatedToPreviousError (implementing);
-                                                               Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
-                                                                       method.GetSignatureForError (), implementing.GetSignatureForError ());
-                                                               return false;
+                                                       } else {
+                                                               PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
+                                                               if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
+                                                                       Report.SymbolRelatedToPreviousError (implementing);
+                                                                       Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
+                                                                               method.GetSignatureForError (), implementing.GetSignatureForError ());
+                                                               }
                                                        }
                                                }
                                        }
@@ -1770,7 +1757,6 @@ namespace Mono.CSharp {
                                                Report.SymbolRelatedToPreviousError (implementing);
                                                Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
                                                        method.GetSignatureForError ());
-                                               return false;
                                        }
                                } else {
                                        if (implementing.DeclaringType.IsInterface) {
@@ -1928,7 +1914,7 @@ namespace Mono.CSharp {
                public static readonly string MetadataName = "Finalize";
 
                public Destructor (DeclSpace parent, Modifiers mod, ParametersCompiled parameters, Attributes attrs, Location l)
-                       : base (parent, null, TypeManager.system_void_expr, mod, AllowedModifiers,
+                       : base (parent, null, null, mod, AllowedModifiers,
                                new MemberName (MetadataName, l), attrs, parameters)
                {
                        ModFlags &= ~Modifiers.PRIVATE;
@@ -1947,19 +1933,22 @@ namespace Mono.CSharp {
 
                protected override bool CheckBase ()
                {
-                       // Don't check base, the destructor has special syntax
+                       // Don't check base, destructors have special syntax
+                       return true;
+               }
 
+               public override void Emit()
+               {
                        var base_type = Parent.PartialContainer.BaseType;
-                       if (base_type == null)
-                               return true;
+                       if (base_type != null && Block != null) {
+                               var base_dtor = MemberCache.FindMember (base_type,
+                                       new MemberFilter (MetadataName, 0, MemberKind.Destructor, null, null), BindingRestriction.InstanceOnly) as MethodSpec;
 
-                       if (Block != null) {
-                               MethodGroupExpr method_expr = Expression.MethodLookup (Parent.Module.Compiler, Parent.Definition, base_type, MemberKind.Destructor, MetadataName, 0, Location);
-                               if (method_expr == null)
+                               if (base_dtor == null)
                                        throw new NotImplementedException ();
 
-                               method_expr.IsBase = true;
-                               method_expr.InstanceExpression = new CompilerGeneratedThis (Parent.Definition, Location);
+                               MethodGroupExpr method_expr = MethodGroupExpr.CreatePredefined (base_dtor, base_type, Location);
+                               method_expr.InstanceExpression = new BaseThis (base_type, Location);
 
                                ToplevelBlock new_block = new ToplevelBlock (Compiler, Block.StartLocation);
                                new_block.EndLocation = Block.EndLocation;
@@ -1978,7 +1967,7 @@ namespace Mono.CSharp {
                                block = new_block;
                        }
 
-                       return true;
+                       base.Emit ();
                }
 
                public override string GetSignatureForError ()
@@ -1986,6 +1975,12 @@ namespace Mono.CSharp {
                        return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
                }
 
+               protected override bool ResolveMemberType ()
+               {
+                       member_type = TypeManager.void_type;
+                       return true;
+               }
+
                public override string[] ValidAttributeTargets {
                        get {
                                return attribute_targets;
@@ -2000,29 +1995,14 @@ namespace Mono.CSharp {
                protected ToplevelBlock block;
                protected Dictionary<SecurityAction, PermissionSet> declarative_security;
 
-               // The accessor are created even if they are not wanted.
-               // But we need them because their names are reserved.
-               // Field says whether accessor will be emited or not
-               public readonly bool IsDummy;
-
                protected readonly string prefix;
 
                ReturnParameter return_attributes;
 
-               public AbstractPropertyEventMethod (PropertyBasedMember member, string prefix)
-                       : base (member.Parent, SetupName (prefix, member, member.Location), null)
-               {
-                       this.prefix = prefix;
-                       IsDummy = true;
-               }
-
-               public AbstractPropertyEventMethod (InterfaceMemberBase member, Accessor accessor,
-                                                   string prefix)
-                       : base (member.Parent, SetupName (prefix, member, accessor.Location),
-                               accessor.Attributes)
+               public AbstractPropertyEventMethod (InterfaceMemberBase member, string prefix, Attributes attrs, Location loc)
+                       : base (member.Parent, SetupName (prefix, member, loc), attrs)
                {
                        this.prefix = prefix;
-                       this.block = accessor.Block;
                }
 
                static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
@@ -2167,15 +2147,16 @@ namespace Mono.CSharp {
 
                public override bool EnableOverloadChecks (MemberCore overload)
                {
+                       if (overload is MethodCore) {
+                               caching_flags |= Flags.MethodOverloadsExist;
+                               return true;
+                       }
+
                        // This can only happen with indexers and it will
                        // be catched as indexer difference
                        if (overload is AbstractPropertyEventMethod)
                                return true;
 
-                       if (overload is MethodCore) {
-                               caching_flags |= Flags.MethodOverloadsExist;
-                               return true;
-                       }
                        return false;
                }
 
@@ -2184,35 +2165,6 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               public bool IsDuplicateImplementation (MethodCore method)
-               {
-                       if (!MemberName.Equals (method.MemberName))
-                               return false;
-
-                       TypeSpec[] param_types = method.ParameterTypes;
-
-                       if (param_types == null || param_types.Length != ParameterTypes.Length)
-                               return false;
-
-                       for (int i = 0; i < param_types.Length; i++)
-                               if (param_types [i] != ParameterTypes [i])
-                                       return false;
-
-                       Report.SymbolRelatedToPreviousError (method);
-                       Report.Error (82, Location, "A member `{0}' is already reserved",
-                               method.GetSignatureForError ());
-                       return true;
-               }
-
-               public override bool IsUsed {
-                       get {
-                               if (IsDummy)
-                                       return false;
-
-                               return base.IsUsed;
-                       }
-               }
-
                public MethodSpec Spec { get; protected set; }
 
                //
@@ -2367,57 +2319,52 @@ namespace Mono.CSharp {
                        if (TypeManager.IsNullableType (return_type))
                                return_type_unwrap = TypeManager.GetTypeArguments (return_type) [0];
 
-                       if (return_type == InternalType.Dynamic || first_arg_type == InternalType.Dynamic) {
-                               Report.Error (1964, Location,
-                                       "User-defined operator `{0}' cannot convert to or from the dynamic type",
-                                       GetSignatureForError ());
-
-                               return false;
-                       }
-
                        //
                        // Rules for conversion operators
                        //
                        if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
-                               if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == 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;
                                }
-                               
+
                                TypeSpec conv_type;
                                if (TypeManager.IsEqual (declaring_type, return_type) || declaring_type == return_type_unwrap) {
                                        conv_type = first_arg_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, 
+                                       Report.Error (556, Location,
                                                "User-defined conversion must convert to or from the enclosing type");
                                        return false;
                                }
 
-                               //
-                               // Because IsInterface and IsClass are not supported
-                               //
-                               if (!TypeManager.IsGenericParameter (conv_type)) {
-                                       if (conv_type.IsInterface) {
-                                               Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
+                               if (conv_type == InternalType.Dynamic) {
+                                       Report.Error (1964, Location,
+                                               "User-defined conversion `{0}' cannot convert to or from the dynamic type",
+                                               GetSignatureForError ());
+
+                                       return false;
+                               }
+
+                               if (conv_type.IsInterface) {
+                                       Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
+                                               GetSignatureForError ());
+                                       return false;
+                               }
+
+                               if (conv_type.IsClass) {
+                                       if (TypeManager.IsSubclassOf (declaring_type, conv_type)) {
+                                               Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
                                                        GetSignatureForError ());
                                                return false;
                                        }
 
-                                       if (conv_type.IsClass) {
-                                               if (TypeManager.IsSubclassOf (declaring_type, conv_type)) {
-                                                       Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
-                                                               GetSignatureForError ());
-                                                       return false;
-                                               }
-
-                                               if (TypeManager.IsSubclassOf (conv_type, declaring_type)) {
-                                                       Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
-                                                               GetSignatureForError ());
-                                                       return false;
-                                               }
+                                       if (TypeManager.IsSubclassOf (conv_type, declaring_type)) {
+                                               Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
+                                                       GetSignatureForError ());
+                                               return false;
                                        }
                                }
                        } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
@@ -2440,15 +2387,15 @@ namespace Mono.CSharp {
                                                return false;
                                        }
                                }
-                               
-                               if (!TypeManager.IsEqual (first_arg_type_unwrap, declaring_type)){
+
+                               if (!TypeManager.IsEqual (first_arg_type_unwrap, declaring_type)) {
                                        Report.Error (562, Location,
                                                "The parameter type of a unary operator must be the containing type");
                                        return false;
                                }
-                               
+
                                if (OperatorType == OpType.True || OperatorType == OpType.False) {
-                                       if (return_type != TypeManager.bool_type){
+                                       if (return_type != TypeManager.bool_type) {
                                                Report.Error (
                                                        215, Location,
                                                        "The return type of operator True or False " +
@@ -2456,13 +2403,13 @@ namespace Mono.CSharp {
                                                return false;
                                        }
                                }
-                               
+
                        } else if (!TypeManager.IsEqual (first_arg_type_unwrap, declaring_type)) {
                                // Checks for Binary operators
 
-                               var second_arg_type = ParameterTypes [1];
+                               var second_arg_type = ParameterTypes[1];
                                if (TypeManager.IsNullableType (second_arg_type))
-                                       second_arg_type = TypeManager.GetTypeArguments (second_arg_type) [0];
+                                       second_arg_type = TypeManager.GetTypeArguments (second_arg_type)[0];
 
                                if (!TypeManager.IsEqual (second_arg_type, declaring_type)) {
                                        Report.Error (563, Location,