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

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.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
ļ»æ// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
 
2
// 
 
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
 
4
// software and associated documentation files (the "Software"), to deal in the Software
 
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
 
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
 
7
// to whom the Software is furnished to do so, subject to the following conditions:
 
8
// 
 
9
// The above copyright notice and this permission notice shall be included in all copies or
 
10
// substantial portions of the Software.
 
11
// 
 
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
17
// DEALINGS IN THE SOFTWARE.
 
18
 
 
19
using System;
 
20
using System.IO;
 
21
using System.Linq;
 
22
 
 
23
using ICSharpCode.NRefactory.CSharp.TypeSystem;
 
24
using ICSharpCode.NRefactory.Semantics;
 
25
using ICSharpCode.NRefactory.TypeSystem;
 
26
using ICSharpCode.NRefactory.TypeSystem.Implementation;
 
27
using NUnit.Framework;
 
28
 
 
29
namespace ICSharpCode.NRefactory.CSharp.Resolver
 
30
{
 
31
        [TestFixture]
 
32
        public class LambdaTests : ResolverTestBase
 
33
        {
 
34
                [Test]
 
35
                public void SimpleLambdaTest()
 
36
                {
 
37
                        string program = @"using System;
 
38
class TestClass {
 
39
        static void Main() {
 
40
                Test(i => Console.WriteLine(i));
 
41
        }
 
42
        public void Test(Action<int> ac) { ac(42); }
 
43
}";
 
44
                        var lrr = Resolve<LocalResolveResult>(program.Replace("(i)", "($i$)"));
 
45
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
46
                        
 
47
                        lrr = Resolve<LocalResolveResult>(program.Replace("i =>", "$i$ =>"));
 
48
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
49
                }
 
50
                
 
51
                [Test]
 
52
                public void LambdaInConstructorTest()
 
53
                {
 
54
                        string program = @"using System;
 
55
class TestClass {
 
56
        static void Main() {
 
57
                TestClass t = new TestClass(i => Console.WriteLine($i$));
 
58
        }
 
59
        public TestClass(Action<int> ac) { ac(42); }
 
60
}";
 
61
                        var lrr = Resolve<LocalResolveResult>(program);
 
62
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
63
                }
 
64
                
 
65
                [Test]
 
66
                public void LambdaInGenericConstructorTest()
 
67
                {
 
68
                        string program = @"using System;
 
69
class TestClass {
 
70
        static void Main() {
 
71
                var t = new SomeClass<string>(i => Console.WriteLine($i$));
 
72
        }
 
73
}
 
74
class SomeClass<T> {
 
75
        public SomeClass(Action<T> ac) { }
 
76
}";
 
77
                        var lrr = Resolve<LocalResolveResult>(program);
 
78
                        Assert.AreEqual("System.String", lrr.Type.ReflectionName);
 
79
                }
 
80
                
 
81
                #region Lambda In Array Initializer
 
82
                [Test]
 
83
                public void LambdaInArrayInitializer1()
 
84
                {
 
85
                        string program = @"using System;
 
86
class TestClass {
 
87
        static void Main() {
 
88
                Converter<int, string>[] arr = {
 
89
                        i => $i$.ToString()
 
90
                };
 
91
        }
 
92
}";
 
93
                        var lrr = Resolve<LocalResolveResult>(program);
 
94
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
95
                }
 
96
                
 
97
                [Test]
 
98
                public void LambdaInArrayInitializer2()
 
99
                {
 
100
                        string program = @"using System;
 
101
class TestClass {
 
102
        static void Main() {
 
103
                a = new Converter<int, string>[] {
 
104
                        i => $i$.ToString()
 
105
                };
 
106
        }
 
107
}";
 
108
                        var lrr = Resolve<LocalResolveResult>(program);
 
109
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
110
                }
 
111
                
 
112
                [Test]
 
113
                public void LambdaInArrayInitializer3()
 
114
                {
 
115
                        string program = @"using System;
 
116
class TestClass {
 
117
        Converter<int, string>[] field = new Converter<int, string>[] {
 
118
                i => $i$.ToString()
 
119
        };
 
120
}";
 
121
                        var lrr = Resolve<LocalResolveResult>(program);
 
122
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
123
                }
 
124
                
 
125
                [Test]
 
126
                public void LambdaInArrayInitializer4()
 
127
                {
 
128
                        string program = @"using System;
 
129
class TestClass {
 
130
        Converter<int, string>[] field = {
 
131
                i => $i$.ToString()
 
132
        };
 
133
}";
 
134
                        var lrr = Resolve<LocalResolveResult>(program);
 
135
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
136
                }
 
137
                
 
138
                [Test]
 
139
                public void LambdaIn2DArrayInitializer()
 
140
                {
 
141
                        string program = @"using System;
 
142
class TestClass {
 
143
        static void Main() {
 
144
                Converter<int, string>[,] arr = {
 
145
                        { i => $i$.ToString() }
 
146
                };
 
147
        }
 
148
}";
 
149
                        var lrr = Resolve<LocalResolveResult>(program);
 
150
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
151
                }
 
152
                
 
153
                [Test]
 
154
                public void LambdaInInferred2DArrayInitializer()
 
155
                {
 
156
                        string program = @"using System;
 
157
class TestClass {
 
158
        static void Main() {
 
159
                var c = new [,] { { null, (Converter<int, string>)null }, { a => $a$.ToString(), b => b.ToString() }};
 
160
        }
 
161
}";
 
162
                        var lrr = Resolve<LocalResolveResult>(program);
 
163
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
164
                }
 
165
                #endregion
 
166
                
 
167
                #region Lambda In Collection Initializer
 
168
                [Test]
 
169
                public void LambdaInCollectionInitializer1()
 
170
                {
 
171
                        string program = @"using System; using System.Collections.Generic;
 
172
class TestClass {
 
173
        static void Main() {
 
174
                a = new List<Converter<int, string>> {
 
175
                        i => $i$.ToString()
 
176
                };
 
177
        }
 
178
}";
 
179
                        var lrr = Resolve<LocalResolveResult>(program);
 
180
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
181
                }
 
182
                
 
183
                [Test]
 
184
                public void LambdaInCollectionInitializer2()
 
185
                {
 
186
                        string program = @"using System; using System.Collections.Generic;
 
187
class TestClass {
 
188
        static void Main() {
 
189
                a = new Dictionary<Func<char, string>, Converter<int, string>> {
 
190
                        { i => $i$.ToString(), i => i.ToString() }
 
191
                };
 
192
        }
 
193
}";
 
194
                        var lrr = Resolve<LocalResolveResult>(program);
 
195
                        Assert.AreEqual("System.Char", lrr.Type.ReflectionName);
 
196
                }
 
197
                
 
198
                [Test]
 
199
                public void LambdaInCollectionInitializer3()
 
200
                {
 
201
                        string program = @"using System; using System.Collections.Generic;
 
202
class TestClass {
 
203
        static void Main() {
 
204
                a = new Dictionary<Func<char, string>, Converter<int, string>> {
 
205
                        { i => i.ToString(), $i$ => i.ToString() }
 
206
                };
 
207
        }
 
208
}";
 
209
                        var lrr = Resolve<LocalResolveResult>(program);
 
210
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
211
                }
 
212
                #endregion
 
213
                
 
214
                [Test]
 
215
                public void LambdaInObjectInitializerTest()
 
216
                {
 
217
                        string program = @"using System;
 
218
class X {
 
219
        void SomeMethod() {
 
220
                Helper h = new Helper {
 
221
                        F = i => $i$.ToString()
 
222
                };
 
223
        }
 
224
}
 
225
class Helper {
 
226
        public Converter<int, string> F;
 
227
}";
 
228
                        var lrr = Resolve<LocalResolveResult>(program);
 
229
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
230
                }
 
231
                
 
232
                [Test]
 
233
                public void LambdaExpressionInCastExpression()
 
234
                {
 
235
                        string program = @"using System;
 
236
static class TestClass {
 
237
        static void Main(string[] args) {
 
238
                var f = (Func<int, string>) ( i => $i$ );
 
239
        }
 
240
        public delegate R Func<T, R>(T arg);
 
241
}";
 
242
                        var lrr = Resolve<LocalResolveResult>(program);
 
243
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
244
                }
 
245
                
 
246
                [Test]
 
247
                public void LambdaExpressionInDelegateCreateExpression()
 
248
                {
 
249
                        string program = @"using System;
 
250
static class TestClass {
 
251
        static void Main(string[] args) {
 
252
                var f = new Func<int, string>( i => $i$ );
 
253
        }
 
254
        public delegate R Func<T, R>(T arg);
 
255
}";
 
256
                        var lrr = Resolve<LocalResolveResult>(program);
 
257
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
258
                }
 
259
                
 
260
                [Test]
 
261
                public void LambdaExpressionInReturnStatement()
 
262
                {
 
263
                        string program = @"using System;
 
264
static class TestClass {
 
265
        static Converter<int, string> GetToString() {
 
266
                return i => $i$.ToString();
 
267
        }
 
268
}";
 
269
                        var lrr = Resolve<LocalResolveResult>(program);
 
270
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
271
                }
 
272
                
 
273
                [Test]
 
274
                public void LambdaExpressionInReturnStatementInStatementLambda()
 
275
                {
 
276
                        string program = @"using System;
 
277
static class TestClass {
 
278
        static void SomeMethod() {
 
279
                Func<Func<string, string>> getStringTransformer = () => {
 
280
                        return s => $s$.ToUpper();
 
281
                };
 
282
        }
 
283
        public delegate R Func<T, R>(T arg);
 
284
        public delegate R Func<R>();
 
285
}";
 
286
                        var lrr = Resolve<LocalResolveResult>(program);
 
287
                        Assert.AreEqual("System.String", lrr.Type.ReflectionName);
 
288
                }
 
289
                
 
290
                [Test]
 
291
                public void LambdaExpressionInReturnStatementInAnonymousMethod()
 
292
                {
 
293
                        string program = @"using System;
 
294
static class TestClass {
 
295
        static void SomeMethod() {
 
296
                Func<Func<string, string>> getStringTransformer = delegate {
 
297
                        return s => $s$.ToUpper();
 
298
                };
 
299
        }
 
300
        public delegate R Func<T, R>(T arg);
 
301
        public delegate R Func<R>();
 
302
}";
 
303
                        var lrr = Resolve<LocalResolveResult>(program);
 
304
                        Assert.AreEqual("System.String", lrr.Type.ReflectionName);
 
305
                }
 
306
                
 
307
                [Test]
 
308
                public void CurriedLambdaExpressionInCastExpression()
 
309
                {
 
310
                        string program = @"using System;
 
311
static class TestClass {
 
312
        static void Main(string[] args) {
 
313
                var f = (Func<char, Func<string, int>>) ( a => b => 0 );
 
314
        }
 
315
        public delegate R Func<T, R>(T arg);
 
316
}";
 
317
                        var lrr = Resolve<LocalResolveResult>(program.Replace("a =>", "$a$ =>"));
 
318
                        Assert.AreEqual("System.Char", lrr.Type.ReflectionName);
 
319
                        
 
320
                        lrr = Resolve<LocalResolveResult>(program.Replace("b =>", "$b$ =>"));
 
321
                        Assert.AreEqual("System.String", lrr.Type.ReflectionName);
 
322
                }
 
323
                
 
324
                [Test]
 
325
                public void LambdaExpressionInVariableInitializer()
 
326
                {
 
327
                        string program = @"using System;
 
328
static class TestClass {
 
329
        static void Main() {
 
330
                Func<int, string> f = $i$ => i.ToString();
 
331
        }
 
332
        public delegate R Func<T, R>(T arg);
 
333
}";
 
334
                        var lrr = Resolve<LocalResolveResult>(program);
 
335
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
336
                }
 
337
                
 
338
                [Test]
 
339
                public void LambdaExpressionInVariableAssignment()
 
340
                {
 
341
                        string program = @"using System;
 
342
static class TestClass {
 
343
        static void Main() {
 
344
                Func<int, string> f;
 
345
                f = $i$ => i.ToString();
 
346
        }
 
347
        public delegate R Func<T, R>(T arg);
 
348
}";
 
349
                        var lrr = Resolve<LocalResolveResult>(program);
 
350
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
351
                }
 
352
                
 
353
                [Test]
 
354
                public void LambdaInDelegateCall()
 
355
                {
 
356
                        string program = @"using System;
 
357
class TestClass {
 
358
        static void Main() {
 
359
                Func<Func<int, string>, char> f;
 
360
                f($i$ => i.ToString());
 
361
        }
 
362
        public delegate R Func<T, R>(T arg);
 
363
}";
 
364
                        var lrr = Resolve<LocalResolveResult>(program);
 
365
                        Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
 
366
                }
 
367
                
 
368
                [Test]
 
369
                public void ConvertAllInGenericMethod()
 
370
                {
 
371
                        string program = @"using System;
 
372
class TestClass {
 
373
        static void Method<T>(System.Collections.Generic.List<T> list) {
 
374
                $list.ConvertAll(x => (int)(object)x)$;
 
375
        }
 
376
}";
 
377
                        var rr = Resolve<CSharpInvocationResolveResult>(program);
 
378
                        Assert.IsFalse(rr.IsError);
 
379
                        var m = (IMethod)rr.Member;
 
380
                        Assert.AreEqual("System.Int32", m.TypeArguments[0].ReflectionName);
 
381
                        Assert.AreEqual("System.Converter`2[[``0],[System.Int32]]", m.Parameters[0].Type.ReflectionName);
 
382
                        
 
383
                        var crr = (ConversionResolveResult)rr.Arguments[0];
 
384
                        Assert.IsTrue(crr.Conversion.IsAnonymousFunctionConversion);
 
385
                        Assert.AreEqual("System.Converter`2[[``0],[System.Int32]]", crr.Type.ReflectionName);
 
386
                }
 
387
                
 
388
                [Test]
 
389
                public void AnonymousMethodWithoutParameterList()
 
390
                {
 
391
                        string program = @"using System;
 
392
class TestClass {
 
393
        event EventHandler Ev = $delegate {}$;
 
394
}";
 
395
                        var rr = Resolve<LambdaResolveResult>(program);
 
396
                        Assert.IsFalse(rr.IsError);
 
397
                        Assert.IsFalse(rr.HasParameterList);
 
398
                }
 
399
                
 
400
                [Test]
 
401
                public void NonVoidMethodInActionLambdaIsValidConversion()
 
402
                {
 
403
                        string program = @"using System;
 
404
class TestClass {
 
405
        void Run(Action a) { }
 
406
        int M() {
 
407
                Run(() => $M()$);
 
408
        }
 
409
}";
 
410
                        var c = GetConversion(program);
 
411
                        Assert.IsTrue(c.IsValid);
 
412
                }
 
413
                
 
414
                [Test]
 
415
                public void NonVoidMethodInImplicitlyTypedActionLambdaIsValidConversion()
 
416
                {
 
417
                        string program = @"using System;
 
418
class TestClass {
 
419
        void Run(Action<string> a) { }
 
420
        int M() {
 
421
                Run(x => $M()$);
 
422
        }
 
423
}";
 
424
                        var c = GetConversion(program);
 
425
                        Assert.IsTrue(c.IsValid);
 
426
                }
 
427
                
 
428
                [Test]
 
429
                public void ImplicitLambdaInNewFunc()
 
430
                {
 
431
                        string program = @"using System;
 
432
class Test {
 
433
        static bool b;
 
434
        object x = new Func<int, string>(a => $a$.ToString());
 
435
}";
 
436
                        var r = Resolve(program);
 
437
                        Assert.AreEqual("System.Int32", r.Type.ReflectionName);
 
438
                }
 
439
                
 
440
                [Test]
 
441
                public void LambdaInNewAction()
 
442
                {
 
443
                        string program = @"using System;
 
444
class Test {
 
445
        static bool b;
 
446
        object x = new Action(() => $b = true$);
 
447
}";
 
448
                        var c = GetConversion(program);
 
449
                        Assert.IsTrue(c.IsValid);
 
450
                }
 
451
                
 
452
                [Test]
 
453
                public void AnonymousMethodInNewEventHandler()
 
454
                {
 
455
                        // The switch statement causes the control flow analysis to ask the resolver if it's a constant,
 
456
                        // which caused a bug.
 
457
                        string program = @"using System;
 
458
class Test {
 
459
        static bool b;
 
460
        object x = new EventHandler<AssemblyLoadEventArgs>($delegate (object sender, AssemblyLoadEventArgs e) { switch (e.Action) {} }$);
 
461
}";
 
462
                        var c = GetConversion(program);
 
463
                        Assert.IsTrue(c.IsValid);
 
464
                }
 
465
                
 
466
                [Test]
 
467
                public void ThrowingAnonymousMethodIsConvertibleToFunc()
 
468
                {
 
469
                        string program = @"using System;
 
470
class Test {
 
471
        Func<string, int> x = $delegate { throw new NotImplementedException(); }$;
 
472
}";
 
473
                        var c = GetConversion(program);
 
474
                        Assert.IsTrue(c.IsValid);
 
475
                }
 
476
                
 
477
                [Test]
 
478
                public void EmptyAnonymousMethodIsNotConvertibleToFunc()
 
479
                {
 
480
                        string program = @"using System;
 
481
class Test {
 
482
        Func<string, int> x = $delegate { }$;
 
483
}";
 
484
                        var c = GetConversion(program);
 
485
                        Assert.IsFalse(c.IsValid);
 
486
                }
 
487
                
 
488
                [Test]
 
489
                public void RaisePropertyChanged_WithExpressionLambda()
 
490
                {
 
491
                        string program = @"using System;
 
492
using System.Linq.Expressions;
 
493
class Test {
 
494
        void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression) {}
 
495
        void RaisePropertyChanged(string propertyName) {}
 
496
        string MyProperty { get {} }
 
497
        void Test() {
 
498
                $RaisePropertyChanged(() => MyProperty)$;
 
499
        }
 
500
}";
 
501
                        var rr = Resolve<CSharpInvocationResolveResult>(program);
 
502
                        Assert.IsFalse(rr.IsError);
 
503
                        Assert.AreEqual("propertyExpression", rr.Member.Parameters.Single().Name);
 
504
                }
 
505
                
 
506
                [Test]
 
507
                public void ParenthesizedExpressionIsNotValidExpressionStatement()
 
508
                {
 
509
                        string program = @"using System;
 
510
class A {
 
511
    static void Foo(string x, Action<Action> y) { Console.WriteLine(1); }
 
512
    static void Foo(object x, Func<Func<int>, int> y) { Console.WriteLine(2); }
 
513
 
 
514
    static void Main()
 
515
    { ";
 
516
                        var rr = ResolveAtLocation<CSharpInvocationResolveResult>(program + "$Foo(null, x => x()); // Prints 1\n}}");
 
517
                        Assert.IsFalse(rr.IsError);
 
518
                        Assert.AreEqual("System.String", rr.Member.Parameters[0].Type.ReflectionName);
 
519
                        
 
520
                        rr = ResolveAtLocation<CSharpInvocationResolveResult>(program + "$Foo(null, x => (x())); // Prints 2\n}}");
 
521
                        Assert.IsFalse(rr.IsError);
 
522
                        Assert.AreEqual("System.Object", rr.Member.Parameters[0].Type.ReflectionName);
 
523
                }
 
524
                
 
525
                [Test]
 
526
                public void LambdaWithComparisonToString()
 
527
                {
 
528
                        string program = @"using System;
 
529
class Test {
 
530
    static void Foo(Func<int, bool> f) {}
 
531
    static void Foo(Func<string, bool> f) {}
 
532
    static void Main() { $Foo(x => x == ""text"")$; } }";
 
533
                        var rr = Resolve<CSharpInvocationResolveResult>(program);
 
534
                        Assert.IsFalse(rr.IsError);
 
535
                        var invoke = rr.Member.Parameters.Single().Type.GetDelegateInvokeMethod();
 
536
                        Assert.AreEqual("System.String", invoke.Parameters.Single().Type.ReflectionName);
 
537
                }
 
538
                
 
539
                [Test]
 
540
                public void LambdaWithComparisonToInt()
 
541
                {
 
542
                        string program = @"using System;
 
543
class Test {
 
544
    static void Foo(Func<int, bool> f) {}
 
545
    static void Foo(Func<string, bool> f) {}
 
546
    static void Main() { $Foo(x => x == 42)$; } }";
 
547
                        var rr = Resolve<CSharpInvocationResolveResult>(program);
 
548
                        Assert.IsFalse(rr.IsError);
 
549
                        var invoke = rr.Member.Parameters.Single().Type.GetDelegateInvokeMethod();
 
550
                        Assert.AreEqual("System.Int32", invoke.Parameters.Single().Type.ReflectionName);
 
551
                }
 
552
                
 
553
                [Test]
 
554
                public void StartNewTask()
 
555
                {
 
556
                        string program = @"using System;
 
557
class Test {
 
558
        int Calculate() {}
 
559
    static void Main() {
 
560
        $System.Threading.Tasks.Task.Factory.StartNew(() => Calculate())$;
 
561
        }}";
 
562
                        var rr = Resolve<CSharpInvocationResolveResult>(program);
 
563
                        Assert.IsFalse(rr.IsError);
 
564
                        Assert.AreEqual("System.Threading.Tasks.Task`1[[System.Int32]]", rr.Type.ReflectionName);
 
565
                }
 
566
                
 
567
                [Test]
 
568
                public void LambdaParameterIdentity()
 
569
                {
 
570
                        string code = @"using System;
 
571
class TestClass {
 
572
        void F() {
 
573
                Func<int, int> f = $i => i + 1$;
 
574
        }
 
575
}";
 
576
                        
 
577
                        var prep = PrepareResolver(code);
 
578
                        var lambda = (LambdaExpression)prep.Item2;
 
579
                        var identifierInLambdaBody = ((BinaryOperatorExpression)lambda.Body).Left;
 
580
                        var resolver = prep.Item1;
 
581
                        
 
582
                        var resolvedParameter = ((LocalResolveResult)resolver.Resolve(lambda.Parameters.Single())).Variable;
 
583
                        var parameterInResolveResult = ((LambdaResolveResult)resolver.Resolve(lambda)).Parameters[0];
 
584
                        var referencedParameter = ((LocalResolveResult)resolver.Resolve(identifierInLambdaBody)).Variable;
 
585
                        
 
586
                        Assert.AreEqual("System.Int32" ,resolvedParameter.Type.ReflectionName);
 
587
                        Assert.AreSame(resolvedParameter, parameterInResolveResult);
 
588
                        Assert.AreSame(resolvedParameter, referencedParameter);
 
589
                }
 
590
                
 
591
                [Test]
 
592
                public void MultipleOverloadsWithImplicitLambda()
 
593
                {
 
594
                        string program = @"class MainClass {
 
595
        void Main() {
 
596
                $M(x=>x.ToUpper())$;
 
597
        }
 
598
        delegate R Func<T, R>(T arg);
 
599
        int M(Func<int, int> f){ }
 
600
        string M(Func<string, string> f){ }
 
601
}";
 
602
                        var mrr = Resolve<CSharpInvocationResolveResult>(program);
 
603
                        Assert.IsFalse(mrr.IsError);
 
604
                        Assert.AreEqual("System.String", mrr.Type.ReflectionName);
 
605
                }
 
606
                
 
607
                [Test]
 
608
                public void MultipleOverloadsWithImplicitLambda2()
 
609
                {
 
610
                        string program = @"class MainClass {
 
611
        void Main() {
 
612
                $M(x=>x.Length)$;
 
613
        }
 
614
        delegate R Func<T, R>(T arg);
 
615
        int M(Func<int, int> f){ }
 
616
        string M(Func<string, int> f){ }
 
617
}";
 
618
                        var mrr = Resolve<CSharpInvocationResolveResult>(program);
 
619
                        Assert.IsFalse(mrr.IsError);
 
620
                        Assert.AreEqual("System.String", mrr.Type.ReflectionName);
 
621
                }
 
622
                
 
623
                [Test]
 
624
                public void MultipleOverloadsWithImplicitLambda3()
 
625
                {
 
626
                        string program = @"class MainClass {
 
627
        void Main() {
 
628
                $M(x=>x+x)$;
 
629
        }
 
630
        delegate R Func<T, R>(T arg);
 
631
        string M(Func<string, int> f){ }
 
632
        int M(Func<int, int> f){ }
 
633
}";
 
634
                        var mrr = Resolve<CSharpInvocationResolveResult>(program);
 
635
                        Assert.IsFalse(mrr.IsError);
 
636
                        Assert.AreEqual("System.Int32", mrr.Type.ReflectionName);
 
637
                }
 
