~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/lambda.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// lambda.cs: support for lambda expressions
3
 
//
4
 
// Authors: Miguel de Icaza (miguel@gnu.org)
5
 
//          Marek Safar (marek.safar@gmail.com)
6
 
//
7
 
// Dual licensed under the terms of the MIT X11 or GNU GPL
8
 
//
9
 
// Copyright 2007-2008 Novell, Inc
10
 
// Copyright 2011 Xamarin Inc
11
 
//
12
 
 
13
 
#if STATIC
14
 
using IKVM.Reflection.Emit;
15
 
#else
16
 
using System.Reflection.Emit;
17
 
#endif
18
 
 
19
 
namespace Mono.CSharp {
20
 
        public class LambdaExpression : AnonymousMethodExpression
21
 
        {
22
 
                //
23
 
                // The parameters can either be:
24
 
                //    A list of Parameters (explicitly typed parameters)
25
 
                //    An ImplicitLambdaParameter
26
 
                //
27
 
                public LambdaExpression (Location loc)
28
 
                        : base (loc)
29
 
                {
30
 
                }
31
 
 
32
 
                protected override Expression CreateExpressionTree (ResolveContext ec, TypeSpec delegate_type)
33
 
                {
34
 
                        if (ec.IsInProbingMode)
35
 
                                return this;
36
 
 
37
 
                        BlockContext bc = new BlockContext (ec.MemberContext, ec.ConstructorBlock, ec.BuiltinTypes.Void) {
38
 
                                CurrentAnonymousMethod = ec.CurrentAnonymousMethod
39
 
                        };
40
 
 
41
 
                        Expression args = Parameters.CreateExpressionTree (bc, loc);
42
 
                        Expression expr = Block.CreateExpressionTree (ec);
43
 
                        if (expr == null)
44
 
                                return null;
45
 
 
46
 
                        Arguments arguments = new Arguments (2);
47
 
                        arguments.Add (new Argument (expr));
48
 
                        arguments.Add (new Argument (args));
49
 
                        return CreateExpressionFactoryCall (ec, "Lambda",
50
 
                                new TypeArguments (new TypeExpression (delegate_type, loc)),
51
 
                                arguments);
52
 
                }
53
 
 
54
 
                public override bool HasExplicitParameters {
55
 
                        get {
56
 
                                return Parameters.Count > 0 && !(Parameters.FixedParameters [0] is ImplicitLambdaParameter);
57
 
                        }
58
 
                }
59
 
 
60
 
                protected override ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegateType)
61
 
                {
62
 
                        if (!delegateType.IsDelegate)
63
 
                                return null;
64
 
 
65
 
                        AParametersCollection d_params = Delegate.GetParameters (delegateType);
66
 
 
67
 
                        if (HasExplicitParameters) {
68
 
                                if (!VerifyExplicitParameters (ec, delegateType, d_params))
69
 
                                        return null;
70
 
 
71
 
                                return Parameters;
72
 
                        }
73
 
 
74
 
                        //
75
 
                        // If L has an implicitly typed parameter list we make implicit parameters explicit
76
 
                        // Set each parameter of L is given the type of the corresponding parameter in D
77
 
                        //
78
 
                        if (!VerifyParameterCompatibility (ec, delegateType, d_params, ec.IsInProbingMode))
79
 
                                return null;
80
 
 
81
 
                        TypeSpec [] ptypes = new TypeSpec [Parameters.Count];
82
 
                        for (int i = 0; i < d_params.Count; i++) {
83
 
                                // D has no ref or out parameters
84
 
                                if ((d_params.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != 0)
85
 
                                        return null;
86
 
 
87
 
                                TypeSpec d_param = d_params.Types [i];
88
 
 
89
 
                                //
90
 
                                // When type inference context exists try to apply inferred type arguments
91
 
                                //
92
 
                                if (tic != null) {
93
 
                                        d_param = tic.InflateGenericArgument (ec, d_param);
94
 
                                }
95
 
 
96
 
                                ptypes [i] = d_param;
97
 
                                ImplicitLambdaParameter ilp = (ImplicitLambdaParameter) Parameters.FixedParameters [i];
98
 
                                ilp.SetParameterType (d_param);
99
 
                                ilp.Resolve (null, i);
100
 
                        }
101
 
 
102
 
                        Parameters.Types = ptypes;
103
 
                        return Parameters;
104
 
                }
105
 
 
106
 
                protected override AnonymousMethodBody CompatibleMethodFactory (TypeSpec returnType, TypeSpec delegateType, ParametersCompiled p, ParametersBlock b)
107
 
                {
108
 
                        return new LambdaMethod (p, b, returnType, delegateType, loc);
109
 
                }
110
 
 
111
 
                protected override bool DoResolveParameters (ResolveContext rc)
112
 
                {
113
 
                        //
114
 
                        // Only explicit parameters can be resolved at this point
115
 
                        //
116
 
                        if (HasExplicitParameters) {
117
 
                                return Parameters.Resolve (rc);
118
 
                        }
119
 
 
120
 
                        return true;
121
 
                }
122
 
 
123
 
                public override string GetSignatureForError ()
124
 
                {
125
 
                        return "lambda expression";
126
 
                }
127
 
                
128
 
                public override object Accept (StructuralVisitor visitor)
129
 
                {
130
 
                        return visitor.Visit (this);
131
 
                }
132
 
        }
133
 
 
134
 
