// Authors: Miguel de Icaza (miguel@gnu.org)
// Marek Safar (marek.safar@gmail.com)
//
-// Licensed under the terms of the GNU GPL
+// Dual licensed under the terms of the MIT X11 or GNU GPL
//
-// (C) 2007 Novell, Inc
+// Copyright 2007-2008 Novell, Inc
//
using System;
// A list of Parameters (explicitly typed parameters)
// An ImplicitLambdaParameter
//
- public LambdaExpression (AnonymousMethodExpression parent,
- GenericMethod generic, TypeContainer host,
- Parameters parameters, Block container,
- Location loc)
- : base (parent, generic, host, parameters, container, loc)
+ public LambdaExpression (Parameters parameters, Location loc)
+ : base (parameters, loc)
{
if (parameters.Count > 0)
explicit_parameters = !(parameters.FixedParameters [0] is ImplicitLambdaParameter);
protected override Expression CreateExpressionTree (EmitContext ec, Type delegate_type)
{
+ if (ec.IsInProbingMode)
+ return this;
+
Expression args = Parameters.CreateExpressionTree (ec, loc);
Expression expr = Block.CreateExpressionTree (ec);
if (expr == null)
if (!TypeManager.IsDelegateType (delegateType))
return null;
- ParameterData d_params = TypeManager.GetDelegateParameters (delegateType);
+ AParametersCollection d_params = TypeManager.GetDelegateParameters (delegateType);
if (explicit_parameters) {
if (!VerifyExplicitParameters (delegateType, d_params, ec.IsInProbingMode))
if (!VerifyParameterCompatibility (delegateType, d_params, ec.IsInProbingMode))
return null;
- if (Parameters.Types == null)
- Parameters.Types = new Type [Parameters.Count];
-
+ Type [] ptypes = new Type [Parameters.Count];
for (int i = 0; i < d_params.Count; i++) {
// D has no ref or out parameters
- if ((d_params.ParameterModifier (i) & Parameter.Modifier.ISBYREF) != 0)
+ if ((d_params.FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) != 0)
return null;
Type d_param = d_params.Types [i];
if (d_param.IsGenericParameter)
d_param = delegateType.GetGenericArguments () [d_param.GenericParameterPosition];
#endif
- // When inferred context exists all generics parameters have type replacements
+ //
+ // When type inference context exists try to apply inferred type arguments
+ //
if (tic != null) {
d_param = tic.InflateGenericArgument (d_param);
}
- Parameters.Types [i] = Parameters.FixedParameters[i].ParameterType = d_param;
+ ptypes [i] = d_param;
+ ((ImplicitLambdaParameter) Parameters.FixedParameters [i]).Type = d_param;
}
+
+ Parameters.Types = ptypes;
return Parameters;
}
return this;
}
- protected override AnonymousMethod CompatibleMethodFactory (Type returnType, Type delegateType, Parameters p, ToplevelBlock b)
+ protected override AnonymousMethodBody CompatibleMethodFactory (Type returnType, Type delegateType, Parameters p, ToplevelBlock b)
{
- return new LambdaMethod (RootScope, Host,
- GenericMethod, p, Container, b, returnType,
- delegateType, loc);
+ return new LambdaMethod (p, b, returnType, delegateType, loc);
}
public override string GetSignatureForError ()
}
}
- public class LambdaMethod : AnonymousMethod
+ public class LambdaMethod : AnonymousMethodBody
{
- public LambdaMethod (RootScopeInfo root_scope,
- DeclSpace host, GenericMethod generic,
- Parameters parameters, Block container,
+ public LambdaMethod (Parameters parameters,
ToplevelBlock block, Type return_type, Type delegate_type,
Location loc)
- : base (root_scope, host, generic, parameters, container, block,
- return_type, delegate_type, loc)
+ : base (parameters, block, return_type, delegate_type, loc)
{
}
return "lambda expression";
}
}
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ Expression args = parameters.CreateExpressionTree (ec, loc);
+ Expression expr = Block.CreateExpressionTree (ec);
+ if (expr == null)
+ return null;
+
+ ArrayList arguments = new ArrayList (2);
+ arguments.Add (new Argument (expr));
+ arguments.Add (new Argument (args));
+ return CreateExpressionFactoryCall ("Lambda",
+ new TypeArguments (loc, new TypeExpression (type, loc)),
+ arguments);
+ }
}
//
//
public class ContextualReturn : Return
{
- bool statement_return;
-
public ContextualReturn (Expression expr)
: base (expr, expr.Location)
{
public override void Emit (EmitContext ec)
{
- if (statement_return) {
- ExpressionStatement es = Expr as ExpressionStatement;
- if (es == null) {
- Expr.Error_InvalidExpressionStatement ();
- return;
- }
-
- es.EmitStatement (ec);
+ if (ec.ReturnType == TypeManager.void_type) {
+ ((ExpressionStatement) Expr).EmitStatement (ec);
+ ec.ig.Emit (OpCodes.Ret);
return;
}
-
+
base.Emit (ec);
}
- public override bool Resolve (EmitContext ec)
- {
+ protected override bool DoResolve (EmitContext ec)
+ {
+ //
+ // When delegate returns void, only expression statements can be used
+ //
if (ec.ReturnType == TypeManager.void_type) {
- statement_return = true;
- return Expr.Resolve (ec) != null;
+ Expr = Expr.Resolve (ec);
+ if (Expr == null)
+ return false;
+
+ if (Expr is ExpressionStatement)
+ return true;
+
+ Expr.Error_InvalidExpressionStatement ();
+ return false;
}
- return base.Resolve (ec);
+ return base.DoResolve (ec);
}
}
}