X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Flambda.cs;h=9c804ceca575e6730e194e54a8bce5735a24cb81;hb=0db4b09607843d097a6f60f5c8101bb7ef8f3866;hp=eb4907b1816bd663a7df3120411ff50119a3f3ca;hpb=0900c61969ca862b0bcc967b4413e539acf07dbb;p=mono.git diff --git a/mcs/mcs/lambda.cs b/mcs/mcs/lambda.cs index eb4907b1816..9c804ceca57 100644 --- a/mcs/mcs/lambda.cs +++ b/mcs/mcs/lambda.cs @@ -7,11 +7,14 @@ // Dual licensed under the terms of the MIT X11 or GNU GPL // // Copyright 2007-2008 Novell, Inc +// Copyright 2011 Xamarin Inc // -using System; -using System.Reflection; +#if STATIC +using IKVM.Reflection.Emit; +#else using System.Reflection.Emit; +#endif namespace Mono.CSharp { public class LambdaExpression : AnonymousMethodExpression @@ -31,7 +34,7 @@ namespace Mono.CSharp { if (ec.IsInProbingMode) return this; - BlockContext bc = new BlockContext (ec.MemberContext, ec.CurrentBlock.Explicit, TypeManager.void_type) { + BlockContext bc = new BlockContext (ec.MemberContext, ec.ConstructorBlock, ec.BuiltinTypes.Void) { CurrentAnonymousMethod = ec.CurrentAnonymousMethod }; @@ -59,10 +62,10 @@ namespace Mono.CSharp { if (!delegateType.IsDelegate) return null; - AParametersCollection d_params = Delegate.GetParameters (ec.Compiler, delegateType); + AParametersCollection d_params = Delegate.GetParameters (delegateType); if (HasExplicitParameters) { - if (!VerifyExplicitParameters (ec, delegateType, d_params)) + if (!VerifyExplicitParameters (ec, tic, delegateType, d_params)) return null; return Parameters; @@ -72,13 +75,13 @@ namespace Mono.CSharp { // If L has an implicitly typed parameter list we make implicit parameters explicit // Set each parameter of L is given the type of the corresponding parameter in D // - if (!VerifyParameterCompatibility (ec, delegateType, d_params, ec.IsInProbingMode)) + if (!VerifyParameterCompatibility (ec, tic, delegateType, d_params, ec.IsInProbingMode)) return null; TypeSpec [] ptypes = new TypeSpec [Parameters.Count]; for (int i = 0; i < d_params.Count; i++) { // D has no ref or out parameters - if ((d_params.FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) != 0) + if ((d_params.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != 0) return null; TypeSpec d_param = d_params.Types [i]; @@ -87,12 +90,12 @@ namespace Mono.CSharp { // When type inference context exists try to apply inferred type arguments // if (tic != null) { - d_param = tic.InflateGenericArgument (d_param); + d_param = tic.InflateGenericArgument (ec, d_param); } ptypes [i] = d_param; ImplicitLambdaParameter ilp = (ImplicitLambdaParameter) Parameters.FixedParameters [i]; - ilp.Type = d_param; + ilp.SetParameterType (d_param); ilp.Resolve (null, i); } @@ -100,45 +103,44 @@ namespace Mono.CSharp { return Parameters; } - protected override Expression DoResolve (ResolveContext ec) + protected override AnonymousMethodBody CompatibleMethodFactory (TypeSpec returnType, TypeSpec delegateType, ParametersCompiled p, ParametersBlock b) + { + return new LambdaMethod (p, b, returnType, delegateType, loc); + } + + protected override bool DoResolveParameters (ResolveContext rc) { // // Only explicit parameters can be resolved at this point // if (HasExplicitParameters) { - if (!Parameters.Resolve (ec)) - return null; + return Parameters.Resolve (rc); } - eclass = ExprClass.Value; - type = InternalType.AnonymousMethod; - return this; - } - - protected override AnonymousMethodBody CompatibleMethodFactory (TypeSpec returnType, TypeSpec delegateType, ParametersCompiled p, ToplevelBlock b) - { - return new LambdaMethod (p, b, returnType, delegateType, loc); + return true; } public override string GetSignatureForError () { return "lambda expression"; } + + public override object Accept (StructuralVisitor visitor) + { + return visitor.Visit (this); + } } - public class LambdaMethod : AnonymousMethodBody + class LambdaMethod : AnonymousMethodBody { public LambdaMethod (ParametersCompiled parameters, - ToplevelBlock block, TypeSpec return_type, TypeSpec delegate_type, + ParametersBlock block, TypeSpec return_type, TypeSpec delegate_type, Location loc) : base (parameters, block, return_type, delegate_type, loc) { } - protected override void CloneTo (CloneContext clonectx, Expression target) - { - // TODO: nothing ?? - } + #region Properties public override string ContainerType { get { @@ -146,6 +148,13 @@ namespace Mono.CSharp { } } + #endregion + + protected override void CloneTo (CloneContext clonectx, Expression target) + { + // TODO: nothing ?? + } + public override Expression CreateExpressionTree (ResolveContext ec) { BlockContext bc = new BlockContext (ec.MemberContext, Block, ReturnType); @@ -173,7 +182,7 @@ namespace Mono.CSharp { ExpressionStatement statement; public ContextualReturn (Expression expr) - : base (expr, expr.Location) + : base (expr, expr.StartLocation) { } @@ -182,15 +191,19 @@ namespace Mono.CSharp { return Expr.CreateExpressionTree (ec); } - public override void Emit (EmitContext ec) + protected override void DoEmit (EmitContext ec) { if (statement != null) { statement.EmitStatement (ec); - ec.Emit (OpCodes.Ret); + if (unwind_protect) + ec.Emit (OpCodes.Leave, ec.CreateReturnLabel ()); + else { + ec.Emit (OpCodes.Ret); + } return; } - base.Emit (ec); + base.DoEmit (ec); } protected override bool DoResolve (BlockContext ec) @@ -198,14 +211,20 @@ namespace Mono.CSharp { // // When delegate returns void, only expression statements can be used // - if (ec.ReturnType == TypeManager.void_type) { + if (ec.ReturnType.Kind == MemberKind.Void) { Expr = Expr.Resolve (ec); if (Expr == null) return false; statement = Expr as ExpressionStatement; - if (statement == null) - Expr.Error_InvalidExpressionStatement (ec); + if (statement == null) { + var reduced = Expr as IReducedExpressionStatement; + if (reduced != null) { + statement = EmptyExpressionStatement.Instance; + } else { + Expr.Error_InvalidExpressionStatement (ec); + } + } return true; }