638
 
 
639
                [Test]
 
640
                public void AsyncLambdaWithAwait()
 
641
                {
 
642
                        string program = @"
 
643
using System;
 
644
using System.Threading.Tasks;
 
645
 
 
646
class A
 
647
{
 
648
        public Task OpenAsync ()
 
649
        {
 
650
                return null;
 
651
        }
 
652
}
 
653
 
 
654
class C
 
655
{
 
656
        async void Foo ()
 
657
        {
 
658
                        await $Test (async () => { await new A().OpenAsync (); })$;
 
659
        }
 
660
        
 
661
        T Test<T> (Func<T> func)
 
662
        {
 
663
                return default (T);
 
664
        }
 
665
}
 
666
";
 
667
                        var mrr = Resolve<CSharpInvocationResolveResult>(program);
 
668
                        Assert.IsFalse(mrr.IsError);
 
669
                        Assert.AreEqual("System.Threading.Tasks.Task", mrr.Type.ReflectionName);
 
670
                }
 
671
 
 
672
                [Test]
 
673
                public void ConversionInExplicitlyTypedLambdaBody() {
 
674
                        string program = @"using System;
 
675
class Test {
 
676
        public object M() {
 
677
                System.Func<int, string> f = $(int i) => null$;
 
678
        }
 
679
}";
 
680
                        var rr = Resolve<LambdaResolveResult>(program);
 
681
                        Assert.IsInstanceOf<ConversionResolveResult>(rr.Body);
 
682
                        Assert.That(((ConversionResolveResult)rr.Body).Conversion.IsNullLiteralConversion);
 
683
                }
 
