X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fdelegate.cs;h=75a0989906ecb32bf4cbb46ae613d1e2cf3faea2;hb=ea15effd923d6ce84e2b3d93641b6144a2c45180;hp=490fe7d75fce8a2a2a14e45672751e0a125759a4;hpb=09ef4df55e60d0e14527e842a4799bd4a1e59618;p=mono.git diff --git a/mcs/mcs/delegate.cs b/mcs/mcs/delegate.cs index 490fe7d75fc..75a0989906e 100644 --- a/mcs/mcs/delegate.cs +++ b/mcs/mcs/delegate.cs @@ -49,7 +49,7 @@ namespace Mono.CSharp { Modifiers.PRIVATE; public Delegate (NamespaceEntry ns, TypeContainer parent, Expression type, - int mod_flags, string name, Parameters param_list, + int mod_flags, MemberName name, Parameters param_list, Attributes attrs, Location l) : base (ns, parent, name, attrs, l) @@ -63,7 +63,7 @@ namespace Mono.CSharp { public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb) { - if (a.Target == "return") { + if (a.Target == AttributeTargets.ReturnValue) { if (return_attributes == null) return_attributes = new ReturnParameter (InvokeBuilder, Location); @@ -79,9 +79,17 @@ namespace Mono.CSharp { if (TypeBuilder != null) return TypeBuilder; + ec = new EmitContext (this, this, Location, null, null, ModFlags, false); + TypeAttributes attr = Modifiers.TypeAttr (ModFlags, IsTopLevel) | TypeAttributes.Class | TypeAttributes.Sealed; + if (TypeManager.multicast_delegate_type == null) + Report.Error (-100, loc, "Internal error: delegate used before " + + "System.MulticastDelegate is resolved. This can only " + + "happen during corlib compilation, when using a delegate " + + "in any of the `core' classes. See bug #72015 for details."); + if (IsTopLevel) { if (TypeManager.NamespaceClash (Name, Location)) return null; @@ -112,8 +120,7 @@ namespace Mono.CSharp { { MethodAttributes mattr; int i; - EmitContext ec = new EmitContext (this, this, Location, null, - null, ModFlags, false); + ec = new EmitContext (this, this, Location, null, null, ModFlags, false); // FIXME: POSSIBLY make this static, as it is always constant // @@ -136,8 +143,10 @@ namespace Mono.CSharp { // // FIXME: POSSIBLY make these static, as they are always the same Parameter [] fixed_pars = new Parameter [2]; - fixed_pars [0] = new Parameter (null, null, Parameter.Modifier.NONE, null); - fixed_pars [1] = new Parameter (null, null, Parameter.Modifier.NONE, null); + fixed_pars [0] = new Parameter (TypeManager.system_object_expr, "object", + Parameter.Modifier.NONE, null); + fixed_pars [1] = new Parameter (TypeManager.system_intptr_expr, "method", + Parameter.Modifier.NONE, null); Parameters const_parameters = new Parameters (fixed_pars, null, Location); TypeManager.RegisterMethod ( @@ -154,10 +163,10 @@ namespace Mono.CSharp { // First, call the `out of band' special method for // defining recursively any types we need: - if (!Parameters.ComputeAndDefineParameterTypes (this)) + if (!Parameters.ComputeAndDefineParameterTypes (ec)) return false; - param_types = Parameters.GetParameterInfo (this); + param_types = Parameters.GetParameterInfo (ec); if (param_types == null) return false; @@ -178,7 +187,7 @@ namespace Mono.CSharp { return false; } - ReturnType = ResolveTypeExpr (ReturnType, false, Location); + ReturnType = ReturnType.ResolveAsTypeTerminal (ec, false); if (ReturnType == null) return false; @@ -237,7 +246,7 @@ namespace Mono.CSharp { InvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); TypeManager.RegisterMethod (InvokeBuilder, - new InternalParameters (Parent, Parameters), + new InternalParameters (param_types, Parameters), param_types); // @@ -300,11 +309,10 @@ namespace Mono.CSharp { Parameter.Modifier.NONE, null); Parameters async_parameters = new Parameters (async_params, null, Location); - async_parameters.ComputeAndDefineParameterTypes (this); - - async_parameters.ComputeAndDefineParameterTypes (this); + async_parameters.ComputeAndDefineParameterTypes (ec); + TypeManager.RegisterMethod (BeginInvokeBuilder, - new InternalParameters (Parent, async_parameters), + new InternalParameters (async_param_types, async_parameters), async_param_types); // @@ -345,11 +353,11 @@ namespace Mono.CSharp { } Parameters end_parameters = new Parameters (end_params, null, Location); - end_parameters.ComputeAndDefineParameterTypes (this); + end_parameters.ComputeAndDefineParameterTypes (ec); TypeManager.RegisterMethod ( EndInvokeBuilder, - new InternalParameters (Parent, end_parameters), + new InternalParameters (end_param_types, end_parameters), end_param_types); return true; @@ -358,8 +366,6 @@ namespace Mono.CSharp { public override void Emit () { if (OptAttributes != null) { - EmitContext ec = new EmitContext ( - Parent, this, Location, null, null, ModFlags, false); Parameters.LabelParameters (ec, InvokeBuilder, Location); OptAttributes.Emit (ec, this); } @@ -367,7 +373,7 @@ namespace Mono.CSharp { base.Emit (); } - protected override string[] ValidAttributeTargets { + public override string[] ValidAttributeTargets { get { return attribute_targets; } @@ -383,11 +389,28 @@ namespace Mono.CSharp { AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location); if (!AttributeTester.IsClsCompliant (ReturnType.Type)) { - Report.Error_T (3002, Location, GetSignatureForError ()); + Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant", GetSignatureForError ()); } return true; } + // + // Returns the MethodBase for "Invoke" from a delegate type, this is used + // to extract the signature of a delegate. + // + public static MethodInfo GetInvokeMethod (EmitContext ec, Type delegate_type, Location loc) + { + Expression ml = Expression.MemberLookup ( + ec, delegate_type, "Invoke", loc); + + if (!(ml is MethodGroupExpr)) { + Report.Error (-100, loc, "Internal error: could not find Invoke method!"); + return null; + } + + return (MethodInfo) (((MethodGroupExpr) ml).Methods [0]); + } + /// /// Verifies whether the method in question is compatible with the delegate /// Returns the method itself if okay and null if not. @@ -399,15 +422,9 @@ namespace Mono.CSharp { int pd_count = pd.Count; - Expression ml = Expression.MemberLookup ( - ec, delegate_type, "Invoke", loc); - - if (!(ml is MethodGroupExpr)) { - Report.Error (-100, loc, "Internal error: could not find Invoke method!"); + MethodBase invoke_mb = GetInvokeMethod (ec, delegate_type, loc); + if (invoke_mb == null) return null; - } - - MethodBase invoke_mb = ((MethodGroupExpr) ml).Methods [0]; ParameterData invoke_pd = Invocation.GetParameterData (invoke_mb); @@ -417,28 +434,48 @@ namespace Mono.CSharp { for (int i = pd_count; i > 0; ) { i--; - if (invoke_pd.ParameterType (i) == pd.ParameterType (i) && - invoke_pd.ParameterModifier (i) == pd.ParameterModifier (i)) + Type invoke_pd_type = invoke_pd.ParameterType (i); + Type pd_type = pd.ParameterType (i); + Parameter.Modifier invoke_pd_type_mod = invoke_pd.ParameterModifier (i); + Parameter.Modifier pd_type_mod = pd.ParameterModifier (i); + + if (invoke_pd_type == pd_type && + invoke_pd_type_mod == pd_type_mod) continue; - else { - return null; - } + + if (invoke_pd_type.IsSubclassOf (pd_type) && + invoke_pd_type_mod == pd_type_mod) + if (RootContext.Version == LanguageVersion.ISO_1) { + Report.FeatureIsNotStandardized (loc, "contravariance"); + return null; + } else + continue; + + return null; } - if (((MethodInfo) invoke_mb).ReturnType == ((MethodInfo) mb).ReturnType) + Type invoke_mb_retval = ((MethodInfo) invoke_mb).ReturnType; + Type mb_retval = ((MethodInfo) mb).ReturnType; + if (invoke_mb_retval == mb_retval) return mb; - else - return null; + + if (mb_retval.IsSubclassOf (invoke_mb_retval)) + if (RootContext.Version == LanguageVersion.ISO_1) { + Report.FeatureIsNotStandardized (loc, "covariance"); + return null; + } + else + return mb; + + return null; } // // Verifies whether the invocation arguments are compatible with the // delegate's target method // - public static bool VerifyApplicability (EmitContext ec, - Type delegate_type, - ArrayList args, - Location loc) + public static bool VerifyApplicability (EmitContext ec, Type delegate_type, + ArrayList args, Location loc) { int arg_count; @@ -465,8 +502,8 @@ namespace Mono.CSharp { if (!params_method && pd_count != arg_count) { Report.Error (1593, loc, - "Delegate '" + delegate_type.ToString () - + "' does not take '" + arg_count + "' arguments"); + "Delegate '{0}' does not take {1} arguments", + delegate_type.ToString (), arg_count); return false; } @@ -487,9 +524,13 @@ namespace Mono.CSharp { bool ans = false; if (arg_count == pd_count) - ans = Invocation.VerifyArgumentsCompat (ec, args, arg_count, mb, false, delegate_type, loc); + ans = Invocation.VerifyArgumentsCompat ( + ec, args, arg_count, mb, false, + delegate_type, false, loc); if (!ans && params_method) - ans = Invocation.VerifyArgumentsCompat (ec, args, arg_count, mb, true, delegate_type, loc); + ans = Invocation.VerifyArgumentsCompat ( + ec, args, arg_count, mb, true, + delegate_type, false, loc); return ans; } @@ -625,10 +666,17 @@ namespace Mono.CSharp { public override AttributeTargets AttributeTargets { get { - return AttributeTargets.Delegate | AttributeTargets.ReturnValue; + return AttributeTargets.Delegate; } } + // + // Represents header string for documentation comment. + // + public override string DocCommentHeader { + get { return "T:"; } + } + protected override void VerifyObsoleteAttribute() { CheckUsageOfObsoleteAttribute (ret_type); @@ -646,6 +694,7 @@ namespace Mono.CSharp { protected MethodBase constructor_method; protected MethodBase delegate_method; protected MethodGroupExpr method_group; + protected Expression delegate_instance_expression; public DelegateCreation () {} @@ -671,11 +720,10 @@ namespace Mono.CSharp { public override void Emit (EmitContext ec) { - if (method_group.InstanceExpression == null || - delegate_method.IsStatic) + if (delegate_instance_expression == null || delegate_method.IsStatic) ec.ig.Emit (OpCodes.Ldnull); else - method_group.InstanceExpression.Emit (ec); + delegate_instance_expression.Emit (ec); if (delegate_method.IsVirtual && !method_group.IsBase) { ec.ig.Emit (OpCodes.Dup); @@ -732,18 +780,16 @@ namespace Mono.CSharp { IMethodData md = TypeManager.GetMethod (delegate_method); if (md == null) { if (System.Attribute.GetCustomAttribute (delegate_method, TypeManager.conditional_attribute_type) != null) { - // Cannot create delegate with '{0}' because it has a Conditional attribute - Report.Error_T (1618, loc, TypeManager.CSharpSignature (delegate_method)); + Report.Error (1618, loc, "Cannot create delegate with '{0}' because it has a Conditional attribute", TypeManager.CSharpSignature (delegate_method)); } } else { if (md.OptAttributes != null && md.OptAttributes.Search (TypeManager.conditional_attribute_type, ec) != null) { - // Cannot create delegate with '{0}' because it has a Conditional attribute - Report.Error_T (1618, loc, TypeManager.CSharpSignature (delegate_method)); + Report.Error (1618, loc, "Cannot create delegate with '{0}' because it has a Conditional attribute", TypeManager.CSharpSignature (delegate_method)); } } if (mg.InstanceExpression != null) - mg.InstanceExpression = mg.InstanceExpression.Resolve (ec); + delegate_instance_expression = mg.InstanceExpression.Resolve (ec); else if (ec.IsStatic) { if (!delegate_method.IsStatic) { Report.Error (120, loc, @@ -751,12 +797,12 @@ namespace Mono.CSharp { delegate_method.Name); return null; } - mg.InstanceExpression = null; + delegate_instance_expression = null; } else - mg.InstanceExpression = ec.GetThis (loc); + delegate_instance_expression = ec.GetThis (loc); - if (mg.InstanceExpression != null && mg.InstanceExpression.Type.IsValueType) - mg.InstanceExpression = new BoxedCast (mg.InstanceExpression); + if (delegate_instance_expression != null && delegate_instance_expression.Type.IsValueType) + delegate_instance_expression = new BoxedCast (delegate_instance_expression); method_group = mg; eclass = ExprClass.Value; @@ -789,7 +835,7 @@ namespace Mono.CSharp { return null; } } - + // // A delegate-creation-expression, invoked from the `New' class // @@ -824,6 +870,9 @@ namespace Mono.CSharp { Expression e = a.Expr; + if (e is AnonymousMethod && RootContext.Version != LanguageVersion.ISO_1) + return ((AnonymousMethod) e).Compatible (ec, type, false); + MethodGroupExpr mg = e as MethodGroupExpr; if (mg != null) return ResolveMethodGroupExpr (ec, mg); @@ -831,7 +880,7 @@ namespace Mono.CSharp { Type e_type = e.Type; if (!TypeManager.IsDelegateType (e_type)) { - e.Error_UnexpectedKind ("method"); + Report.Error (149, loc, "Method name expected"); return null; } @@ -852,7 +901,7 @@ namespace Mono.CSharp { return null; } - method_group.InstanceExpression = e; + delegate_instance_expression = e; delegate_method = method_group.Methods [0]; eclass = ExprClass.Value;