// Miguel de Icaza (miguel@ximian.com)
// Marek Safar (marek.safar@gmail.com)
//
-// Licensed under the terms of the GNU GPL
-//
-// (C) 2001 Ximian, Inc (http://www.ximian.com)
+// Dual licensed under the terms of the MIT X11 or GNU GPL
//
+// Copyright 2001 Ximian, Inc (http://www.ximian.com)
+// Copyright 2003-2008 Novell, Inc (http://www.ximian.com)
//
using System;
/// </summary>
public class Delegate : DeclSpace, IMemberContainer
{
- public Expression ReturnType;
+ FullNamedExpression ReturnType;
public Parameters Parameters;
public ConstructorBuilder ConstructorBuilder;
Modifiers.UNSAFE |
Modifiers.PRIVATE;
- public Delegate (NamespaceEntry ns, DeclSpace parent, Expression type,
+ public Delegate (NamespaceEntry ns, DeclSpace parent, FullNamedExpression type,
int mod_flags, MemberName name, Parameters param_list,
Attributes attrs)
: base (ns, parent, name, attrs)
Parameters.VerifyClsCompliance ();
if (!AttributeTester.IsClsCompliant (ReturnType.Type)) {
- Report.Error (3002, Location, "Return type of `{0}' is not CLS-compliant", GetSignatureForError ());
+ Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant",
+ GetSignatureForError ());
}
return true;
}
return (MethodInfo) mg.Methods[0];
}
+ //
+ // 15.2 Delegate compatibility
+ //
public static bool IsTypeCovariant (Expression a, Type b)
{
- Type a_type = a.Type;
- if (a_type == b)
+ //
+ // For each value parameter (a parameter with no ref or out modifier), an
+ // identity conversion or implicit reference conversion exists from the
+ // parameter type in D to the corresponding parameter type in M
+ //
+ if (a.Type == b)
return true;
if (RootContext.Version == LanguageVersion.ISO_1)
return false;
- if (a.Type.IsValueType)
- return false;
-
- return Convert.ImplicitReferenceConversionCore (
- a, b);
+ return Convert.ImplicitReferenceConversionExists (a, b);
}
/// <summary>
/// Returns the method itself if okay and null if not.
/// </summary>
public static MethodBase VerifyMethod (Type container_type, Type delegate_type,
- MethodGroupExpr old_mg, MethodBase mb,
- Location loc)
+ MethodGroupExpr old_mg, MethodBase mb)
{
MethodInfo invoke_mb = GetInvokeMethod (container_type, delegate_type);
if (invoke_mb == null)
protected MethodGroupExpr method_group;
protected Expression delegate_instance_expression;
- ArrayList CreateDelegateMethodArguments (MethodInfo invoke_method)
+ public static ArrayList CreateDelegateMethodArguments (MethodInfo invoke_method, Location loc)
{
ParameterData pd = TypeManager.GetParameterData (invoke_method);
ArrayList delegate_arguments = new ArrayList (pd.Count);
return delegate_arguments;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ MemberAccess ma = new MemberAccess (new MemberAccess (new QualifiedAliasMember ("global", "System", loc), "Delegate", loc), "CreateDelegate", loc);
+
+ ArrayList args = new ArrayList (3);
+ args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+ args.Add (new Argument (new NullLiteral (loc)));
+ args.Add (new Argument (new TypeOfMethodInfo (delegate_method, loc)));
+ Expression e = new Invocation (ma, args).Resolve (ec);
+ if (e == null)
+ return null;
+
+ e = Convert.ExplicitConversion (ec, e, type, loc);
+ if (e == null)
+ return null;
+
+ return e.CreateExpressionTree (ec);
+ }
+
public override Expression DoResolve (EmitContext ec)
{
constructor_method = Delegate.GetConstructor (ec.ContainerType, type);
method_group.DelegateType = type;
method_group.CustomErrorHandler = this;
- ArrayList arguments = CreateDelegateMethodArguments (invoke_method);
+ ArrayList arguments = CreateDelegateMethodArguments (invoke_method, loc);
method_group = method_group.OverloadResolve (ec, ref arguments, false, loc);
if (method_group == null)
return null;
delegate_method = (MethodInfo) method_group;
+ Invocation.IsSpecialMethodInvocation (delegate_method, loc);
+
ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr;
if (emg != null) {
delegate_instance_expression = emg.ExtensionExpression;
//
if (delegate_instance_expression != null)
return;
-
- if (method_group.InstanceExpression != null)
+
+ if (method_group.InstanceExpression != null) {
delegate_instance_expression = method_group.InstanceExpression;
- else if (!delegate_method.IsStatic && !ec.IsStatic)
+ Type instance_type = delegate_instance_expression.Type;
+ if (TypeManager.IsValueType (instance_type) || TypeManager.IsGenericParameter (instance_type)) {
+ delegate_instance_expression = new BoxedCast (
+ delegate_instance_expression, TypeManager.object_type);
+ }
+ } else if (!delegate_method.IsStatic && !ec.IsStatic) {
delegate_instance_expression = ec.GetThis (loc);
-
- if (delegate_instance_expression != null && delegate_instance_expression.Type.IsValueType)
- delegate_instance_expression = new BoxedCast (
- delegate_instance_expression, TypeManager.object_type);
+ }
}
public override void Emit (EmitContext ec)
return null;
foreach (MethodInfo mi in mg.Methods){
- MethodBase mb = Delegate.VerifyMethod (mg.DeclaringType, target_type, mg, mi, Location.Null);
+ MethodBase mb = Delegate.VerifyMethod (mg.DeclaringType, target_type, mg, mi);
if (mb != null)
return mb;
}
return null;
}
+ public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+ {
+ if (delegate_instance_expression != null)
+ delegate_instance_expression.MutateHoistedGenericType (storey);
+
+ delegate_method = storey.MutateGenericMethod (delegate_method);
+ constructor_method = storey.MutateConstructor (constructor_method);
+ }
+
#region IErrorHandler Members
public bool NoExactMatch (EmitContext ec, MethodBase method)
Argument a = (Argument) Arguments [0];
if (!a.ResolveMethodGroup (ec))
return null;
-
+
Expression e = a.Expr;
- if (e is AnonymousMethodExpression && RootContext.Version != LanguageVersion.ISO_1) {
- e = ((AnonymousMethodExpression) e).Compatible (ec, type);
+
+ AnonymousMethodExpression ame = e as AnonymousMethodExpression;
+ if (ame != null && RootContext.Version != LanguageVersion.ISO_1) {
+ e = ame.Compatible (ec, type);
if (e == null)
return null;
+
return e.Resolve (ec);
}
TypeManager.GetFullNameSignature (delegate_method));
}
- if (Invocation.IsMethodExcluded (delegate_method)) {
+ if (Invocation.IsMethodExcluded (delegate_method, loc)) {
Report.SymbolRelatedToPreviousError (delegate_method);
Report.Error (1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute",
TypeManager.CSharpSignature (delegate_method));
readonly Expression InstanceExpr;
readonly ArrayList Arguments;
- MethodBase method;
+ MethodInfo method;
public DelegateInvocation (Expression instance_expr, ArrayList args, Location loc)
{
this.Arguments = args;
this.loc = loc;
}
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ ArrayList args;
+ if (Arguments == null)
+ args = new ArrayList (1);
+ else
+ args = new ArrayList (Arguments.Count + 1);
+
+ args.Add (new Argument (InstanceExpr.CreateExpressionTree (ec)));
+ if (Arguments != null) {
+ foreach (Argument a in Arguments)
+ args.Add (new Argument (a.Expr.CreateExpressionTree (ec)));
+ }
+
+ return CreateExpressionFactoryCall ("Invoke", args);
+ }
public override Expression DoResolve (EmitContext ec)
{
if (InstanceExpr is EventExpr) {
-
- EventInfo ei = ((EventExpr) InstanceExpr).EventInfo;
-
- Expression ml = MemberLookup (
- ec.ContainerType, ec.ContainerType, ei.Name,
- MemberTypes.Event, AllBindingFlags | BindingFlags.DeclaredOnly, loc);
-
- if (ml == null) {
- //
- // If this is the case, then the Event does not belong
- // to this Type and so, according to the spec
- // cannot be accessed directly
- //
- // Note that target will not appear as an EventExpr
- // in the case it is being referenced within the same type container;
- // it will appear as a FieldExpr in that case.
- //
-
- Assign.error70 (ei, loc);
- return null;
- }
+ ((EventExpr) InstanceExpr).Error_CannotAssign ();
+ return null;
}
-
Type del_type = InstanceExpr.Type;
if (del_type == null)
return null;
return null;
method = Delegate.GetInvokeMethod (ec.ContainerType, del_type);
- type = ((MethodInfo) method).ReturnType;
- type = TypeManager.TypeToCoreType (type);
+ type = TypeManager.TypeToCoreType (method.ReturnType);
eclass = ExprClass.Value;
return this;
//
// Pop the return value if there is one
//
- if (method is MethodInfo){
- Type ret = ((MethodInfo)method).ReturnType;
- if (TypeManager.TypeToCoreType (ret) != TypeManager.void_type)
- ec.ig.Emit (OpCodes.Pop);
- }
+ if (type != TypeManager.void_type)
+ ec.ig.Emit (OpCodes.Pop);
}
+ public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+ {
+ method = storey.MutateGenericMethod (method);
+ type = storey.MutateType (type);
+
+ if (Arguments != null) {
+ foreach (Argument a in Arguments) {
+ a.Expr.MutateHoistedGenericType (storey);
+ }
+ }
+
+ InstanceExpr.MutateHoistedGenericType (storey);
+ }
}
}