684
 
 
685
                [Test]
 
686
                public void ConversionInImplicitlyTypedLambdaBody() {
 
687
                        string program = @"using System;
 
688
class Test {
 
689
        public object M() {
 
690
                System.Func<int, string> f = $i => null$;
 
691
        }
 
692
}";
 
693
                        var rr = Resolve<LambdaResolveResult>(program);
 
694
                        Assert.IsInstanceOf<ConversionResolveResult>(rr.Body);
 
695
                        Assert.That(((ConversionResolveResult)rr.Body).Conversion.IsNullLiteralConversion);
 
696
                }
 
697
 
 
698
                [Test]
 
699
                public void NoConversionInVoidExplicitlyTypedLambdaBody() {
 
700
                        string program = @"using System;
 
701
class Test {
 
702
        public object M() {
 
703
                System.Action<int> f = $(int i) => i++$;
 
704
        }
 
705
}";
 
706
                        var rr = Resolve<LambdaResolveResult>(program);
 
707
                        Assert.IsInstanceOf<OperatorResolveResult>(rr.Body);
 
708
                }
 
709
 
 
710
                [Test]
 
711
                public void NoConversionInVoidImplicitlyTypedLambdaBody() {
 
712
                        string program = @"using System;
 
713
class Test {
 
714
        public object M() {
 
715
                System.Action<int> f = $i => i++$;
 
716
        }
 
717
}";
 
718
                        var rr = Resolve<LambdaResolveResult>(program);
 
719
                        Assert.IsInstanceOf<OperatorResolveResult>(rr.Body);
 
720
                }
 
