1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
8
using ICSharpCode.NRefactory.Parser;
9
using ICSharpCode.NRefactory.Ast;
10
using ICSharpCode.NRefactory.PrettyPrinter;
11
using ICSharpCode.NRefactory.Visitors;
13
namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
16
public class CSharpToVBNetConverterTest
18
public void TestProgram(string input, string expectedOutput)
20
IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(input));
22
Assert.AreEqual("", parser.Errors.ErrorOutput);
23
var specials = parser.Lexer.SpecialTracker.RetrieveSpecials();
24
PreprocessingDirective.CSharpToVB(specials);
25
parser.CompilationUnit.AcceptVisitor(new CSharpConstructsConvertVisitor(), null);
26
parser.CompilationUnit.AcceptVisitor(new ToVBNetConvertVisitor(), null);
27
VBNetOutputVisitor outputVisitor = new VBNetOutputVisitor();
28
outputVisitor.Options.IndentationChar = ' ';
29
outputVisitor.Options.IndentSize = 2;
30
outputVisitor.Options.OutputByValModifier = true;
31
using (SpecialNodesInserter.Install(specials, outputVisitor)) {
32
outputVisitor.VisitCompilationUnit(parser.CompilationUnit, null);
34
Assert.AreEqual("", outputVisitor.Errors.ErrorOutput);
35
Assert.AreEqual(expectedOutput.Replace("\r", ""), outputVisitor.Text.Replace("\r", ""));
38
public void TestMember(string input, string expectedOutput)
40
StringBuilder b = new StringBuilder();
41
b.AppendLine("Class tmp1");
42
using (StringReader r = new StringReader(expectedOutput)) {
44
while ((line = r.ReadLine()) != null) {
49
b.AppendLine("End Class");
50
TestProgram("class tmp1 { \n" + input + "\n}", b.ToString());
53
public void TestStatement(string input, string expectedOutput)
55
StringBuilder b = new StringBuilder();
56
b.AppendLine("Class tmp1");
57
b.AppendLine(" Private Sub tmp2()");
58
using (StringReader r = new StringReader(expectedOutput)) {
60
while ((line = r.ReadLine()) != null) {
65
b.AppendLine(" End Sub");
66
b.AppendLine("End Class");
67
TestProgram("class tmp1 { void tmp2() {\n" + input + "\n}}", b.ToString());
71
public void MoveImportsStatement()
73
TestProgram("namespace test { using SomeNamespace; }",
74
"Imports SomeNamespace" + Environment.NewLine +
75
"Namespace test" + Environment.NewLine +
76
"End Namespace" + Environment.NewLine);
80
public void ClassImplementsInterface()
82
TestProgram("class test : IComparable { }",
83
"Class test" + Environment.NewLine +
84
" Implements IComparable" + Environment.NewLine +
85
"End Class" + Environment.NewLine);
89
public void ClassImplementsInterface2()
91
TestProgram("class test : System.IComparable { }",
92
"Class test" + Environment.NewLine +
93
" Implements System.IComparable" + Environment.NewLine +
94
"End Class" + Environment.NewLine);
98
public void ClassInheritsClass()
100
TestProgram("class test : InvalidDataException { }",
101
"Class test" + Environment.NewLine +
102
" Inherits InvalidDataException" + Environment.NewLine +
103
"End Class"+ Environment.NewLine);
107
public void ClassInheritsClass2()
109
TestProgram("class test : System.IO.InvalidDataException { }",
110
"Class test" + Environment.NewLine +
111
" Inherits System.IO.InvalidDataException" + Environment.NewLine +
112
"End Class" + Environment.NewLine);
116
public void ForWithUnknownConditionAndSingleStatement()
118
TestStatement("for (i = 0; unknownCondition; i++) b[i] = s[i];",
120
"While unknownCondition\n" +
127
public void ForWithUnknownConditionAndBlock()
129
TestStatement("for (i = 0; unknownCondition; i++) { b[i] = s[i]; }",
131
"While unknownCondition\n" +
138
public void ForWithSingleStatement()
140
TestStatement("for (i = 0; i < end; i++) b[i] = s[i];",
141
"For i = 0 To [end] - 1\n" +
146
public void ForWithBlock()
148
TestStatement("for (i = 0; i < end; i++) { b[i] = s[i]; }",
149
"For i = 0 To [end] - 1\n" +
155
public void RaiseEvent()
157
TestStatement("if (MyEvent != null) MyEvent(this, EventArgs.Empty);",
158
"RaiseEvent MyEvent(Me, EventArgs.Empty)");
159
TestStatement("if ((MyEvent != null)) MyEvent(this, EventArgs.Empty);",
160
"RaiseEvent MyEvent(Me, EventArgs.Empty)");
161
TestStatement("if (null != MyEvent) { MyEvent(this, EventArgs.Empty); }",
162
"RaiseEvent MyEvent(Me, EventArgs.Empty)");
163
TestStatement("if (this.MyEvent != null) MyEvent(this, EventArgs.Empty);",
164
"RaiseEvent MyEvent(Me, EventArgs.Empty)");
165
TestStatement("if (MyEvent != null) this.MyEvent(this, EventArgs.Empty);",
166
"RaiseEvent MyEvent(Me, EventArgs.Empty)");
167
TestStatement("if ((this.MyEvent != null)) { this.MyEvent(this, EventArgs.Empty); }",
168
"RaiseEvent MyEvent(Me, EventArgs.Empty)");
172
public void IfStatementSimilarToRaiseEvent()
174
TestStatement("if (FullImage != null) DrawImage();",
175
"If FullImage IsNot Nothing Then\n" +
179
TestStatement("if (FullImage != null) e.DrawImage();",
180
"If FullImage IsNot Nothing Then\n" +
184
TestStatement("if (FullImage != null) { DrawImage(); }",
185
"If FullImage IsNot Nothing Then\n" +
188
TestStatement("if (FullImage != null) { e.DrawImage(); }",
189
"If FullImage IsNot Nothing Then\n" +
192
// another bug related to the IfStatement code:
193
TestStatement("if (Tiles != null) foreach (Tile t in Tiles) this.TileTray.Controls.Remove(t);",
194
"If Tiles IsNot Nothing Then\n" +
195
" For Each t As Tile In Tiles\n" +
196
" Me.TileTray.Controls.Remove(t)\n" +
202
public void ElseIfStatement()
204
TestStatement("if (a) {} else if (b) {} else {}",
212
public void AnonymousMethod()
214
TestMember("void A() { Converter<int, int> i = delegate(int argument) { return argument * 2; }; }",
215
"Private Sub A()\n" +
216
" Dim i As Converter(Of Integer, Integer) = Function(ByVal argument As Integer) argument * 2\n" +
221
public void StaticMethod()
223
TestMember("static void A() {}",
224
"Private Shared Sub A()\nEnd Sub");
228
public void PInvoke()
230
TestMember("[DllImport(\"user32.dll\", CharSet = CharSet.Auto)]" + Environment.NewLine +
231
"public static extern int MessageBox(IntPtr hwnd, string t, string caption, UInt32 t2);",
232
"<DllImport(\"user32.dll\", CharSet := CharSet.Auto)> _" + Environment.NewLine +
233
"Public Shared Function MessageBox(ByVal hwnd As IntPtr, ByVal t As String, ByVal caption As String, ByVal t2 As UInt32) As Integer\n" +
236
TestMember("[DllImport(\"user32.dll\", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]\n" +
237
"public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, UIntPtr wParam, IntPtr lParam);",
238
"Public Declare Ansi Function SendMessage Lib \"user32.dll\" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As UIntPtr, ByVal lParam As IntPtr) As IntPtr");
240
TestMember("[DllImport(\"user32.dll\", SetLastError = true, ExactSpelling = true, EntryPoint = \"SendMessageW\")]\n" +
241
"public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, UIntPtr wParam, IntPtr lParam);",
242
"Public Declare Auto Function SendMessage Lib \"user32.dll\" Alias \"SendMessageW\" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As UIntPtr, ByVal lParam As IntPtr) As IntPtr");
246
public void PInvokeSub()
248
TestMember("[DllImport(\"kernel32\", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]\n" +
249
"private static extern void Sleep(long dwMilliseconds);",
250
"Private Declare Ansi Sub Sleep Lib \"kernel32\" (ByVal dwMilliseconds As Long)");
254
public void Constructor()
256
TestMember("public tmp1() : base(1) { }",
257
"Public Sub New()\n MyBase.New(1)\nEnd Sub");
258
TestMember("public tmp1() : this(1) { }",
259
"Public Sub New()\n Me.New(1)\nEnd Sub");
263
public void StaticConstructor()
265
TestMember("static tmp1() { }",
266
"Shared Sub New()\nEnd Sub");
270
public void Destructor()
272
TestMember("~tmp1() { Dead(); }",
273
"Protected Overrides Sub Finalize()\n" +
277
" MyBase.Finalize()\n" +
283
public void Indexer()
285
TestMember("public CategoryInfo this[int index] { get { return List[index] as CategoryInfo; } }",
286
"Public Default ReadOnly Property Item(ByVal index As Integer) As CategoryInfo\n" +
288
" Return TryCast(List(index), CategoryInfo)\n" +
294
public void RenameConflictingNames()
296
TestMember("int count;" +
297
"public int Count { get { return count; } }" +
298
"void Test1(int count) { count = 3; }" +
299
"void Test2() { int count; count = 3; }" +
300
"void Test3() { foreach (int count in someList) { count = 3; } }",
302
"Private m_count As Integer\n" +
303
"Public ReadOnly Property Count() As Integer\n" +
305
" Return m_count\n" +
308
"Private Sub Test1(ByVal count As Integer)\n" +
311
"Private Sub Test2()\n" +
312
" Dim count As Integer\n" +
315
"Private Sub Test3()\n" +
316
" For Each count As Integer In someList\n" +
323
public void NullCoalescing()
325
TestStatement("c = a ?? b;",
330
public void Ternary()
332
TestStatement("d = a ? b : c;",
337
public void ConvertedLoop()
339
TestStatement("while (cond) example();",
346
public void UIntVariableDeclaration()
348
TestStatement("uint s = 0;", "Dim s As UInteger = 0");
352
public void BreakInWhileLoop()
354
TestStatement("while (test != null) { break; }",
355
"While test IsNot Nothing\n" +
361
public void BreakInDoLoop()
363
TestStatement("do { break; } while (test != null);",
366
"Loop While test IsNot Nothing");
370
public void StructFieldVisibility()
372
TestMember("public struct A { int field; }",
373
"Public Structure A\n" +
374
" Private field As Integer\n" +
379
public void InnerClassVisibility()
381
TestMember("class Inner\n{\n}",
382
"Private Class Inner\n" +
387
public void InnerDelegateVisibility()
389
TestMember("delegate void Test();",
390
"Private Delegate Sub Test()");
394
public void InterfaceVisibility()
396
TestMember("public interface ITest {\n" +
398
" string Name { get; set; }\n" +
400
"Public Interface ITest\n" +
402
" Property Name() As String\n" +
407
public void ImportAliasPrimitiveType()
409
TestProgram("using T = System.Boolean;", "Imports T = System.Boolean"+ Environment.NewLine);
413
public void DefaultExpression()
415
TestStatement("T oldValue = default(T);", "Dim oldValue As T = Nothing");
419
public void StaticClass()
421
TestProgram("public static class Test {}", @"Public NotInheritable Class Test" + Environment.NewLine +
422
" Private Sub New()" + Environment.NewLine +
423
" End Sub" + Environment.NewLine +
424
"End Class" + Environment.NewLine);
428
public void GlobalTypeReference()
430
TestStatement("global::System.String a;", "Dim a As Global.System.String");
434
public void TestMethodCallOnCastExpression()
436
TestStatement("((IDisposable)o).Dispose();", "DirectCast(o, IDisposable).Dispose()");
440
public void CaseConflictingMethod()
442
TestMember("void T(int v) { int V = v; M(V, v); }",
443
"Private Sub T(ByVal v__1 As Integer)\n" +
444
" Dim V__2 As Integer = v__1\n" +
450
public void ArrayCreationUpperBound()
452
TestStatement("string[] i = new string[2];",
453
"Dim i As String() = New String(1) {}");
454
TestStatement("string[] i = new string[2] { \"0\", \"1\" };",
455
"Dim i As String() = New String(1) {\"0\", \"1\"}");
456
TestStatement("string[,] i = new string[6, 6];",
457
"Dim i As String(,) = New String(5, 5) {}");
461
public void VariableNamedRem()
463
TestStatement("int rem;", "Dim [rem] As Integer");
464
TestStatement("int Rem;", "Dim [Rem] As Integer");
465
TestStatement("int a = rem;", "Dim a As Integer = [rem]");
469
public void ArrayCast()
471
TestStatement("string[] i = (string[])obj;",
472
"Dim i As String() = DirectCast(obj, String())");
474
// ensure the converter does not use CInt:
475
TestStatement("int[] i = (int[])obj;",
476
"Dim i As Integer() = DirectCast(obj, Integer())");
481
public void PrimitiveCast()
483
TestStatement("int a = (int)number;", "Dim a As Integer = CInt(number)");
484
TestStatement("byte i = (byte)obj;", "Dim i As Byte = CByte(obj)");
485
TestStatement("short i = (short)obj;", "Dim i As Short = CShort(obj)");
486
TestStatement("long i = (long)obj;", "Dim i As Long = CLng(obj)");
490
public void PrimitiveUnsignedCast()
492
TestStatement("uint i = (uint)obj;", "Dim i As UInteger = CUInt(obj)");
493
TestStatement("sbyte i = (sbyte)obj;", "Dim i As SByte = CSByte(obj)");
494
TestStatement("ushort i = (ushort)obj;", "Dim i As UShort = CUShort(obj)");
495
TestStatement("ulong i = (ulong)obj;", "Dim i As ULong = CULng(obj)");
499
public void InlineAssignment()
501
TestProgram(@"public class Convert { void Run(string s) { char c; if ((c = s[0]) == '\n') { c = ' '; } } }",
502
@"Public Class Convert" + Environment.NewLine +
503
" Private Sub Run(ByVal s As String)" + Environment.NewLine +
504
" Dim c As Char" + Environment.NewLine +
505
" If (InlineAssignHelper(c, s(0))) = ControlChars.Lf Then" + Environment.NewLine +
506
" c = \" \"C" + Environment.NewLine +
507
" End If" + Environment.NewLine +
508
" End Sub" + Environment.NewLine +
509
" Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T" + Environment.NewLine +
510
" target = value" + Environment.NewLine +
511
" Return value" + Environment.NewLine +
512
" End Function" + Environment.NewLine +
513
"End Class" + Environment.NewLine);
517
public void StandaloneBlockStatement()
519
TestStatement("{ int a; } { string a; }",
521
" Dim a As Integer\n" +
524
" Dim a As String\n" +
529
public void CSharpLinefeedToVBString()
531
TestStatement(@"string Test = ""My Test\n"";",
532
@"Dim Test As String = ""My Test"" & vbLf");
536
public void CSharpTabToVBString()
538
TestStatement(@"string Test = ""\t\a"";",
539
@"Dim Test As String = vbTab & ChrW(7)");
543
public void SizeOfInt32()
545
TestStatement(@"byte[] ret = new byte[IntPtr.Size * sizeof(int)];",
546
@"Dim ret As Byte() = New Byte(IntPtr.Size * 4 - 1) {}");
550
public void AutomaticProperty()
552
TestMember(@"public string Name { get; set; }",
553
@"Public Property Name() As String
561
Private m_Name As String");
565
public void AutomaticPropertyPrivateSetter()
567
TestMember(@"public string Name { get; private set; }",
568
@"Public Property Name() As String
576
Private m_Name As String");
580
public void DefaultValueExpression()
582
TestStatement(@"object x = default(int);",
583
@"Dim x As Object = 0");
587
public void BaseIndexerAccess()
589
TestStatement("object a = base[0];", "Dim a As Object = MyBase.Item(0)");
593
public void TestMemberHiding()
595
TestMember("public new void Remove() {}", "Public Shadows Sub Remove()\nEnd Sub");
599
public void TestImplicitlyTypedVariable()
601
TestStatement("var i = 0;", "Dim i = 0");
605
public void TestAnonymousType()
607
TestStatement("var x = new { i = 0, abc, abc.Test };",
608
"Dim x = New With { _\n" +
616
public void CollectionAndObjectInitializer()
618
TestStatement("List<X> l = new List<X> { new X { A = 1 }, new X { A = 2 } };",
619
"Dim l As New List(Of X)() From { _\n" +
620
" New X() With { _\n" +
623
" New X() With { _\n" +
630
public void SD2_970()
633
@"namespace MyNamespace
637
public partial class MainForm
644
Namespace MyNamespace
646
Public Partial Class MainForm
656
public void SD2_1424()
664
@"Public Function Min() As Integer
665
Dim min__1 As Integer = 5
672
public void GenericConstraint()
676
using System.Collections;
681
public class List<T> : CollectionBase where T : IDisposable
686
Imports System.Collections
690
Public Class List(Of T As IDisposable)
691
Inherits CollectionBase