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

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.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.CodeDom;
 
21
using System.CodeDom.Compiler;
 
22
using System.IO;
 
23
using System.Linq;
 
24
using System.Text.RegularExpressions;
 
25
using ICSharpCode.NRefactory.CSharp.Resolver;
 
26
using ICSharpCode.NRefactory.CSharp.TypeSystem;
 
27
using ICSharpCode.NRefactory.TypeSystem;
 
28
using Microsoft.CSharp;
 
29
using NUnit.Framework;
 
30
 
 
31
namespace ICSharpCode.NRefactory.CSharp
 
32
{
 
33
        [TestFixture]
 
34
        public class CodeDomConvertVisitorTests : ResolverTestBase
 
35
        {
 
36
                CodeDomConvertVisitor convertVisitor;
 
37
                CSharpUnresolvedFile unresolvedFile;
 
38
                
 
39
                public override void SetUp()
 
40
                {
 
41
                        base.SetUp();
 
42
                        unresolvedFile = new CSharpUnresolvedFile("test.cs");
 
43
                        unresolvedFile.RootUsingScope.Usings.Add(MakeReference("System"));
 
44
                        unresolvedFile.RootUsingScope.Usings.Add(MakeReference("System.Collections.Generic"));
 
45
                        unresolvedFile.RootUsingScope.Usings.Add(MakeReference("System.Linq"));
 
46
                        
 
47
                        convertVisitor = new CodeDomConvertVisitor();
 
48
                        convertVisitor.AllowSnippetNodes = false;
 
49
                        convertVisitor.UseFullyQualifiedTypeNames = true;
 
50
                }
 
51
                
 
52
                #region Helper methods
 
53
                CodeObject ConvertInContext(string program)
 
54
                {
 
55
                        var p = PrepareResolver(program);
 
56
                        return convertVisitor.Convert(p.Item2, p.Item1);
 
57
                }
 
58
                
 
59
                string ConvertHelper(AstNode node, Action<CSharpCodeProvider, CodeObject, TextWriter, CodeGeneratorOptions> action)
 
60
                {
 
61
                        CSharpResolver resolver = new CSharpResolver(compilation);
 
62
                        resolver = resolver.WithCurrentUsingScope(unresolvedFile.RootUsingScope.Resolve(compilation));
 
63
                        resolver = resolver.WithCurrentTypeDefinition(compilation.FindType(KnownTypeCode.Object).GetDefinition());
 
64
                        var codeObj = convertVisitor.Convert(node, new CSharpAstResolver(resolver, node));
 
65
                        
 
66
                        StringWriter writer = new StringWriter();
 
67
                        writer.NewLine = " ";
 
68
                        action(new CSharpCodeProvider(), codeObj, writer, new CodeGeneratorOptions { IndentString = " " });
 
69
                        return Regex.Replace(writer.ToString(), @"\s+", " ").Trim();
 
70
                }
 
71
                
 
72
                string ConvertExpression(Expression expr)
 
73
                {
 
74
                        return ConvertHelper(expr, (p,obj,w,opt) => p.GenerateCodeFromExpression((CodeExpression)obj, w, opt));
 
75
                }
 
76
                
 
77
                string ConvertExpression(string code)
 
78
                {
 
79
                        CSharpParser parser = new CSharpParser();
 
80
                        var expr = parser.ParseExpression(code);
 
81
                        Assert.IsFalse(parser.HasErrors);
 
82
                        return ConvertExpression(expr);
 
83
                }
 
84
                
 
85
                string ConvertStatement(Statement statement)
 
86
                {
 
87
                        return ConvertHelper(statement, (p,obj,w,opt) => p.GenerateCodeFromStatement((CodeStatement)obj, w, opt));
 
88
                }
 
89
                
 
90
                string ConvertStatement(string code)
 
91
                {
 
92
                        CSharpParser parser = new CSharpParser();
 
93
                        var expr = parser.ParseStatements(code).Single();
 
94
                        Assert.IsFalse(parser.HasErrors);
 
95
                        return ConvertStatement(expr);
 
96
                }
 
97
                
 
98
                string ConvertMember(EntityDeclaration entity)
 
99
                {
 
100
                        return ConvertHelper(entity, (p,obj,w,opt) => p.GenerateCodeFromMember((CodeTypeMember)obj, w, opt));
 
101
                }
 
102
                
 
103
                string ConvertMember(string code)
 
104
                {
 
105
                        CSharpParser parser = new CSharpParser();
 
106
                        var expr = parser.ParseTypeMembers(code).Single();
 
107
                        Assert.IsFalse(parser.HasErrors);
 
108
                        return ConvertMember(expr);
 
109
                }
 
110
                
 
111
                string ConvertTypeDeclaration(EntityDeclaration decl)
 
112
                {
 
113
                        return ConvertHelper(decl, (p,obj,w,opt) => p.GenerateCodeFromType((CodeTypeDeclaration)obj, w, opt));
 
114
                }
 
115
                
 
116
                string ConvertTypeDeclaration(string code)
 
117
                {
 
118
                        CSharpParser parser = new CSharpParser();
 
119
                        var syntaxTree = parser.Parse(code, "program.cs");
 
120
                        Assert.IsFalse(parser.HasErrors);
 
121
                        return ConvertTypeDeclaration((EntityDeclaration)syntaxTree.Children.Single());
 
122
                }
 
123
                
 
124
                string ConvertSyntaxTree(SyntaxTree syntaxTree)
 
125
                {
 
126
                        return ConvertHelper(syntaxTree, (p,obj,w,opt) => p.GenerateCodeFromCompileUnit((CodeCompileUnit)obj, w, opt));
 
127
                }
 
128
                
 
129
                string ConvertSyntaxTree(string code)
 
130
                {
 
131
                        CSharpParser parser = new CSharpParser();
 
132
                        var syntaxTree = parser.Parse(code, "program.cs");
 
133
                        Assert.IsFalse(parser.HasErrors);
 
134
                        var result = ConvertSyntaxTree(syntaxTree);
 
135
                        var idx = result.IndexOf("namespace", StringComparison.Ordinal);
 
136
                        if (idx > 0)
 
137
                                result = result.Substring (idx);
 
138
                        return result;
 
139
                }
 
140
                #endregion
 
141
                
 
142
                #region Type References
 
143
                [Test]
 
144
                public void MultidimensionalArrayTypeReference()
 
145
                {
 
146
                        Assert.AreEqual("default(int[,][])", ConvertExpression("default(int[,][])"));
 
147
                }
 
148
                
 
149
                [Test]
 
150
                public void NestedTypeInGenericType()
 
151
                {
 
152
                        Assert.AreEqual("default(System.Collections.Generic.List<string>.Enumerator)",
 
153
                                        ConvertExpression("default(List<string>.Enumerator)"));
 
154
                        convertVisitor.UseFullyQualifiedTypeNames = false;
 
155
                        Assert.AreEqual("default(List<string>.Enumerator)",
 
156
                                        ConvertExpression("default(List<string>.Enumerator)"));
 
157
                }
 
158
                #endregion
 
159
                
 
160
                #region Arrays
 
161
                [Test]
 
162
                public void CreateArray()
 
163
                {
 
164
                        Assert.AreEqual("new int[10]", ConvertExpression("new int[10]"));
 
165
                }
 
166
                
 
167
                [Test, ExpectedException(typeof(NotSupportedException))]
 
168
                public void CreateJaggedArray()
 
169
                {
 
170
                        ConvertExpression("new int[10][]");
 
171
                }
 
172
                
 
173
                [Test, ExpectedException(typeof(NotSupportedException))]
 
174
                public void Create2DArray()
 
175
                {
 
176
                        ConvertExpression("new int[10, 20]");
 
177
                }
 
178
                
 
179
                [Test]
 
180
                public void CreateImplicitlyTypedArray()
 
181
                {
 
182
                        // implicitly-typed array not supported in CodeDom, so the conversion should infer the type
 
183
                        Assert.AreEqual("new int[] { 1, 2, 3}", ConvertExpression("new [] { 1, 2, 3 }"));
 
184
                        Assert.AreEqual("new System.Collections.Generic.List<string>[] { new System.Collections.Generic.List<string>()}",
 
185
                                        ConvertExpression("new [] { new List<string>() }"));
 
186
                }
 
187
                
 
188
                [Test, ExpectedException(typeof(NotSupportedException))]
 
189
                public void Create2DImplicitlyTypedArray()
 
190
                {
 
191
                        ConvertExpression("new [,] { { 1, 2 }, { 3, 4 }}");
 
192
                }
 
193
                #endregion
 
194
                
 
195
                #region Operators
 
196
                [Test]
 
197
                public void ArithmeticOperators()
 
198
                {
 
199
                        Assert.AreEqual("(0 + 1)", ConvertExpression("0 + 1"));
 
200
                        Assert.AreEqual("(0 - 1)", ConvertExpression("0 - 1"));
 
201
                        Assert.AreEqual("(0 * 1)", ConvertExpression("0 * 1"));
 
202
                        Assert.AreEqual("(0 / 1)", ConvertExpression("0 / 1"));
 
203
                        Assert.AreEqual("(0 % 1)", ConvertExpression("0 % 1"));
 
204
                        Assert.AreEqual("(0 & 1)", ConvertExpression("0 & 1"));
 
205
                        Assert.AreEqual("(0 | 1)", ConvertExpression("0 | 1"));
 
206
                        Assert.AreEqual("(0 < 1)", ConvertExpression("0 < 1"));
 
207
                        Assert.AreEqual("(0 > 1)", ConvertExpression("0 > 1"));
 
208
                        Assert.AreEqual("(0 <= 1)", ConvertExpression("0 <= 1"));
 
209
                        Assert.AreEqual("(0 >= 1)", ConvertExpression("0 >= 1"));
 
210
                        Assert.AreEqual("(true && false)", ConvertExpression("true && false"));
 
211
                        Assert.AreEqual("(true || false)", ConvertExpression("true || false"));
 
212
                }
 
213
                
 
214
                [Test]
 
215
                public void EqualityOperator()
 
216
                {
 
217
                        Assert.AreEqual("(0 == 1)", ConvertExpression("0 == 1"));
 
218
                        Assert.AreEqual("(default(object) == null)", ConvertExpression("default(object) == null"));
 
219
                }
 
220
                
 
221
                [Test]
 
222
                public void InEqualityOperator()
 
223
                {
 
224
                        Assert.AreEqual("((0 == 1) == false)", ConvertExpression("0 != 1"));
 
225
                        Assert.AreEqual("(default(object) != null)", ConvertExpression("default(object) != null"));
 
226
                }
 
227
                
 
228
                [Test]
 
229
                public void UnaryOperators()
 
230
                {
 
231
                        Assert.AreEqual("(a == false)", ConvertExpression("!a"));
 
232
                        Assert.AreEqual("(0 - a)", ConvertExpression("-a"));
 
233
                        Assert.AreEqual("a", ConvertExpression("+a"));
 
234
                }
 
235
                
 
236
                [Test]
 
237
                public void Cast()
 
238
                {
 
239
                        Assert.AreEqual("((double)(0))", ConvertExpression("(double)0"));
 
240
                }
 
241
                #endregion
 
242
                
 
243
                #region Member Access
 
244
                [Test]
 
245
                public void StaticProperty()
 
246
                {
 
247
                        Assert.AreEqual("System.Environment.TickCount", ConvertExpression("Environment.TickCount"));
 
248
                }
 
249
                
 
250
                [Test]
 
251
                public void FullyQualifiedEnumFieldAccess()
 
252
                {
 
253
                        string program = "class A { object x = $System.StringComparison.Ordinal$; }";
 
254
                        var cfre = (CodeFieldReferenceExpression)ConvertInContext(program);
 
255
                        Assert.AreEqual("Ordinal", cfre.FieldName);
 
256
                        var ctre = ((CodeTypeReferenceExpression)cfre.TargetObject);
 
257
                        Assert.AreEqual("System.StringComparison", ctre.Type.BaseType);
 
258
                }
 
259
                
 
260
                [Test]
 
261
                public void EnumFieldAccess()
 
262
                {
 
263
                        string program = "using System; class A { object x = $StringComparison.Ordinal$; }";
 
264
                        var cfre = (CodeFieldReferenceExpression)ConvertInContext(program);
 
265
                        Assert.AreEqual("Ordinal", cfre.FieldName);
 
266
                        var ctre = ((CodeTypeReferenceExpression)cfre.TargetObject);
 
267
                        Assert.AreEqual("System.StringComparison", ctre.Type.BaseType);
 
268
                }
 
269
                
 
270
                [Test]
 
271
                public void InstanceMethodInvocation()
 
272
                {
 
273
                        Assert.AreEqual("this.Equals(null)", ConvertExpression("Equals(null)"));
 
274
                }
 
275
                
 
276
                [Test]
 
277
                public void StaticMethodInvocation()
 
278
                {
 
279
                        Assert.AreEqual("object.Equals(null, null)", ConvertExpression("Equals(null, null)"));
 
280
                }
 
281
                
 
282
                [Test]
 
283
                public void BaseMemberAccess()
 
284
                {
 
285
                        Assert.AreEqual("base.X", ConvertExpression("base.X"));
 
286
                        Assert.AreEqual("base[i]", ConvertExpression("base[i]"));
 
287
                }
 
288
                
 
289
                [Test]
 
290
                public void GenericMethodReference()
 
291
                {
 
292
                        Assert.AreEqual("this.Stuff<string>", ConvertExpression("this.Stuff<string>"));
 
293
                        Assert.AreEqual("this.Stuff<string>", ConvertExpression("Stuff<string>"));
 
294
                }
 
295
                
 
296
                [Test]
 
297
                public void ByReferenceCall()
 
298
                {
 
299
                        Assert.AreEqual("a.Call(ref x, out y, z)", ConvertExpression("a.Call(ref x, out y, z)"));
 
300
                }
 
301
                
 
302
                [Test]
 
303
                public void MemberAccessOnType()
 
304
                {
 
305
                        Assert.AreEqual("string.Empty", ConvertExpression("string.Empty"));
 
306
                }
 
307
                #endregion
 
308
                
 
309
                #region Statements
 
310
                [Test]
 
311
                public void MethodInvocationStatement()
 
312
                {
 
313
                        Assert.AreEqual("a.SomeMethod();", ConvertStatement("a.SomeMethod();"));
 
314
                }
 
315
                
 
316
                [Test]
 
317
                public void Assignment()
 
318
                {
 
319
                        Assert.AreEqual("a = 1;", ConvertStatement("a = 1;"));
 
320
                }
 
321
                
 
322
                [Test, ExpectedException(typeof(NotSupportedException))]
 
323
                public void AssignmentNotSupportedInExpression()
 
324
                {
 
325
                        ConvertStatement("a = b = 1;");
 
326
                }
 
327
                
 
328
                [Test]
 
329
                public void BlockStatement()
 
330
                {
 
331
                        Assert.AreEqual("if (true) { a = 1; b = 2; }",
 
332
                                        ConvertStatement("{ a = 1; b = 2; }"));
 
333
                }
 
334
                
 
335
                [Test]
 
336
                public void CompoundAssign()
 
337
                {
 
338
                        Assert.AreEqual("a = (a + 1);", ConvertStatement("a += 1;"));
 
339
                        Assert.AreEqual("a = (a - 1);", ConvertStatement("a -= 1;"));
 
340
                        Assert.AreEqual("a = (a * 1);", ConvertStatement("a *= 1;"));
 
341
                        Assert.AreEqual("a = (a / 1);", ConvertStatement("a /= 1;"));
 
342
                        Assert.AreEqual("a = (a % 1);", ConvertStatement("a %= 1;"));
 
343
                        Assert.AreEqual("a = (a & 1);", ConvertStatement("a &= 1;"));
 
344
                        Assert.AreEqual("a = (a | 1);", ConvertStatement("a |= 1;"));
 
345
                }
 
346
                
 
347
                [Test]
 
348
                public void Increment()
 
349
                {
 
350
                        Assert.AreEqual("a = (a + 1);", ConvertStatement("a++;"));
 
351
                        Assert.AreEqual("a = (a + 1);", ConvertStatement("++a;"));
 
352
                        Assert.AreEqual("a = (a - 1);", ConvertStatement("a--;"));
 
353
                        Assert.AreEqual("a = (a - 1);", ConvertStatement("--a;"));
 
354
                }
 
355
                
 
356
                [Test]
 
357
                public void ForLoop()
 
358
                {
 
359
                        Assert.AreEqual("for (int i = 0; (i < 10); i = (i + 1)) { }",
 
360
                                        ConvertStatement("for (int i = 0; i < 10; i++) {}"));
 
361
                }
 
362
                
 
363
                [Test]
 
364
                public void WhileLoop()
 
365
                {
 
366
                        Assert.AreEqual("for (new object(); (i < 10); new object()) { }",
 
367
                                        ConvertStatement("while (i < 10);"));
 
368
                }
 
369
                
 
370
                [Test]
 
371
                public void VariableDeclarationWithArrayInitializer()
 
372
                {
 
373
                        Assert.AreEqual("int[] nums = new int[] { 1, 2};",
 
374
                                        ConvertStatement("int[] nums = { 1, 2 };"));
 
375
                }
 
376
                
 
377
                [Test]
 
378
                public void TryCatch()
 
379
                {
 
380
                        Assert.AreEqual("try { a = 1; } catch (System.Exception ex) { ex.ToString(); }",
 
381
                                        ConvertStatement("try { a = 1; } catch (Exception ex) { ex.ToString(); }"));
 
382
                }
 
383
                
 
384
                [Test]
 
385
                public void TryEmptyCatch()
 
386
                {
 
387
                        Assert.AreEqual("try { a = 1; } catch (System.Exception ) { }",
 
388
                                        ConvertStatement("try { a = 1; } catch (Exception) { }"));
 
389
                }
 
390
                
 
391
                [Test]
 
392
                public void TryFinally()
 
393
                {
 
394
                        Assert.AreEqual("try { a = 1; } finally { a = 0; }",
 
395
                                        ConvertStatement("try { a = 1; } finally { a = 0; }"));
 
396
                }
 
397
                #endregion
 
398
                
 
399
                #region Type Members
 
400
                [Test]
 
401
                public void MethodParameterNamedValue()
 
402
                {
 
403
                        Assert.AreEqual("void M(string value) { System.Console.WriteLine(value); }",
 
404
                                        ConvertMember("void M(string value) { Console.WriteLine(value); }"));
 
405
                }
 
406
                
 
407
                [Test]
 
408
                public void ValueInProperty()
 
409
                {
 
410
                        Assert.AreEqual("string P { set { System.Console.WriteLine(value); } }",
 
411
                                        ConvertMember("string P { set { Console.WriteLine(value); } }"));
 
412
                }
 
413
                
 
414
                [Test]
 
415
                public void MethodWithAttribute()
 
416
                {
 
417
                        Assert.AreEqual("[Test()] void MethodWithAttribute() { }",
 
418
                                        ConvertMember("[Test] void MethodWithAttribute() { }"));
 
419
                }
 
420
                
 
421
                [Test]
 
422
                public void PublicNonVirtualMethod()
 
423
                {
 
424
                        Assert.AreEqual("public void Method() { }",
 
425
                                        ConvertMember("public void Method() { }"));
 
426
                }
 
427
                
 
428
                [Test]
 
429
                public void PublicVirtualMethod()
 
430
                {
 
431
                        Assert.AreEqual("public virtual void Method() { }",
 
432
                                        ConvertMember("public virtual void Method() { }"));
 
433
                }
 
434
                
 
435
                [Test]
 
436
                public void NestedClass()
 
437
                {
 
438
                        Assert.AreEqual("public class Outer { public class Inner { } }",
 
439
                                        ConvertTypeDeclaration("class Outer { class Inner { } }"));
 
440
                }
 
441
                
 
442
                [Test]
 
443
                public void Constructor()
 
444
                {
 
445
                        string code = "public class Test : Base { public Test(string x) : base(x) { } }";
 
446
                        Assert.AreEqual(code, ConvertTypeDeclaration(code));
 
447
                }
 
448
                
 
449
                [Test]
 
450
                public void Enum()
 
451
                {
 
452
                        string code = "public enum E { [Description(\"Text\")] None, B = 2, }";
 
453
                        Assert.AreEqual(code, ConvertTypeDeclaration(code));
 
454
                }
 
455
                
 
456
                [Test]
 
457
                public void Field()
 
458
                {
 
459
                        Assert.AreEqual("public class X {" +
 
460
                                        " int A;" +
 
461
                                        " int B; }",
 
462
                                        ConvertMember("public class X { int A, B; }"));
 
463
                }
 
464
                
 
465
                [Test]
 
466
                public void Event()
 
467
                {
 
468
                        Assert.AreEqual("public class X {" +
 
469
                                        " protected event System.EventHandler A;" +
 
470
                                        " protected event System.EventHandler B; }",
 
471
                                        ConvertMember("public class X { protected event EventHandler A, B; }"));
 
472
                }
 
473
                #endregion
 
474
                
 
475
                #region SyntaxTrees
 
476
                [Test]
 
477
                public void TestGlobalNamespaceFix ()
 
478
                {
 
479
                        Assert.AreEqual("namespace A { using System; public class AClass { } } namespace B { using System.IO; using System; public class AClass { } }",
 
480
                                        ConvertSyntaxTree("using System; namespace A { public class AClass {} } namespace B { using System.IO; public class AClass {} }"));
 
481
                }
 
482
                #endregion
 
483
        }
 
484
}