721
                
 
722
                [Test]
 
723
                public void NumericConversion()
 
724
                {
 
725
                        string program = @"using System;
 
726
class Test {
 
727
        public void M() {
 
728
                Func<int, double> f = $i => i + 1$;
 
729
        }
 
730
}";
 
731
                        var rr = Resolve<LambdaResolveResult>(program);
 
732
                        Assert.IsInstanceOf<ConversionResolveResult>(rr.Body);
 
733
                        var bodyConv = ((ConversionResolveResult)rr.Body).Conversion;
 
734
                        Assert.IsTrue(bodyConv.IsValid);
 
735
                        Assert.IsTrue(bodyConv.IsNumericConversion);
 
736
                        
 
737
                        var c = GetConversion(program);
 
738
                        Assert.IsTrue(c.IsValid);
 
739
                        Assert.IsTrue(c.IsAnonymousFunctionConversion);
 
740
                }
 
741
                
 
742
                [Test]
 
743
                public void InvalidNumericConversion()
 
744
                {
 
745
                        string program = @"using System;
 
746
class Test {
 
747
        public void M() {
 
748
                Func<double, int> f = $i => i + 1$;
 
749
        }
 
750
}";
 
751
                        var rr = Resolve<LambdaResolveResult>(program);
 
752
                        Assert.IsInstanceOf<ConversionResolveResult>(rr.Body);
 
753
                        var bodyConv = ((ConversionResolveResult)rr.Body).Conversion;
 
754
                        Assert.IsFalse(bodyConv.IsValid);
 
755
                        
 
756
                        var c = GetConversion(program);
 
757
                        Assert.IsFalse(c.IsValid);
 
758
                        Assert.IsTrue(c.IsAnonymousFunctionConversion);
 
759
                }
 