        class LambdaMethod : AnonymousMethodBody
135
 
        {
136
 
                public LambdaMethod (ParametersCompiled parameters,
137
 
                                        ParametersBlock block, TypeSpec return_type, TypeSpec delegate_type,
138
 
                                        Location loc)
139
 
                        : base (parameters, block, return_type, delegate_type, loc)
140
 
                {
141
 
                }
142
 
 
143
 
                #region Properties
144
 
 
145
 
                public override string ContainerType {
146
 
                        get {
147
 
                                return "lambda expression";
148
 
                        }
149
 
                }
150
 
 
151
 
                #endregion
152
 
 
153
 
                protected override void CloneTo (CloneContext clonectx, Expression target)
154
 
                {
155
 
                        // TODO: nothing ??
156
 
                }
157
 
 
158
 
                public override Expression CreateExpressionTree (ResolveContext ec)
159
 
                {
160
 
                        BlockContext bc = new BlockContext (ec.MemberContext, Block, ReturnType);
161
 
                        Expression args = parameters.CreateExpressionTree (bc, loc);
162
 
                        Expression expr = Block.CreateExpressionTree (ec);
163
 
                        if (expr == null)
164
 
                                return null;
165
 
 
166
 
                        Arguments arguments = new Arguments (2);
167
 
                        arguments.Add (new Argument (expr));
168
 
                        arguments.Add (new Argument (args));
169
 
                        return CreateExpressionFactoryCall (ec, "Lambda",
170
 
                                new TypeArguments (new TypeExpression (type, loc)),
171
 
                                arguments);
172
 
                }
173
 
        }
174
 
 
175
 
        //
176
 
        // This is a return statement that is prepended lambda expression bodies that happen
177
 
        // to be expressions.  Depending on the return type of the delegate this will behave
178
 
        // as either { expr (); return (); } or { return expr (); }
179
 
        //
180
 
        public class ContextualReturn : Return
181
 
        {
182
 
                ExpressionStatement statement;
183
 
 
184
 
                public ContextualReturn (Expression expr)
185
 
                        : base (expr, expr.Location)
186
 
                {
187
 
                }
188
 
 
189
 
                public override Expression CreateExpressionTree (ResolveContext ec)
190
 
                {
191
 
                        return Expr.CreateExpressionTree (ec);
192
 
                }
193
 
 
194
 
                protected override void DoEmit (EmitContext ec)
195
 
                {
196
 
                        if (statement != null) {
197
 
                                statement.EmitStatement (ec);
198
 
                                if (unwind_protect)
199
 
                                        ec.Emit (OpCodes.Leave, ec.CreateReturnLabel ());
200
 
                                else {
201
 
                                        ec.Emit (OpCodes.Ret);
202
 
                                }
203
 
                                return;
204
 
                        }
205
 
 
206
 
                        base.DoEmit (ec);
207
 
                }
208
 
 
209
 
                protected override bool DoResolve (BlockContext ec)
210
 
                {
211
 
                        //
212
 
                        // When delegate returns void, only expression statements can be used
213
 
                        //
214
 
                        if (ec.ReturnType.Kind == MemberKind.Void) {
215
 
                                Expr = Expr.Resolve (ec);
216
 
                                if (Expr == null)
217
 
                                        return false;
218
 
 
219
 
                                statement = Expr as ExpressionStatement;
220
 
                                if (statement == null)
221
 
                                        Expr.Error_InvalidExpressionStatement (ec);
222
 
 
223
 
                                return true;
224
 
                        }
225
 
 
226
 
                        return base.DoResolve (ec);
227
 
                }
228
 
        }
229
 
}