760
                
 
761
                [Test]
 
762
                public void ImplicitAsyncLambda()
 
763
                {
 
764
                        string program = @"using System;
 
765
using System.Threading.Tasks;
 
766
class Test {
 
767
        public void M() {
 
768
                Func<int, Task<int>> f = $async i => i + 1$;
 
769
        }
 
770
}";
 
771
                        var rr = Resolve<LambdaResolveResult>(program);
 
772
                        Assert.IsInstanceOf<OperatorResolveResult>(rr.Body);
 
773
                        Assert.AreEqual("System.Int32", rr.Body.Type.FullName);
 
774
                        
 
775
                        var c = GetConversion(program);
 
776
                        Assert.IsTrue(c.IsValid);
 
777
                        Assert.IsTrue(c.IsAnonymousFunctionConversion);
 
778
                }
 
779
                
 
780
                [Test]
 
781
                public void ImplicitAsyncLambdaWithNumericConversion()
 
782
                {
 
783
                        string program = @"using System;
 
784
using System.Threading.Tasks;
 
785
class Test {
 
786
        public void M() {
 
787
                Func<int, Task<double>> f = $async i => i + 1$;
 
788
        }
 
789
}";
 
790
                        var rr = Resolve<LambdaResolveResult>(program);
 
791
                        Assert.IsInstanceOf<ConversionResolveResult>(rr.Body);
 
792
                        Assert.AreEqual("System.Double", rr.Body.Type.FullName);
 
793
                        
 
794
                        var c = GetConversion(program);
 
795
                        Assert.IsTrue(c.IsValid);
 
796
                        Assert.IsTrue(c.IsAnonymousFunctionConversion);
 
797
                }
 
798
                
 
799
                [Test]
 
800
                public void ExplicitAsyncLambda()
 
801
                {
 
802
                        string program = @"using System;
 
803
using System.Threading.Tasks;
 
804
class Test {
 
805
        public void M() {
 
806
                Func<int, Task<int>> f = $async (int i) => i + 1$;
 
807
        }
 
808
}";
 
809
                        var rr = Resolve<LambdaResolveResult>(program);
 
810
                        Assert.IsInstanceOf<OperatorResolveResult>(rr.Body);
 
811
                        Assert.AreEqual("System.Int32", rr.Body.Type.FullName);
 
812
                        
 
813
                        var c = GetConversion(program);
 
814
                        Assert.IsTrue(c.IsValid);
 
815
                        Assert.IsTrue(c.IsAnonymousFunctionConversion);
 
816
                }
 
817
                
 
818
                [Test]
 
819
                public void ExplicitAsyncLambdaWithNumericConversion()
 
820
                {
 
821
                        string program = @"using System;
 
822
using System.Threading.Tasks;
 
823
class Test {
 
824
        public void M() {
 
825
                Func<int, Task<double>> f = $async (int i) => i + 1$;
 
826
        }
 
827
}";
 
828
                        var rr = Resolve<LambdaResolveResult>(program);
 
829
                        Assert.IsInstanceOf<ConversionResolveResult>(rr.Body);
 
830
                        Assert.AreEqual("System.Double", rr.Body.Type.FullName);
 
831
                        
 
832
                        var c = GetConversion(program);
 
833
                        Assert.IsTrue(c.IsValid);
 
834
                        Assert.IsTrue(c.IsAnonymousFunctionConversion);
 
835
                }
 
836
        }
 
837
}