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

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.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) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
 
2
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
 
3
 
 
4
using System;
 
5
using System.Collections.Generic;
 
6
using System.Diagnostics;
 
7
using System.Globalization;
 
8
using System.IO;
 
9
using System.Linq;
 
10
using System.Text;
 
11
 
 
12
using ICSharpCode.NRefactory.PatternMatching;
 
13
using ICSharpCode.NRefactory.VB.Ast;
 
14
 
 
15
namespace ICSharpCode.NRefactory.VB
 
16
{
 
17
        /// <summary>
 
18
        /// Description of OutputVisitor.
 
19
        /// </summary>
 
20
        public class OutputVisitor : IAstVisitor<object, object>
 
21
        {
 
22
                readonly IOutputFormatter formatter;
 
23
                readonly VBFormattingOptions policy;
 
24
                
 
25
                readonly Stack<AstNode> containerStack = new Stack<AstNode>();
 
26
                readonly Stack<AstNode> positionStack = new Stack<AstNode>();
 
27
                
 
28
                /// <summary>
 
29
                /// Used to insert the minimal amount of spaces so that the lexer recognizes the tokens that were written.
 
30
                /// </summary>
 
31
                LastWritten lastWritten;
 
32
                
 
33
                enum LastWritten
 
34
                {
 
35
                        Whitespace,
 
36
                        Other,
 
37
                        KeywordOrIdentifier
 
38
                }
 
39
                
 
40
                public OutputVisitor(TextWriter textWriter, VBFormattingOptions formattingPolicy)
 
41
                {
 
42
                        if (textWriter == null)
 
43
                                throw new ArgumentNullException("textWriter");
 
44
                        if (formattingPolicy == null)
 
45
                                throw new ArgumentNullException("formattingPolicy");
 
46
                        this.formatter = new TextWriterOutputFormatter(textWriter);
 
47
                        this.policy = formattingPolicy;
 
48
                }
 
49
                
 
50
                public OutputVisitor(IOutputFormatter formatter, VBFormattingOptions formattingPolicy)
 
51
                {
 
52
                        if (formatter == null)
 
53
                                throw new ArgumentNullException("formatter");
 
54
                        if (formattingPolicy == null)
 
55
                                throw new ArgumentNullException("formattingPolicy");
 
56
                        this.formatter = formatter;
 
57
                        this.policy = formattingPolicy;
 
58
                }
 
59
                
 
60
                public object VisitCompilationUnit(CompilationUnit compilationUnit, object data)
 
61
                {
 
62
                        // don't do node tracking as we visit all children directly
 
63
                        foreach (AstNode node in compilationUnit.Children)
 
64
                                node.AcceptVisitor(this, data);
 
65
                        return null;
 
66
                }
 
67
                
 
68
                public object VisitBlockStatement(BlockStatement blockStatement, object data)
 
69
                {
 
70
                        StartNode(blockStatement);
 
71
                        foreach (var stmt in blockStatement) {
 
72
                                stmt.AcceptVisitor(this, data);
 
73
                                NewLine();
 
74
                        }
 
75
                        return EndNode(blockStatement);
 
76
                }
 
77
                
 
78
                public object VisitPatternPlaceholder(AstNode placeholder, Pattern pattern, object data)
 
79
                {
 
80
                        throw new NotImplementedException();
 
81
                }
 
82
                
 
83
                public object VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration, object data)
 
84
                {
 
85
                        StartNode(typeParameterDeclaration);
 
86
                        
 
87
                        switch (typeParameterDeclaration.Variance) {
 
88
                                case ICSharpCode.NRefactory.TypeSystem.VarianceModifier.Invariant:
 
89
                                        break;
 
90
                                case ICSharpCode.NRefactory.TypeSystem.VarianceModifier.Covariant:
 
91
                                        WriteKeyword("Out");
 
92
                                        break;
 
93
                                case ICSharpCode.NRefactory.TypeSystem.VarianceModifier.Contravariant:
 
94
                                        WriteKeyword("In");
 
95
                                        break;
 
96
                                default:
 
97
                                        throw new Exception("Invalid value for VarianceModifier");
 
98
                        }
 
99
                        
 
100
                        WriteIdentifier(typeParameterDeclaration.Name);
 
101
                        if (typeParameterDeclaration.Constraints.Any()) {
 
102
                                WriteKeyword("As");
 
103
                                if (typeParameterDeclaration.Constraints.Count > 1)
 
104
                                        WriteToken("{", TypeParameterDeclaration.Roles.LBrace);
 
105
                                WriteCommaSeparatedList(typeParameterDeclaration.Constraints);
 
106
                                if (typeParameterDeclaration.Constraints.Count > 1)
 
107
                                        WriteToken("}", TypeParameterDeclaration.Roles.RBrace);
 
108
                        }
 
109
                        
 
110
                        return EndNode(typeParameterDeclaration);
 
111
                }
 
112
                
 
113
                public object VisitParameterDeclaration(ParameterDeclaration parameterDeclaration, object data)
 
114
                {
 
115
                        StartNode(parameterDeclaration);
 
116
                        WriteAttributes(parameterDeclaration.Attributes);
 
117
                        WriteModifiers(parameterDeclaration.ModifierTokens);
 
118
                        WriteIdentifier(parameterDeclaration.Name.Name);
 
119
                        if (!parameterDeclaration.Type.IsNull) {
 
120
                                WriteKeyword("As");
 
121
                                parameterDeclaration.Type.AcceptVisitor(this, data);
 
122
                        }
 
123
                        if (!parameterDeclaration.OptionalValue.IsNull) {
 
124
                                WriteToken("=", ParameterDeclaration.Roles.Assign);
 
125
                                parameterDeclaration.OptionalValue.AcceptVisitor(this, data);
 
126
                        }
 
127
                        return EndNode(parameterDeclaration);
 
128
                }
 
129
                
 
130
                public object VisitVBTokenNode(VBTokenNode vBTokenNode, object data)
 
131
                {
 
132
                        var mod = vBTokenNode as VBModifierToken;
 
133
                        if (mod != null) {
 
134
                                StartNode(vBTokenNode);
 
135
                                WriteKeyword(VBModifierToken.GetModifierName(mod.Modifier));
 
136
                                return EndNode(vBTokenNode);
 
137
                        } else {
 
138
                                throw new NotSupportedException("Should never visit individual tokens");
 
139
                        }
 
140
                }
 
141
                
 
142
                public object VisitAliasImportsClause(AliasImportsClause aliasImportsClause, object data)
 
143
                {
 
144
                        throw new NotImplementedException();
 
145
                }
 
146
                
 
147
                public object VisitAttribute(ICSharpCode.NRefactory.VB.Ast.Attribute attribute, object data)
 
148
                {
 
149
                        StartNode(attribute);
 
150
                        
 
151
                        if (attribute.Target != AttributeTarget.None) {
 
152
                                switch (attribute.Target) {
 
153
                                        case AttributeTarget.None:
 
154
                                                break;
 
155
                                        case AttributeTarget.Assembly:
 
156
                                                WriteKeyword("Assembly");
 
157
                                                break;
 
158
                                        case AttributeTarget.Module:
 
159
                                                WriteKeyword("Module");
 
160
                                                break;
 
161
                                        default:
 
162
                                                throw new Exception("Invalid value for AttributeTarget");
 
163
                                }
 
164
                                WriteToken(":", Ast.Attribute.Roles.Colon);
 
165
                                Space();
 
166
                        }
 
167
                        attribute.Type.AcceptVisitor(this, data);
 
168
                        WriteCommaSeparatedListInParenthesis(attribute.Arguments, false);
 
169
                        
 
170
                        return EndNode(attribute);
 
171
                }
 
172
                
 
173
                public object VisitAttributeBlock(AttributeBlock attributeBlock, object data)
 
174
                {
 
175
                        StartNode(attributeBlock);
 
176
                        
 
177
                        WriteToken("<", AttributeBlock.Roles.LChevron);
 
178
                        WriteCommaSeparatedList(attributeBlock.Attributes);
 
179
                        WriteToken(">", AttributeBlock.Roles.RChevron);
 
180
                        if (attributeBlock.Parent is ParameterDeclaration)
 
181
                                Space();
 
182
                        else
 
183
                                NewLine();
 
184
                        
 
185
                        return EndNode(attributeBlock);
 
186
                }
 
187
                
 
188
                public object VisitImportsStatement(ImportsStatement importsStatement, object data)
 
189
                {
 
190
                        StartNode(importsStatement);
 
191
                        
 
192
                        WriteKeyword("Imports", AstNode.Roles.Keyword);
 
193
                        Space();
 
194
                        WriteCommaSeparatedList(importsStatement.ImportsClauses);
 
195
                        NewLine();
 
196
                        
 
197
                        return EndNode(importsStatement);
 
198
                }
 
199
                
 
200
                public object VisitMemberImportsClause(MemberImportsClause memberImportsClause, object data)
 
201
                {
 
202
                        StartNode(memberImportsClause);
 
203
                        memberImportsClause.Member.AcceptVisitor(this, data);
 
204
                        return EndNode(memberImportsClause);
 
205
                }
 
206
                
 
207
                public object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data)
 
208
                {
 
209
                        StartNode(namespaceDeclaration);
 
210
                        NewLine();
 
211
                        WriteKeyword("Namespace");
 
212
                        bool isFirst = true;
 
213
                        foreach (Identifier node in namespaceDeclaration.Identifiers) {
 
214
                                if (isFirst) {
 
215
                                        isFirst = false;
 
216
                                } else {
 
217
                                        WriteToken(".", NamespaceDeclaration.Roles.Dot);
 
218
                                }
 
219
                                node.AcceptVisitor(this, null);
 
220
                        }
 
221
                        NewLine();
 
222
                        WriteMembers(namespaceDeclaration.Members);
 
223
                        WriteKeyword("End");
 
224
                        WriteKeyword("Namespace");
 
225
                        NewLine();
 
226
                        return EndNode(namespaceDeclaration);
 
227
                }
 
228
                
 
229
                public object VisitOptionStatement(OptionStatement optionStatement, object data)
 
230
                {
 
231
                        throw new NotImplementedException();
 
232
                }
 
233
                
 
234
                public object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
 
235
                {
 
236
                        StartNode(typeDeclaration);
 
237
                        WriteAttributes(typeDeclaration.Attributes);
 
238
                        WriteModifiers(typeDeclaration.ModifierTokens);
 
239
                        WriteClassTypeKeyword(typeDeclaration);
 
240
                        WriteIdentifier(typeDeclaration.Name.Name);
 
241
                        MarkFoldStart();
 
242
                        NewLine();
 
243
                        
 
244
                        if (!typeDeclaration.InheritsType.IsNull) {
 
245
                                Indent();
 
246
                                WriteKeyword("Inherits");
 
247
                                typeDeclaration.InheritsType.AcceptVisitor(this, data);
 
248
                                Unindent();
 
249
                                NewLine();
 
250
                        }
 
251
                        if (typeDeclaration.ImplementsTypes.Any()) {
 
252
                                Indent();
 
253
                                WriteImplementsClause(typeDeclaration.ImplementsTypes);
 
254
                                Unindent();
 
255
                                NewLine();
 
256
                        }
 
257
                        
 
258
                        if (!typeDeclaration.InheritsType.IsNull || typeDeclaration.ImplementsTypes.Any())
 
259
                        NewLine();
 
260
                        
 
261
                        WriteMembers(typeDeclaration.Members);
 
262
                        
 
263
                        WriteKeyword("End");
 
264
                        WriteClassTypeKeyword(typeDeclaration);
 
265
                        MarkFoldEnd();
 
266
                        NewLine();
 
267
                        return EndNode(typeDeclaration);
 
268
                }
 
269
 
 
270
                void WriteClassTypeKeyword(TypeDeclaration typeDeclaration)
 
271
                {
 
272
                        switch (typeDeclaration.ClassType) {
 
273
                                case ClassType.Class:
 
274
                                        WriteKeyword("Class");
 
275
                                        break;
 
276
                                case ClassType.Interface:
 
277
                                        WriteKeyword("Interface");
 
278
                                        break;
 
279
                                case ClassType.Struct:
 
280
                                        WriteKeyword("Structure");
 
281
                                        break;
 
282
                                case ClassType.Module:
 
283
                                        WriteKeyword("Module");
 
284
                                        break;
 
285
                                default:
 
286
                                        throw new Exception("Invalid value for ClassType");
 
287
                        }
 
288
                }
 
289
                
 
290
                public object VisitXmlNamespaceImportsClause(XmlNamespaceImportsClause xmlNamespaceImportsClause, object data)
 
291
                {
 
292
                        throw new NotImplementedException();
 
293
                }
 
294
                
 
295
                public object VisitEnumDeclaration(EnumDeclaration enumDeclaration, object data)
 
296
                {
 
297
                        StartNode(enumDeclaration);
 
298
                        
 
299
                        WriteAttributes(enumDeclaration.Attributes);
 
300
                        WriteModifiers(enumDeclaration.ModifierTokens);
 
301
                        WriteKeyword("Enum");
 
302
                        WriteIdentifier(enumDeclaration.Name.Name);
 
303
                        if (!enumDeclaration.UnderlyingType.IsNull) {
 
304
                                Space();
 
305
                                WriteKeyword("As");
 
306
                                enumDeclaration.UnderlyingType.AcceptVisitor(this, data);
 
307
                        }
 
308
                        MarkFoldStart();
 
309
                        NewLine();
 
310
                        
 
311
                        Indent();
 
312
                        foreach (var member in enumDeclaration.Members) {
 
313
                                member.AcceptVisitor(this, null);
 
314
                        }
 
315
                        Unindent();
 
316
                        
 
317
                        WriteKeyword("End");
 
318
                        WriteKeyword("Enum");
 
319
                        MarkFoldEnd();
 
320
                        NewLine();
 
321
                        
 
322
                        return EndNode(enumDeclaration);
 
323
                }
 
324
                
 
325
                public object VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration, object data)
 
326
                {
 
327
                        StartNode(enumMemberDeclaration);
 
328
                        
 
329
                        WriteAttributes(enumMemberDeclaration.Attributes);
 
330
                        WriteIdentifier(enumMemberDeclaration.Name.Name);
 
331
                        
 
332
                        if (!enumMemberDeclaration.Value.IsNull) {
 
333
                                Space();
 
334
                                WriteToken("=", EnumMemberDeclaration.Roles.Assign);
 
335
                                Space();
 
336
                                enumMemberDeclaration.Value.AcceptVisitor(this, data);
 
337
                        }
 
338
                        NewLine();
 
339
                        
 
340
                        return EndNode(enumMemberDeclaration);
 
341
                }
 
342
                
 
343
                public object VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration, object data)
 
344
                {
 
345
                        StartNode(delegateDeclaration);
 
346
                        
 
347
                        WriteAttributes(delegateDeclaration.Attributes);
 
348
                        WriteModifiers(delegateDeclaration.ModifierTokens);
 
349
                        WriteKeyword("Delegate");
 
350
                        if (delegateDeclaration.IsSub)
 
351
                                WriteKeyword("Sub");
 
352
                        else
 
353
                                WriteKeyword("Function");
 
354
                        WriteIdentifier(delegateDeclaration.Name.Name);
 
355
                        WriteTypeParameters(delegateDeclaration.TypeParameters);
 
356
                        WriteCommaSeparatedListInParenthesis(delegateDeclaration.Parameters, false);
 
357
                        if (!delegateDeclaration.IsSub) {
 
358
                                Space();
 
359
                                WriteKeyword("As");
 
360
                                WriteAttributes(delegateDeclaration.ReturnTypeAttributes);
 
361
                                delegateDeclaration.ReturnType.AcceptVisitor(this, data);
 
362
                        }
 
363
                        NewLine();
 
364
                        
 
365
                        return EndNode(delegateDeclaration);
 
366
                }
 
367
                
 
368
                public object VisitIdentifier(Identifier identifier, object data)
 
369
                {
 
370
                        StartNode(identifier);
 
371
                        WriteIdentifier(identifier.Name);
 
372
                        WriteTypeCharacter(identifier.TypeCharacter);
 
373
                        return EndNode(identifier);
 
374
                }
 
375
                
 
376
                public object VisitXmlIdentifier(XmlIdentifier xmlIdentifier, object data)
 
377
                {
 
378
                        throw new NotImplementedException();
 
379
                }
 
380
                
 
381
                public object VisitXmlLiteralString(XmlLiteralString xmlLiteralString, object data)
 
382
                {
 
383
                        throw new NotImplementedException();
 
384
                }
 
385
                
 
386
                public object VisitSimpleNameExpression(SimpleNameExpression simpleNameExpression, object data)
 
387
                {
 
388
                        StartNode(simpleNameExpression);
 
389
                        
 
390
                        simpleNameExpression.Identifier.AcceptVisitor(this, data);
 
391
                        WriteTypeArguments(simpleNameExpression.TypeArguments);
 
392
                        
 
393
                        return EndNode(simpleNameExpression);
 
394
                }
 
395
                
 
396
                public object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
 
397
                {
 
398
                        StartNode(primitiveExpression);
 
399
                        
 
400
                        WritePrimitiveValue(primitiveExpression.Value);
 
401
                        
 
402
                        return EndNode(primitiveExpression);
 
403
                }
 
404
                
 
405
                public object VisitInstanceExpression(InstanceExpression instanceExpression, object data)
 
406
                {
 
407
                        StartNode(instanceExpression);
 
408
                        
 
409
                        switch (instanceExpression.Type) {
 
410
                                case InstanceExpressionType.Me:
 
411
                                        WriteKeyword("Me");
 
412
                                        break;
 
413
                                case InstanceExpressionType.MyBase:
 
414
                                        WriteKeyword("MyBase");
 
415
                                        break;
 
416
                                case InstanceExpressionType.MyClass:
 
417
                                        WriteKeyword("MyClass");
 
418
                                        break;
 
419
                                default:
 
420
                                        throw new Exception("Invalid value for InstanceExpressionType");
 
421
                        }
 
422
                        
 
423
                        return EndNode(instanceExpression);
 
424
                }
 
425
                
 
426
                public object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data)
 
427
                {
 
428
                        StartNode(parenthesizedExpression);
 
429
                        
 
430
                        LPar();
 
431
                        parenthesizedExpression.Expression.AcceptVisitor(this, data);
 
432
                        RPar();
 
433
                        
 
434
                        return EndNode(parenthesizedExpression);
 
435
                }
 
436
                
 
437
                public object VisitGetTypeExpression(GetTypeExpression getTypeExpression, object data)
 
438
                {
 
439
                        StartNode(getTypeExpression);
 
440
                        
 
441
                        WriteKeyword("GetType");
 
442
                        LPar();
 
443
                        getTypeExpression.Type.AcceptVisitor(this, data);
 
444
                        RPar();
 
445
                        
 
446
                        return EndNode(getTypeExpression);
 
447
                }
 
448
                
 
449
                public object VisitTypeOfIsExpression(TypeOfIsExpression typeOfIsExpression, object data)
 
450
                {
 
451
                        StartNode(typeOfIsExpression);
 
452
                        
 
453
                        WriteKeyword("TypeOf");
 
454
                        typeOfIsExpression.TypeOfExpression.AcceptVisitor(this, data);
 
455
                        WriteKeyword("Is");
 
456
                        typeOfIsExpression.Type.AcceptVisitor(this, data);
 
457
                        
 
458
                        return EndNode(typeOfIsExpression);
 
459
                }
 
460
                
 
461
                public object VisitGetXmlNamespaceExpression(GetXmlNamespaceExpression getXmlNamespaceExpression, object data)
 
462
                {
 
463
                        throw new NotImplementedException();
 
464
                }
 
465
                
 
466
                public object VisitMemberAccessExpression(MemberAccessExpression memberAccessExpression, object data)
 
467
                {
 
468
                        StartNode(memberAccessExpression);
 
469
                        
 
470
                        memberAccessExpression.Target.AcceptVisitor(this, data);
 
471
                        WriteToken(".", MemberAccessExpression.Roles.Dot);
 
472
                        memberAccessExpression.MemberName.AcceptVisitor(this, data);
 
473
                        WriteTypeArguments(memberAccessExpression.TypeArguments);
 
474
                        
 
475
                        return EndNode(memberAccessExpression);
 
476
                }
 
477
                
 
478
                public object VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, object data)
 
479
                {
 
480
                        StartNode(typeReferenceExpression);
 
481
                        
 
482
                        typeReferenceExpression.Type.AcceptVisitor(this, data);
 
483
                        
 
484
                        return EndNode(typeReferenceExpression);
 
485
                }
 
486
                
 
487
                public object VisitEventMemberSpecifier(EventMemberSpecifier eventMemberSpecifier, object data)
 
488
                {
 
489
                        StartNode(eventMemberSpecifier);
 
490
                        
 
491
                        eventMemberSpecifier.Target.AcceptVisitor(this, data);
 
492
                        WriteToken(".", EventMemberSpecifier.Roles.Dot);
 
493
                        eventMemberSpecifier.Member.AcceptVisitor(this, data);
 
494
                        
 
495
                        return EndNode(eventMemberSpecifier);
 
496
                }
 
497
                
 
498
                public object VisitInterfaceMemberSpecifier(InterfaceMemberSpecifier interfaceMemberSpecifier, object data)
 
499
                {
 
500
                        StartNode(interfaceMemberSpecifier);
 
501
                        
 
502
                        interfaceMemberSpecifier.Target.AcceptVisitor(this, data);
 
503
                        WriteToken(".", EventMemberSpecifier.Roles.Dot);
 
504
                        interfaceMemberSpecifier.Member.AcceptVisitor(this, data);
 
505
                        
 
506
                        return EndNode(interfaceMemberSpecifier);
 
507
                }
 
508
                
 
509
                #region TypeMembers
 
510
                public object VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data)
 
511
                {
 
512
                        StartNode(constructorDeclaration);
 
513
                        
 
514
                        WriteAttributes(constructorDeclaration.Attributes);
 
515
                        WriteModifiers(constructorDeclaration.ModifierTokens);
 
516
                        WriteKeyword("Sub");
 
517
                        WriteKeyword("New");
 
518
                        WriteCommaSeparatedListInParenthesis(constructorDeclaration.Parameters, false);
 
519
                        MarkFoldStart();
 
520
                        NewLine();
 
521
                        
 
522
                        Indent();
 
523
                        WriteBlock(constructorDeclaration.Body);
 
524
                        Unindent();
 
525
                        
 
526
                        WriteKeyword("End");
 
527
                        WriteKeyword("Sub");
 
528
                        MarkFoldEnd();
 
529
                        NewLine();
 
530
                        
 
531
                        return EndNode(constructorDeclaration);
 
532
                }
 
533
                
 
534
                public object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data)
 
535
                {
 
536
                        StartNode(methodDeclaration);
 
537
                        
 
538
                        WriteAttributes(methodDeclaration.Attributes);
 
539
                        WriteModifiers(methodDeclaration.ModifierTokens);
 
540
                        if (methodDeclaration.IsSub)
 
541
                                WriteKeyword("Sub");
 
542
                        else
 
543
                                WriteKeyword("Function");
 
544
                        methodDeclaration.Name.AcceptVisitor(this, data);
 
545
                        WriteTypeParameters(methodDeclaration.TypeParameters);
 
546
                        WriteCommaSeparatedListInParenthesis(methodDeclaration.Parameters, false);
 
547
                        if (!methodDeclaration.IsSub && !methodDeclaration.ReturnType.IsNull) {
 
548
                                Space();
 
549
                                WriteKeyword("As");
 
550
                                WriteAttributes(methodDeclaration.ReturnTypeAttributes);
 
551
                                methodDeclaration.ReturnType.AcceptVisitor(this, data);
 
552
                        }
 
553
                        WriteHandlesClause(methodDeclaration.HandlesClause);
 
554
                        WriteImplementsClause(methodDeclaration.ImplementsClause);
 
555
                        if (!methodDeclaration.Body.IsNull) {
 
556
                                MarkFoldStart();
 
557
                                NewLine();
 
558
                                Indent();
 
559
                                WriteBlock(methodDeclaration.Body);
 
560
                                Unindent();
 
561
                                WriteKeyword("End");
 
562
                                if (methodDeclaration.IsSub)
 
563
                                        WriteKeyword("Sub");
 
564
                                else
 
565
                                        WriteKeyword("Function");
 
566
                                MarkFoldEnd();
 
567
                        }
 
568
                        NewLine();
 
569
                        
 
570
                        return EndNode(methodDeclaration);
 
571
                }
 
572
 
 
573
                public object VisitFieldDeclaration(FieldDeclaration fieldDeclaration, object data)
 
574
                {
 
575
                        StartNode(fieldDeclaration);
 
576
                        
 
577
                        WriteAttributes(fieldDeclaration.Attributes);
 
578
                        WriteModifiers(fieldDeclaration.ModifierTokens);
 
579
                        WriteCommaSeparatedList(fieldDeclaration.Variables);
 
580
                        NewLine();
 
581
                        
 
582
                        return EndNode(fieldDeclaration);
 
583
                }
 
584
                
 
585
                public object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
 
586
                {
 
587
                        StartNode(propertyDeclaration);
 
588
                        
 
589
                        WriteAttributes(propertyDeclaration.Attributes);
 
590
                        WriteModifiers(propertyDeclaration.ModifierTokens);
 
591
                        WriteKeyword("Property");
 
592
                        WriteIdentifier(propertyDeclaration.Name.Name);
 
593
                        WriteCommaSeparatedListInParenthesis(propertyDeclaration.Parameters, false);
 
594
                        if (!propertyDeclaration.ReturnType.IsNull) {
 
595
                                Space();
 
596
                                WriteKeyword("As");
 
597
                                WriteAttributes(propertyDeclaration.ReturnTypeAttributes);
 
598
                                propertyDeclaration.ReturnType.AcceptVisitor(this, data);
 
599
                        }
 
600
                        
 
601
                        bool needsBody = !propertyDeclaration.Getter.Body.IsNull || !propertyDeclaration.Setter.Body.IsNull;
 
602
                        
 
603
                        if (needsBody) {
 
604
                                MarkFoldStart();
 
605
                                NewLine();
 
606
                                Indent();
 
607
                                
 
608
                                if (!propertyDeclaration.Getter.Body.IsNull) {
 
609
                                        propertyDeclaration.Getter.AcceptVisitor(this, data);
 
610
                                }
 
611
                                
 
612
                                if (!propertyDeclaration.Setter.Body.IsNull) {
 
613
                                        propertyDeclaration.Setter.AcceptVisitor(this, data);
 
614
                                }
 
615
                                Unindent();
 
616
                                
 
617
                                WriteKeyword("End");
 
618
                                WriteKeyword("Property");
 
619
                                MarkFoldEnd();
 
620
                        }
 
621
                        NewLine();
 
622
                        
 
623
                        return EndNode(propertyDeclaration);
 
624
                }
 
625
                #endregion
 
626
                
 
627
                #region TypeName
 
628
                public object VisitPrimitiveType(PrimitiveType primitiveType, object data)
 
629
                {
 
630
                        StartNode(primitiveType);
 
631
                        
 
632
                        WriteKeyword(primitiveType.Keyword);
 
633
                        
 
634
                        return EndNode(primitiveType);
 
635
                }
 
636
                
 
637
                public object VisitQualifiedType(QualifiedType qualifiedType, object data)
 
638
                {
 
639
                        StartNode(qualifiedType);
 
640
                        
 
641
                        qualifiedType.Target.AcceptVisitor(this, data);
 
642
                        WriteToken(".", AstNode.Roles.Dot);
 
643
                        WriteIdentifier(qualifiedType.Name);
 
644
                        WriteTypeArguments(qualifiedType.TypeArguments);
 
645
                        
 
646
                        return EndNode(qualifiedType);
 
647
                }
 
648
                
 
649
                public object VisitComposedType(ComposedType composedType, object data)
 
650
                {
 
651
                        StartNode(composedType);
 
652
                        
 
653
                        composedType.BaseType.AcceptVisitor(this, data);
 
654
                        if (composedType.HasNullableSpecifier)
 
655
                                WriteToken("?", ComposedType.Roles.QuestionMark);
 
656
                        WriteArraySpecifiers(composedType.ArraySpecifiers);
 
657
                        
 
658
                        return EndNode(composedType);
 
659
                }
 
660
                
 
661
                public object VisitArraySpecifier(ArraySpecifier arraySpecifier, object data)
 
662
                {
 
663
                        StartNode(arraySpecifier);
 
664
                        
 
665
                        LPar();
 
666
                        for (int i = 0; i < arraySpecifier.Dimensions - 1; i++) {
 
667
                                WriteToken(",", ArraySpecifier.Roles.Comma);
 
668
                        }
 
669
                        RPar();
 
670
                        
 
671
                        return EndNode(arraySpecifier);
 
672
                }
 
673
                
 
674
                public object VisitSimpleType(SimpleType simpleType, object data)
 
675
                {
 
676
                        StartNode(simpleType);
 
677
                        
 
678
                        WriteIdentifier(simpleType.Identifier);
 
679
                        WriteTypeArguments(simpleType.TypeArguments);
 
680
                        
 
681
                        return EndNode(simpleType);
 
682
                }
 
683
                #endregion
 
684
                
 
685
                #region StartNode/EndNode
 
686
                void StartNode(AstNode node)
 
687
                {
 
688
                        // Ensure that nodes are visited in the proper nested order.
 
689
                        // Jumps to different subtrees are allowed only for the child of a placeholder node.
 
690
                        Debug.Assert(containerStack.Count == 0 || node.Parent == containerStack.Peek());
 
691
                        if (positionStack.Count > 0)
 
692
                                WriteSpecialsUpToNode(node);
 
693
                        containerStack.Push(node);
 
694
                        positionStack.Push(node.FirstChild);
 
695
                        formatter.StartNode(node);
 
696
                }
 
697
                
 
698
                object EndNode(AstNode node)
 
699
                {
 
700
                        Debug.Assert(node == containerStack.Peek());
 
701
                        AstNode pos = positionStack.Pop();
 
702
                        Debug.Assert(pos == null || pos.Parent == node);
 
703
                        WriteSpecials(pos, null);
 
704
                        containerStack.Pop();
 
705
                        formatter.EndNode(node);
 
706
                        return null;
 
707
                }
 
708
                #endregion
 
709
                
 
710
                #region WriteSpecials
 
711
                /// <summary>
 
712
                /// Writes all specials from start to end (exclusive). Does not touch the positionStack.
 
713
                /// </summary>
 
714
                void WriteSpecials(AstNode start, AstNode end)
 
715
                {
 
716
                        for (AstNode pos = start; pos != end; pos = pos.NextSibling) {
 
717
                                if (pos.Role == AstNode.Roles.Comment) {
 
718
                                        pos.AcceptVisitor(this, null);
 
719
                                }
 
720
                        }
 
721
                }
 
722
                
 
723
                /// <summary>
 
724
                /// Writes all specials between the current position (in the positionStack) and the next
 
725
                /// node with the specified role. Advances the current position.
 
726
                /// </summary>
 
727
                void WriteSpecialsUpToRole(Role role)
 
728
                {
 
729
                        for (AstNode pos = positionStack.Peek(); pos != null; pos = pos.NextSibling) {
 
730
                                if (pos.Role == role) {
 
731
                                        WriteSpecials(positionStack.Pop(), pos);
 
732
                                        positionStack.Push(pos);
 
733
                                        break;
 
734
                                }
 
735
                        }
 
736
                }
 
737
                
 
738
                /// <summary>
 
739
                /// Writes all specials between the current position (in the positionStack) and the specified node.
 
740
                /// Advances the current position.
 
741
                /// </summary>
 
742
                void WriteSpecialsUpToNode(AstNode node)
 
743
                {
 
744
                        for (AstNode pos = positionStack.Peek(); pos != null; pos = pos.NextSibling) {
 
745
                                if (pos == node) {
 
746
                                        WriteSpecials(positionStack.Pop(), pos);
 
747
                                        positionStack.Push(pos);
 
748
                                        break;
 
749
                                }
 
750
                        }
 
751
                }
 
752
                
 
753
                void WriteSpecialsUpToRole(Role role, AstNode nextNode)
 
754
                {
 
755
                        // Look for the role between the current position and the nextNode.
 
756
                        for (AstNode pos = positionStack.Peek(); pos != null && pos != nextNode; pos = pos.NextSibling) {
 
757
                                if (pos.Role == AstNode.Roles.Comma) {
 
758
                                        WriteSpecials(positionStack.Pop(), pos);
 
759
                                        positionStack.Push(pos);
 
760
                                        break;
 
761
                                }
 
762
                        }
 
763
                }
 
764
                #endregion
 
765
                
 
766
                #region Comma
 
767
                /// <summary>
 
768
                /// Writes a comma.
 
769
                /// </summary>
 
770
                /// <param name="nextNode">The next node after the comma.</param>
 
771
                /// <param name="noSpacesAfterComma">When set prevents printing a space after comma.</param>
 
772
                void Comma(AstNode nextNode, bool noSpaceAfterComma = false)
 
773
                {
 
774
                        WriteSpecialsUpToRole(AstNode.Roles.Comma, nextNode);
 
775
                        formatter.WriteToken(",");
 
776
                        lastWritten = LastWritten.Other;
 
777
                        Space(!noSpaceAfterComma); // TODO: Comma policy has changed.
 
778
                }
 
779
                
 
780
                void WriteCommaSeparatedList(IEnumerable<AstNode> list)
 
781
                {
 
782
                        bool isFirst = true;
 
783
                        foreach (AstNode node in list) {
 
784
                                if (isFirst) {
 
785
                                        isFirst = false;
 
786
                                } else {
 
787
                                        Comma(node);
 
788
                                }
 
789
                                node.AcceptVisitor(this, null);
 
790
                        }
 
791
                }
 
792
                
 
793
                void WriteCommaSeparatedListInParenthesis(IEnumerable<AstNode> list, bool spaceWithin)
 
794
                {
 
795
                        LPar();
 
796
                        if (list.Any()) {
 
797
                                Space(spaceWithin);
 
798
                                WriteCommaSeparatedList(list);
 
799
                                Space(spaceWithin);
 
800
                        }
 
801
                        RPar();
 
802
                }
 
803
                
 
804
                #if DOTNET35
 
805
                void WriteCommaSeparatedList(IEnumerable<VariableInitializer> list)
 
806
                {
 
807
                        WriteCommaSeparatedList(list);
 
808
                }
 
809
                
 
810
                void WriteCommaSeparatedList(IEnumerable<AstType> list)
 
811
                {
 
812
                        WriteCommaSeparatedList(list);
 
813
                }
 
814
                
 
815
                void WriteCommaSeparatedListInParenthesis(IEnumerable<Expression> list, bool spaceWithin)
 
816
                {
 
817
                        WriteCommaSeparatedListInParenthesis(list.SafeCast<Expression, AstNode>(), spaceWithin);
 
818
                }
 
819
                
 
820
                void WriteCommaSeparatedListInParenthesis(IEnumerable<ParameterDeclaration> list, bool spaceWithin)
 
821
                {
 
822
                        WriteCommaSeparatedListInParenthesis(list.SafeCast<ParameterDeclaration, AstNode>(), spaceWithin);
 
823
                }
 
824
 
 
825
                #endif
 
826
 
 
827
                void WriteCommaSeparatedListInBrackets(IEnumerable<ParameterDeclaration> list, bool spaceWithin)
 
828
                {
 
829
                        WriteToken("[", AstNode.Roles.LBracket);
 
830
                        if (list.Any()) {
 
831
                                Space(spaceWithin);
 
832
                                WriteCommaSeparatedList(list);
 
833
                                Space(spaceWithin);
 
834
                        }
 
835
                        WriteToken("]", AstNode.Roles.RBracket);
 
836
                }
 
837
 
 
838
                void WriteCommaSeparatedListInBrackets(IEnumerable<Expression> list)
 
839
                {
 
840
                        WriteToken ("[", AstNode.Roles.LBracket);
 
841
                        if (list.Any ()) {
 
842
                                Space();
 
843
                                WriteCommaSeparatedList(list);
 
844
                                Space();
 
845
                        }
 
846
                        WriteToken ("]", AstNode.Roles.RBracket);
 
847
                }
 
848
                #endregion
 
849
                
 
850
                #region Write tokens
 
851
                /// <summary>
 
852
                /// Writes a keyword, and all specials up to
 
853
                /// </summary>
 
854
                void WriteKeyword(string keyword, Role<VBTokenNode> tokenRole = null)
 
855
                {
 
856
                        WriteSpecialsUpToRole(tokenRole ?? AstNode.Roles.Keyword);
 
857
                        if (lastWritten == LastWritten.KeywordOrIdentifier)
 
858
                                formatter.Space();
 
859
                        formatter.WriteKeyword(keyword);
 
860
                        lastWritten = LastWritten.KeywordOrIdentifier;
 
861
                }
 
862
                
 
863
                void WriteIdentifier(string identifier, Role<Identifier> identifierRole = null)
 
864
                {
 
865
                        WriteSpecialsUpToRole(identifierRole ?? AstNode.Roles.Identifier);
 
866
                        if (IsKeyword(identifier, containerStack.Peek())) {
 
867
                                if (lastWritten == LastWritten.KeywordOrIdentifier)
 
868
                                        Space(); // this space is not strictly required, so we call Space()
 
869
                                formatter.WriteToken("[");
 
870
                        } else if (lastWritten == LastWritten.KeywordOrIdentifier) {
 
871
                                formatter.Space(); // this space is strictly required, so we directly call the formatter
 
872
                        }
 
873
                        formatter.WriteIdentifier(identifier);
 
874
                        if (IsKeyword(identifier, containerStack.Peek())) {
 
875
                                formatter.WriteToken("]");
 
876
                        }
 
877
                        lastWritten = LastWritten.KeywordOrIdentifier;
 
878
                }
 
879
                
 
880
                void WriteToken(string token, Role<VBTokenNode> tokenRole)
 
881
                {
 
882
                        WriteSpecialsUpToRole(tokenRole);
 
883
                        // Avoid that two +, - or ? tokens are combined into a ++, -- or ?? token.
 
884
                        // Note that we don't need to handle tokens like = because there's no valid
 
885
                        // C# program that contains the single token twice in a row.
 
886
                        // (for +, - and &, this can happen with unary operators;
 
887
                        // for ?, this can happen in "a is int? ? b : c" or "a as int? ?? 0";
 
888
                        // and for /, this can happen with "1/ *ptr" or "1/ //comment".)
 
889
//                      if (lastWritten == LastWritten.Plus && token[0] == '+'
 
890
//                          || lastWritten == LastWritten.Minus && token[0] == '-'
 
891
//                          || lastWritten == LastWritten.Ampersand && token[0] == '&'
 
892
//                          || lastWritten == LastWritten.QuestionMark && token[0] == '?'
 
893
//                          || lastWritten == LastWritten.Division && token[0] == '*')
 
894
//                      {
 
895
//                              formatter.Space();
 
896
//                      }
 
897
                        formatter.WriteToken(token);
 
898
//                      if (token == "+")
 
899
//                              lastWritten = LastWritten.Plus;
 
900
//                      else if (token == "-")
 
901
//                              lastWritten = LastWritten.Minus;
 
902
//                      else if (token == "&")
 
903
//                              lastWritten = LastWritten.Ampersand;
 
904
//                      else if (token == "?")
 
905
//                              lastWritten = LastWritten.QuestionMark;
 
906
//                      else if (token == "/")
 
907
//                              lastWritten = LastWritten.Division;
 
908
//                      else
 
909
                        lastWritten = LastWritten.Other;
 
910
                }
 
911
                
 
912
                void WriteTypeCharacter(TypeCode typeCharacter)
 
913
                {
 
914
                        switch (typeCharacter) {
 
915
                                case TypeCode.Empty:
 
916
                                case TypeCode.Object:
 
917
                                case TypeCode.DBNull:
 
918
                                case TypeCode.Boolean:
 
919
                                case TypeCode.Char:
 
920
                                        
 
921
                                        break;
 
922
                                case TypeCode.SByte:
 
923
                                        
 
924
                                        break;
 
925
                                case TypeCode.Byte:
 
926
                                        
 
927
                                        break;
 
928
                                case TypeCode.Int16:
 
929
                                        
 
930
                                        break;
 
931
                                case TypeCode.UInt16:
 
932
                                        
 
933
                                        break;
 
934
                                case TypeCode.Int32:
 
935
                                        WriteToken("%", null);
 
936
                                        break;
 
937
                                case TypeCode.UInt32:
 
938
                                        
 
939
                                        break;
 
940
                                case TypeCode.Int64:
 
941
                                        WriteToken("&", null);
 
942
                                        break;
 
943
                                case TypeCode.UInt64:
 
944
                                        
 
945
                                        break;
 
946
                                case TypeCode.Single:
 
947
                                        WriteToken("!", null);
 
948
                                        break;
 
949
                                case TypeCode.Double:
 
950
                                        WriteToken("#", null);
 
951
                                        break;
 
952
                                case TypeCode.Decimal:
 
953
                                        WriteToken("@", null);
 
954
                                        break;
 
955
                                case TypeCode.DateTime:
 
956
                                        
 
957
                                        break;
 
958
                                case TypeCode.String:
 
959
                                        WriteToken("$", null);
 
960
                                        break;
 
961
                                default:
 
962
                                        throw new Exception("Invalid value for TypeCode");
 
963
                        }
 
964
                }
 
965
                
 
966
                void LPar()
 
967
                {
 
968
                        WriteToken("(", AstNode.Roles.LPar);
 
969
                }
 
970
                
 
971
                void RPar()
 
972
                {
 
973
                        WriteToken(")", AstNode.Roles.LPar);
 
974
                }
 
975
                
 
976
                /// <summary>
 
977
                /// Writes a space depending on policy.
 
978
                /// </summary>
 
979
                void Space(bool addSpace = true)
 
980
                {
 
981
                        if (addSpace) {
 
982
                                formatter.Space();
 
983
                                lastWritten = LastWritten.Whitespace;
 
984
                        }
 
985
                }
 
986
                
 
987
                void NewLine()
 
988
                {
 
989
                        formatter.NewLine();
 
990
                        lastWritten = LastWritten.Whitespace;
 
991
                }
 
992
                
 
993
                void Indent()
 
994
                {
 
995
                        formatter.Indent();
 
996
                }
 
997
                
 
998
                void Unindent()
 
999
                {
 
1000
                        formatter.Unindent();
 
1001
                }
 
1002
                
 
1003
                void MarkFoldStart()
 
1004
                {
 
1005
                        formatter.MarkFoldStart();
 
1006
                }
 
1007
                
 
1008
                void MarkFoldEnd()
 
1009
                {
 
1010
                        formatter.MarkFoldEnd();
 
1011
                }
 
1012
                #endregion
 
1013
                
 
1014
                #region IsKeyword Test
 
1015
                static readonly HashSet<string> unconditionalKeywords = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {
 
1016
                        "AddHandler", "AddressOf", "Alias", "And", "AndAlso", "As", "Boolean", "ByRef", "Byte",
 
1017
                        "ByVal", "Call", "Case", "Catch", "CBool", "CByte", "CChar", "CInt", "Class", "CLng",
 
1018
                        "CObj", "Const", "Continue", "CSByte", "CShort", "CSng", "CStr", "CType", "CUInt",
 
1019
                        "CULng", "CUShort", "Date", "Decimal", "Declare", "Default", "Delegate", "Dim",
 
1020
                        "DirectCast", "Do", "Double", "Each", "Else", "ElseIf", "End", "EndIf", "Enum", "Erase",
 
1021
                        "Error", "Event", "Exit", "False", "Finally", "For", "Friend", "Function", "Get",
 
1022
                        "GetType", "GetXmlNamespace", "Global", "GoSub", "GoTo", "Handles", "If", "Implements",
 
1023
                        "Imports", "In", "Inherits", "Integer", "Interface", "Is", "IsNot", "Let", "Lib", "Like",
 
1024
                        "Long", "Loop", "Me", "Mod", "Module", "MustInherit", "MustOverride", "MyBase", "MyClass",
 
1025
                        "Namespace", "Narrowing", "New", "Next", "Not", "Nothing", "NotInheritable", "NotOverridable",
 
1026
                        "Object", "Of", "On", "Operator", "Option", "Optional", "Or", "OrElse", "Overloads",
 
1027
                        "Overridable", "Overrides", "ParamArray", "Partial", "Private", "Property", "Protected",
 
1028
                        "Public", "RaiseEvent", "ReadOnly", "ReDim", "REM", "RemoveHandler", "Resume", "Return",
 
1029
                        "SByte", "Select", "Set", "Shadows", "Shared", "Short", "Single", "Static", "Step", "Stop",
 
1030
                        "String", "Structure", "Sub", "SyncLock", "Then", "Throw", "To", "True", "Try", "TryCast",
 
1031
                        "TypeOf", "UInteger", "ULong", "UShort", "Using", "Variant", "Wend", "When", "While",
 
1032
                        "Widening", "With", "WithEvents", "WriteOnly", "Xor"
 
1033
                };
 
1034
                
 
1035
                static readonly HashSet<string> queryKeywords = new HashSet<string> {
 
1036
                        
 
1037
                };
 
1038
                
 
1039
                /// <summary>
 
1040
                /// Determines whether the specified identifier is a keyword in the given context.
 
1041
                /// </summary>
 
1042
                public static bool IsKeyword(string identifier, AstNode context)
 
1043
                {
 
1044
                        if (unconditionalKeywords.Contains(identifier))
 
1045
                                return true;
 
1046
//                      if (context.Ancestors.Any(a => a is QueryExpression)) {
 
1047
//                              if (queryKeywords.Contains(identifier))
 
1048
//                                      return true;
 
1049
//                      }
 
1050
                        return false;
 
1051
                }
 
1052
                #endregion
 
1053
                
 
1054
                #region Write constructs
 
1055
                void WriteTypeArguments(IEnumerable<AstType> typeArguments)
 
1056
                {
 
1057
                        if (typeArguments.Any()) {
 
1058
                                LPar();
 
1059
                                WriteKeyword("Of");
 
1060
                                WriteCommaSeparatedList(typeArguments);
 
1061
                                RPar();
 
1062
                        }
 
1063
                }
 
1064
                
 
1065
                void WriteTypeParameters(IEnumerable<TypeParameterDeclaration> typeParameters)
 
1066
                {
 
1067
                        if (typeParameters.Any()) {
 
1068
                                LPar();
 
1069
                                WriteKeyword("Of");
 
1070
                                WriteCommaSeparatedList(typeParameters);
 
1071
                                RPar();
 
1072
                        }
 
1073
                }
 
1074
                
 
1075
                void WriteModifiers(IEnumerable<VBModifierToken> modifierTokens)
 
1076
                {
 
1077
                        foreach (VBModifierToken modifier in modifierTokens) {
 
1078
                                modifier.AcceptVisitor(this, null);
 
1079
                        }
 
1080
                }
 
1081
                
 
1082
                void WriteArraySpecifiers(IEnumerable<ArraySpecifier> arraySpecifiers)
 
1083
                {
 
1084
                        foreach (ArraySpecifier specifier in arraySpecifiers) {
 
1085
                                specifier.AcceptVisitor(this, null);
 
1086
                        }
 
1087
                }
 
1088
                
 
1089
                void WriteQualifiedIdentifier(IEnumerable<Identifier> identifiers)
 
1090
                {
 
1091
                        bool first = true;
 
1092
                        foreach (Identifier ident in identifiers) {
 
1093
                                if (first) {
 
1094
                                        first = false;
 
1095
                                        if (lastWritten == LastWritten.KeywordOrIdentifier)
 
1096
                                                formatter.Space();
 
1097
                                } else {
 
1098
                                        WriteSpecialsUpToRole(AstNode.Roles.Dot, ident);
 
1099
                                        formatter.WriteToken(".");
 
1100
                                        lastWritten = LastWritten.Other;
 
1101
                                }
 
1102
                                WriteSpecialsUpToNode(ident);
 
1103
                                formatter.WriteIdentifier(ident.Name);
 
1104
                                lastWritten = LastWritten.KeywordOrIdentifier;
 
1105
                        }
 
1106
                }
 
1107
                
 
1108
                void WriteEmbeddedStatement(Statement embeddedStatement)
 
1109
                {
 
1110
                        if (embeddedStatement.IsNull)
 
1111
                                return;
 
1112
                        BlockStatement block = embeddedStatement as BlockStatement;
 
1113
                        if (block != null)
 
1114
                                VisitBlockStatement(block, null);
 
1115
                        else
 
1116
                                embeddedStatement.AcceptVisitor(this, null);
 
1117
                }
 
1118
                
 
1119
                void WriteBlock(BlockStatement body)
 
1120
                {
 
1121
                        if (body.IsNull)
 
1122
                                NewLine();
 
1123
                        else
 
1124
                                VisitBlockStatement(body, null);
 
1125
                }
 
1126
                
 
1127
                void WriteMembers(IEnumerable<AstNode> members)
 
1128
                {
 
1129
                        Indent();
 
1130
                        bool isFirst = true;
 
1131
                        foreach (var member in members) {
 
1132
                                if (isFirst) {
 
1133
                                        isFirst = false;
 
1134
                                } else {
 
1135
                                        NewLine();
 
1136
                                }
 
1137
                                member.AcceptVisitor(this, null);
 
1138
                        }
 
1139
                        Unindent();
 
1140
                }
 
1141
                
 
1142
                void WriteAttributes(IEnumerable<AttributeBlock> attributes)
 
1143
                {
 
1144
                        foreach (AttributeBlock attr in attributes) {
 
1145
                                attr.AcceptVisitor(this, null);
 
1146
                        }
 
1147
                }
 
1148
                
 
1149
                void WritePrivateImplementationType(AstType privateImplementationType)
 
1150
                {
 
1151
                        if (!privateImplementationType.IsNull) {
 
1152
                                privateImplementationType.AcceptVisitor(this, null);
 
1153
                                WriteToken(".", AstNode.Roles.Dot);
 
1154
                        }
 
1155
                }
 
1156
                
 
1157
                void WriteImplementsClause(AstNodeCollection<InterfaceMemberSpecifier> implementsClause)
 
1158
                {
 
1159
                        if (implementsClause.Any()) {
 
1160
                                Space();
 
1161
                                WriteKeyword("Implements");
 
1162
                                WriteCommaSeparatedList(implementsClause);
 
1163
                        }
 
1164
                }
 
1165
                
 
1166
                void WriteImplementsClause(AstNodeCollection<AstType> implementsClause)
 
1167
                {
 
1168
                        if (implementsClause.Any()) {
 
1169
                                WriteKeyword("Implements");
 
1170
                                WriteCommaSeparatedList(implementsClause);
 
1171
                        }
 
1172
                }
 
1173
                
 
1174
                void WriteHandlesClause(AstNodeCollection<EventMemberSpecifier> handlesClause)
 
1175
                {
 
1176
                        if (handlesClause.Any()) {
 
1177
                                Space();
 
1178
                                WriteKeyword("Handles");
 
1179
                                WriteCommaSeparatedList(handlesClause);
 
1180
                        }
 
1181
                }
 
1182
                
 
1183
                void WritePrimitiveValue(object val)
 
1184
                {
 
1185
                        if (val == null) {
 
1186
                                WriteKeyword("Nothing");
 
1187
                                return;
 
1188
                        }
 
1189
                        
 
1190
                        if (val is bool) {
 
1191
                                if ((bool)val) {
 
1192
                                        WriteKeyword("True");
 
1193
                                } else {
 
1194
                                        WriteKeyword("False");
 
1195
                                }
 
1196
                                return;
 
1197
                        }
 
1198
                        
 
1199
                        if (val is string) {
 
1200
                                formatter.WriteToken("\"" + ConvertString(val.ToString()) + "\"");
 
1201
                                lastWritten = LastWritten.Other;
 
1202
                        } else if (val is char) {
 
1203
                                formatter.WriteToken("\"" + ConvertCharLiteral((char)val) + "\"c");
 
1204
                                lastWritten = LastWritten.Other;
 
1205
                        } else if (val is decimal) {
 
1206
                                formatter.WriteToken(((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "D");
 
1207
                                lastWritten = LastWritten.Other;
 
1208
                        } else if (val is float) {
 
1209
                                float f = (float)val;
 
1210
                                if (float.IsInfinity(f) || float.IsNaN(f)) {
 
1211
                                        // Strictly speaking, these aren't PrimitiveExpressions;
 
1212
                                        // but we still support writing these to make life easier for code generators.
 
1213
                                        WriteKeyword("Single");
 
1214
                                        WriteToken(".", AstNode.Roles.Dot);
 
1215
                                        if (float.IsPositiveInfinity(f))
 
1216
                                                WriteIdentifier("PositiveInfinity");
 
1217
                                        else if (float.IsNegativeInfinity(f))
 
1218
                                                WriteIdentifier("NegativeInfinity");
 
1219
                                        else
 
1220
                                                WriteIdentifier("NaN");
 
1221
                                        return;
 
1222
                                }
 
1223
                                formatter.WriteToken(f.ToString("R", NumberFormatInfo.InvariantInfo) + "F");
 
1224
                                lastWritten = LastWritten.Other;
 
1225
                        } else if (val is double) {
 
1226
                                double f = (double)val;
 
1227
                                if (double.IsInfinity(f) || double.IsNaN(f)) {
 
1228
                                        // Strictly speaking, these aren't PrimitiveExpressions;
 
1229
                                        // but we still support writing these to make life easier for code generators.
 
1230
                                        WriteKeyword("Double");
 
1231
                                        WriteToken(".", AstNode.Roles.Dot);
 
1232
                                        if (double.IsPositiveInfinity(f))
 
1233
                                                WriteIdentifier("PositiveInfinity");
 
1234
                                        else if (double.IsNegativeInfinity(f))
 
1235
                                                WriteIdentifier("NegativeInfinity");
 
1236
                                        else
 
1237
                                                WriteIdentifier("NaN");
 
1238
                                        return;
 
1239
                                }
 
1240
                                string number = f.ToString("R", NumberFormatInfo.InvariantInfo);
 
1241
                                if (number.IndexOf('.') < 0 && number.IndexOf('E') < 0)
 
1242
                                        number += ".0";
 
1243
                                formatter.WriteToken(number);
 
1244
                                // needs space if identifier follows number; this avoids mistaking the following identifier as type suffix
 
1245
                                lastWritten = LastWritten.KeywordOrIdentifier;
 
1246
                        } else if (val is IFormattable) {
 
1247
                                StringBuilder b = new StringBuilder();
 
1248
//                              if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) {
 
1249
//                                      b.Append("0x");
 
1250
//                                      b.Append(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo));
 
1251
//                              } else {
 
1252
                                b.Append(((IFormattable)val).ToString(null, NumberFormatInfo.InvariantInfo));
 
1253
//                              }
 
1254
                                if (val is uint || val is ulong) {
 
1255
                                        b.Append("U");
 
1256
                                }
 
1257
                                if (val is long || val is ulong) {
 
1258
                                        b.Append("L");
 
1259
                                }
 
1260
                                formatter.WriteToken(b.ToString());
 
1261
                                // needs space if identifier follows number; this avoids mistaking the following identifier as type suffix
 
1262
                                lastWritten = LastWritten.KeywordOrIdentifier;
 
1263
                        } else {
 
1264
                                formatter.WriteToken(val.ToString());
 
1265
                                lastWritten = LastWritten.Other;
 
1266
                        }
 
1267
                }
 
1268
                #endregion
 
1269
                
 
1270
                #region ConvertLiteral
 
1271
                static string ConvertCharLiteral(char ch)
 
1272
                {
 
1273
                        if (ch == '"') return "\"\"";
 
1274
                        return ch.ToString();
 
1275
                }
 
1276
                
 
1277
                static string ConvertString(string str)
 
1278
                {
 
1279
                        StringBuilder sb = new StringBuilder();
 
1280
                        foreach (char ch in str) {
 
1281
                                sb.Append(ConvertCharLiteral(ch));
 
1282
                        }
 
1283
                        return sb.ToString();
 
1284
                }
 
1285
                #endregion
 
1286
                
 
1287
                public object VisitVariableIdentifier(VariableIdentifier variableIdentifier, object data)
 
1288
                {
 
1289
                        StartNode(variableIdentifier);
 
1290
                        
 
1291
                        WriteIdentifier(variableIdentifier.Name.Name);
 
1292
                        if (variableIdentifier.HasNullableSpecifier)
 
1293
                                WriteToken("?", VariableIdentifier.Roles.QuestionMark);
 
1294
                        WriteArraySpecifiers(variableIdentifier.ArraySpecifiers);
 
1295
                        
 
1296
                        return EndNode(variableIdentifier);
 
1297
                }
 
1298
                
 
1299
                public object VisitAccessor(Accessor accessor, object data)
 
1300
                {
 
1301
                        StartNode(accessor);
 
1302
                        WriteAttributes(accessor.Attributes);
 
1303
                        WriteModifiers(accessor.ModifierTokens);
 
1304
                        if (accessor.Role == PropertyDeclaration.GetterRole) {
 
1305
                                WriteKeyword("Get");
 
1306
                        } else if (accessor.Role == PropertyDeclaration.SetterRole) {
 
1307
                                WriteKeyword("Set");
 
1308
                        } else if (accessor.Role == EventDeclaration.AddHandlerRole) {
 
1309
                                WriteKeyword("AddHandler");
 
1310
                        } else if (accessor.Role == EventDeclaration.RemoveHandlerRole) {
 
1311
                                WriteKeyword("RemoveHandler");
 
1312
                        } else if (accessor.Role == EventDeclaration.RaiseEventRole) {
 
1313
                                WriteKeyword("RaiseEvent");
 
1314
                        }
 
1315
                        if (accessor.Parameters.Any())
 
1316
                                WriteCommaSeparatedListInParenthesis(accessor.Parameters, false);
 
1317
                        NewLine();
 
1318
                        Indent();
 
1319
                        WriteBlock(accessor.Body);
 
1320
                        Unindent();
 
1321
                        WriteKeyword("End");
 
1322
 
 
1323
                        if (accessor.Role == PropertyDeclaration.GetterRole) {
 
1324
                                WriteKeyword("Get");
 
1325
                        } else if (accessor.Role == PropertyDeclaration.SetterRole) {
 
1326
                                WriteKeyword("Set");
 
1327
                        } else if (accessor.Role == EventDeclaration.AddHandlerRole) {
 
1328
                                WriteKeyword("AddHandler");
 
1329
                        } else if (accessor.Role == EventDeclaration.RemoveHandlerRole) {
 
1330
                                WriteKeyword("RemoveHandler");
 
1331
                        } else if (accessor.Role == EventDeclaration.RaiseEventRole) {
 
1332
                                WriteKeyword("RaiseEvent");
 
1333
                        }
 
1334
                        NewLine();
 
1335
                        
 
1336
                        return EndNode(accessor);
 
1337
                }
 
1338
 
 
1339
                
 
1340
                public object VisitLabelDeclarationStatement(LabelDeclarationStatement labelDeclarationStatement, object data)
 
1341
                {
 
1342
                        StartNode(labelDeclarationStatement);
 
1343
                        
 
1344
                        labelDeclarationStatement.Label.AcceptVisitor(this, data);
 
1345
                        WriteToken(":", LabelDeclarationStatement.Roles.Colon);
 
1346
                        
 
1347
                        return EndNode(labelDeclarationStatement);
 
1348
                }
 
1349
                
 
1350
                public object VisitLocalDeclarationStatement(LocalDeclarationStatement localDeclarationStatement, object data)
 
1351
                {
 
1352
                        StartNode(localDeclarationStatement);
 
1353
                        
 
1354
                        if (localDeclarationStatement.ModifierToken != null && !localDeclarationStatement.ModifierToken.IsNull)
 
1355
                                WriteModifiers(new [] { localDeclarationStatement.ModifierToken });
 
1356
                        WriteCommaSeparatedList(localDeclarationStatement.Variables);
 
1357
                        
 
1358
                        return EndNode(localDeclarationStatement);
 
1359
                }
 
1360
                
 
1361
                public object VisitWithStatement(WithStatement withStatement, object data)
 
1362
                {
 
1363
                        StartNode(withStatement);
 
1364
                        WriteKeyword("With");
 
1365
                        withStatement.Expression.AcceptVisitor(this, data);
 
1366
                        NewLine();
 
1367
                        Indent();
 
1368
                        withStatement.Body.AcceptVisitor(this, data);
 
1369
                        Unindent();
 
1370
                        WriteKeyword("End");
 
1371
                        WriteKeyword("With");
 
1372
                        return EndNode(withStatement);
 
1373
                }
 
1374
                
 
1375
                public object VisitSyncLockStatement(SyncLockStatement syncLockStatement, object data)
 
1376
                {
 
1377
                        StartNode(syncLockStatement);
 
1378
                        WriteKeyword("SyncLock");
 
1379
                        syncLockStatement.Expression.AcceptVisitor(this, data);
 
1380
                        NewLine();
 
1381
                        Indent();
 
1382
                        syncLockStatement.Body.AcceptVisitor(this, data);
 
1383
                        Unindent();
 
1384
                        WriteKeyword("End");
 
1385
                        WriteKeyword("SyncLock");
 
1386
                        return EndNode(syncLockStatement);
 
1387
                }
 
1388
                
 
1389
                public object VisitTryStatement(TryStatement tryStatement, object data)
 
1390
                {
 
1391
                        StartNode(tryStatement);
 
1392
                        WriteKeyword("Try");
 
1393
                        NewLine();
 
1394
                        Indent();
 
1395
                        tryStatement.Body.AcceptVisitor(this, data);
 
1396
                        Unindent();
 
1397
                        foreach (var clause in tryStatement.CatchBlocks) {
 
1398
                                clause.AcceptVisitor(this, data);
 
1399
                        }
 
1400
                        if (!tryStatement.FinallyBlock.IsNull) {
 
1401
                                WriteKeyword("Finally");
 
1402
                                NewLine();
 
1403
                                Indent();
 
1404
                                tryStatement.FinallyBlock.AcceptVisitor(this, data);
 
1405
                                Unindent();
 
1406
                        }
 
1407
                        WriteKeyword("End");
 
1408
                        WriteKeyword("Try");
 
1409
                        return EndNode(tryStatement);
 
1410
                }
 
1411
                
 
1412
                public object VisitCatchBlock(CatchBlock catchBlock, object data)
 
1413
                {
 
1414
                        StartNode(catchBlock);
 
1415
                        WriteKeyword("Catch");
 
1416
                        catchBlock.ExceptionVariable.AcceptVisitor(this, data);
 
1417
                        if (!catchBlock.ExceptionType.IsNull) {
 
1418
                                WriteKeyword("As");
 
1419
                                catchBlock.ExceptionType.AcceptVisitor(this, data);
 
1420
                        }
 
1421
                        NewLine();
 
1422
                        Indent();
 
1423
                        foreach (var stmt in catchBlock) {
 
1424
                                stmt.AcceptVisitor(this, data);
 
1425
                                NewLine();
 
1426
                        }
 
1427
                        Unindent();
 
1428
                        return EndNode(catchBlock);
 
1429
                }
 
1430
                
 
1431
                public object VisitExpressionStatement(ExpressionStatement expressionStatement, object data)
 
1432
                {
 
1433
                        StartNode(expressionStatement);
 
1434
                        expressionStatement.Expression.AcceptVisitor(this, data);
 
1435
                        return EndNode(expressionStatement);
 
1436
                }
 
1437
                
 
1438
                public object VisitThrowStatement(ThrowStatement throwStatement, object data)
 
1439
                {
 
1440
                        StartNode(throwStatement);
 
1441
                        
 
1442
                        WriteKeyword("Throw");
 
1443
                        throwStatement.Expression.AcceptVisitor(this, data);
 
1444
                        
 
1445
                        return EndNode(throwStatement);
 
1446
                }
 
1447
                
 
1448
                public object VisitIfElseStatement(IfElseStatement ifElseStatement, object data)
 
1449
                {
 
1450
                        StartNode(ifElseStatement);
 
1451
                        WriteKeyword("If");
 
1452
                        ifElseStatement.Condition.AcceptVisitor(this, data);
 
1453
                        Space();
 
1454
                        WriteKeyword("Then");
 
1455
                        NewLine();
 
1456
                        Indent();
 
1457
                        ifElseStatement.Body.AcceptVisitor(this, data);
 
1458
                        Unindent();
 
1459
                        if (!ifElseStatement.ElseBlock.IsNull) {
 
1460
                                WriteKeyword("Else");
 
1461
                                NewLine();
 
1462
                                Indent();
 
1463
                                ifElseStatement.ElseBlock.AcceptVisitor(this, data);
 
1464
                                Unindent();
 
1465
                        }
 
1466
                        WriteKeyword("End");
 
1467
                        WriteKeyword("If");
 
1468
                        return EndNode(ifElseStatement);
 
1469
                }
 
1470
                
 
1471
                public object VisitReturnStatement(ReturnStatement returnStatement, object data)
 
1472
                {
 
1473
                        StartNode(returnStatement);
 
1474
                        WriteKeyword("Return");
 
1475
                        returnStatement.Expression.AcceptVisitor(this, data);
 
1476
                        return EndNode(returnStatement);
 
1477
                }
 
1478
                
 
1479
                public object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
 
1480
                {
 
1481
                        StartNode(binaryOperatorExpression);
 
1482
                        binaryOperatorExpression.Left.AcceptVisitor(this, data);
 
1483
                        Space();
 
1484
                        switch (binaryOperatorExpression.Operator) {
 
1485
                                case BinaryOperatorType.BitwiseAnd:
 
1486
                                        WriteKeyword("And");
 
1487
                                        break;
 
1488
                                case BinaryOperatorType.BitwiseOr:
 
1489
                                        WriteKeyword("Or");
 
1490
                                        break;
 
1491
                                case BinaryOperatorType.LogicalAnd:
 
1492
                                        WriteKeyword("AndAlso");
 
1493
                                        break;
 
1494
                                case BinaryOperatorType.LogicalOr:
 
1495
                                        WriteKeyword("OrElse");
 
1496
                                        break;
 
1497
                                case BinaryOperatorType.ExclusiveOr:
 
1498
                                        WriteKeyword("Xor");
 
1499
                                        break;
 
1500
                                case BinaryOperatorType.GreaterThan:
 
1501
                                        WriteToken(">", BinaryOperatorExpression.OperatorRole);
 
1502
                                        break;
 
1503
                                case BinaryOperatorType.GreaterThanOrEqual:
 
1504
                                        WriteToken(">=", BinaryOperatorExpression.OperatorRole);
 
1505
                                        break;
 
1506
                                case BinaryOperatorType.Equality:
 
1507
                                        WriteToken("=", BinaryOperatorExpression.OperatorRole);
 
1508
                                        break;
 
1509
                                case BinaryOperatorType.InEquality:
 
1510
                                        WriteToken("<>", BinaryOperatorExpression.OperatorRole);
 
1511
                                        break;
 
1512
                                case BinaryOperatorType.LessThan:
 
1513
                                        WriteToken("<", BinaryOperatorExpression.OperatorRole);
 
1514
                                        break;
 
1515
                                case BinaryOperatorType.LessThanOrEqual:
 
1516
                                        WriteToken("<=", BinaryOperatorExpression.OperatorRole);
 
1517
                                        break;
 
1518
                                case BinaryOperatorType.Add:
 
1519
                                        WriteToken("+", BinaryOperatorExpression.OperatorRole);
 
1520
                                        break;
 
1521
                                case BinaryOperatorType.Subtract:
 
1522
                                        WriteToken("-", BinaryOperatorExpression.OperatorRole);
 
1523
                                        break;
 
1524
                                case BinaryOperatorType.Multiply:
 
1525
                                        WriteToken("*", BinaryOperatorExpression.OperatorRole);
 
1526
                                        break;
 
1527
                                case BinaryOperatorType.Divide:
 
1528
                                        WriteToken("/", BinaryOperatorExpression.OperatorRole);
 
1529
                                        break;
 
1530
                                case BinaryOperatorType.Modulus:
 
1531
                                        WriteKeyword("Mod");
 
1532
                                        break;
 
1533
                                case BinaryOperatorType.DivideInteger:
 
1534
                                        WriteToken("\\", BinaryOperatorExpression.OperatorRole);
 
1535
                                        break;
 
1536
                                case BinaryOperatorType.Power:
 
1537
                                        WriteToken("*", BinaryOperatorExpression.OperatorRole);
 
1538
                                        break;
 
1539
                                case BinaryOperatorType.Concat:
 
1540
                                        WriteToken("&", BinaryOperatorExpression.OperatorRole);
 
1541
                                        break;
 
1542
                                case BinaryOperatorType.ShiftLeft:
 
1543
                                        WriteToken("<<", BinaryOperatorExpression.OperatorRole);
 
1544
                                        break;
 
1545
                                case BinaryOperatorType.ShiftRight:
 
1546
                                        WriteToken(">>", BinaryOperatorExpression.OperatorRole);
 
1547
                                        break;
 
1548
                                case BinaryOperatorType.ReferenceEquality:
 
1549
                                        WriteKeyword("Is");
 
1550
                                        break;
 
1551
                                case BinaryOperatorType.ReferenceInequality:
 
1552
                                        WriteKeyword("IsNot");
 
1553
                                        break;
 
1554
                                case BinaryOperatorType.Like:
 
1555
                                        WriteKeyword("Like");
 
1556
                                        break;
 
1557
                                case BinaryOperatorType.DictionaryAccess:
 
1558
                                        WriteToken("!", BinaryOperatorExpression.OperatorRole);
 
1559
                                        break;
 
1560
                                default:
 
1561
                                        throw new Exception("Invalid value for BinaryOperatorType: " + binaryOperatorExpression.Operator);
 
1562
                        }
 
1563
                        Space();
 
1564
                        binaryOperatorExpression.Right.AcceptVisitor(this, data);
 
1565
                        return EndNode(binaryOperatorExpression);
 
1566
                }
 
1567
                
 
1568
                public object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
 
1569
                {
 
1570
                        StartNode(identifierExpression);
 
1571
                        identifierExpression.Identifier.AcceptVisitor(this, data);
 
1572
                        WriteTypeArguments(identifierExpression.TypeArguments);
 
1573
                        return EndNode(identifierExpression);
 
1574
                }
 
1575
                
 
1576
                public object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data)
 
1577
                {
 
1578
                        StartNode(assignmentExpression);
 
1579
                        assignmentExpression.Left.AcceptVisitor(this, data);
 
1580
                        Space();
 
1581
                        switch (assignmentExpression.Operator) {
 
1582
                                case AssignmentOperatorType.Assign:
 
1583
                                        WriteToken("=", AssignmentExpression.OperatorRole);
 
1584
                                        break;
 
1585
                                case AssignmentOperatorType.Add:
 
1586
                                        WriteToken("+=", AssignmentExpression.OperatorRole);
 
1587
                                        break;
 
1588
                                case AssignmentOperatorType.Subtract:
 
1589
                                        WriteToken("-=", AssignmentExpression.OperatorRole);
 
1590
                                        break;
 
1591
                                case AssignmentOperatorType.Multiply:
 
1592
                                        WriteToken("*=", AssignmentExpression.OperatorRole);
 
1593
                                        break;
 
1594
                                case AssignmentOperatorType.Divide:
 
1595
                                        WriteToken("/=", AssignmentExpression.OperatorRole);
 
1596
                                        break;
 
1597
                                case AssignmentOperatorType.Power:
 
1598
                                        WriteToken("^=", AssignmentExpression.OperatorRole);
 
1599
                                        break;
 
1600
                                case AssignmentOperatorType.DivideInteger:
 
1601
                                        WriteToken("\\=", AssignmentExpression.OperatorRole);
 
1602
                                        break;
 
1603
                                case AssignmentOperatorType.ConcatString:
 
1604
                                        WriteToken("&=", AssignmentExpression.OperatorRole);
 
1605
                                        break;
 
1606
                                case AssignmentOperatorType.ShiftLeft:
 
1607
                                        WriteToken("<<=", AssignmentExpression.OperatorRole);
 
1608
                                        break;
 
1609
                                case AssignmentOperatorType.ShiftRight:
 
1610
                                        WriteToken(">>=", AssignmentExpression.OperatorRole);
 
1611
                                        break;
 
1612
                                default:
 
1613
                                        throw new Exception("Invalid value for AssignmentOperatorType: " + assignmentExpression.Operator);
 
1614
                        }
 
1615
                        Space();
 
1616
                        assignmentExpression.Right.AcceptVisitor(this, data);
 
1617
                        return EndNode(assignmentExpression);
 
1618
                }
 
1619
                
 
1620
                public object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
 
1621
                {
 
1622
                        StartNode(invocationExpression);
 
1623
                        invocationExpression.Target.AcceptVisitor(this, data);
 
1624
                        WriteCommaSeparatedListInParenthesis(invocationExpression.Arguments, false);
 
1625
                        return EndNode(invocationExpression);
 
1626
                }
 
1627
                
 
1628
                public object VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, object data)
 
1629
                {
 
1630
                        StartNode(arrayInitializerExpression);
 
1631
                        WriteToken("{", ArrayInitializerExpression.Roles.LBrace);
 
1632
                        Space();
 
1633
                        WriteCommaSeparatedList(arrayInitializerExpression.Elements);
 
1634
                        Space();
 
1635
                        WriteToken("}", ArrayInitializerExpression.Roles.RBrace);
 
1636
                        return EndNode(arrayInitializerExpression);
 
1637
                }
 
1638
                
 
1639
                public object VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data)
 
1640
                {
 
1641
                        StartNode(arrayCreateExpression);
 
1642
                        WriteKeyword("New");
 
1643
                        Space();
 
1644
                        arrayCreateExpression.Type.AcceptVisitor(this, data);
 
1645
                        WriteCommaSeparatedListInParenthesis(arrayCreateExpression.Arguments, false);
 
1646
                        foreach (var specifier in arrayCreateExpression.AdditionalArraySpecifiers) {
 
1647
                                specifier.AcceptVisitor(this, data);
 
1648
                        }
 
1649
                        if (!arrayCreateExpression.Initializer.IsNull) {
 
1650
                                Space();
 
1651
                                WriteToken("=", ArrayCreateExpression.Roles.Assign);
 
1652
                                Space();
 
1653
                                arrayCreateExpression.Initializer.AcceptVisitor(this, data);
 
1654
                        }
 
1655
                        return EndNode(arrayCreateExpression);
 
1656
                }
 
1657
                
 
1658
                public object VisitObjectCreationExpression(ObjectCreationExpression objectCreationExpression, object data)
 
1659
                {
 
1660
                        StartNode(objectCreationExpression);
 
1661
                        
 
1662
                        WriteKeyword("New");
 
1663
                        objectCreationExpression.Type.AcceptVisitor(this, data);
 
1664
                        WriteCommaSeparatedListInParenthesis(objectCreationExpression.Arguments, false);
 
1665
                        if (!objectCreationExpression.Initializer.IsNull) {
 
1666
                                Space();
 
1667
                                if (objectCreationExpression.Initializer.Elements.Any(x => x is FieldInitializerExpression))
 
1668
                                        WriteKeyword("With");
 
1669
                                else
 
1670
                                        WriteKeyword("From");
 
1671
                                Space();
 
1672
                                objectCreationExpression.Initializer.AcceptVisitor(this, data);
 
1673
                        }
 
1674
                        
 
1675
                        return EndNode(objectCreationExpression);
 
1676
                }
 
1677
                
 
1678
                public object VisitCastExpression(CastExpression castExpression, object data)
 
1679
                {
 
1680
                        StartNode(castExpression);
 
1681
                        
 
1682
                        switch (castExpression.CastType) {
 
1683
                                case CastType.DirectCast:
 
1684
                                        WriteKeyword("DirectCast");
 
1685
                                        break;
 
1686
                                case CastType.TryCast:
 
1687
                                        WriteKeyword("TryCast");
 
1688
                                        break;
 
1689
                                case CastType.CType:
 
1690
                                        WriteKeyword("CType");
 
1691
                                        break;
 
1692
                                case CastType.CBool:
 
1693
                                        WriteKeyword("CBool");
 
1694
                                        break;
 
1695
                                case CastType.CByte:
 
1696
                                        WriteKeyword("CByte");
 
1697
                                        break;
 
1698
                                case CastType.CChar:
 
1699
                                        WriteKeyword("CChar");
 
1700
                                        break;
 
1701
                                case CastType.CDate:
 
1702
                                        WriteKeyword("CDate");
 
1703
                                        break;
 
1704
                                case CastType.CDec:
 
1705
                                        WriteKeyword("CType");
 
1706
                                        break;
 
1707
                                case CastType.CDbl:
 
1708
                                        WriteKeyword("CDec");
 
1709
                                        break;
 
1710
                                case CastType.CInt:
 
1711
                                        WriteKeyword("CInt");
 
1712
                                        break;
 
1713
                                case CastType.CLng:
 
1714
                                        WriteKeyword("CLng");
 
1715
                                        break;
 
1716
                                case CastType.CObj:
 
1717
                                        WriteKeyword("CObj");
 
1718
                                        break;
 
1719
                                case CastType.CSByte:
 
1720
                                        WriteKeyword("CSByte");
 
1721
                                        break;
 
1722
                                case CastType.CShort:
 
1723
                                        WriteKeyword("CShort");
 
1724
                                        break;
 
1725
                                case CastType.CSng:
 
1726
                                        WriteKeyword("CSng");
 
1727
                                        break;
 
1728
                                case CastType.CStr:
 
1729
                                        WriteKeyword("CStr");
 
1730
                                        break;
 
1731
                                case CastType.CUInt:
 
1732
                                        WriteKeyword("CUInt");
 
1733
                                        break;
 
1734
                                case CastType.CULng:
 
1735
                                        WriteKeyword("CULng");
 
1736
                                        break;
 
1737
                                case CastType.CUShort:
 
1738
                                        WriteKeyword("CUShort");
 
1739
                                        break;
 
1740
                                default:
 
1741
                                        throw new Exception("Invalid value for CastType");
 
1742
                        }
 
1743
                        
 
1744
                        WriteToken("(", CastExpression.Roles.LPar);
 
1745
                        castExpression.Expression.AcceptVisitor(this, data);
 
1746
                        
 
1747
                        if (castExpression.CastType == CastType.CType ||
 
1748
                            castExpression.CastType == CastType.DirectCast ||
 
1749
                            castExpression.CastType == CastType.TryCast) {
 
1750
                                WriteToken(",", CastExpression.Roles.Comma);
 
1751
                                Space();
 
1752
                                castExpression.Type.AcceptVisitor(this, data);
 
1753
                        }
 
1754
                        
 
1755
                        WriteToken(")", CastExpression.Roles.RPar);
 
1756
                        
 
1757
                        return EndNode(castExpression);
 
1758
                }
 
1759
                
 
1760
                public object VisitComment(Comment comment, object data)
 
1761
                {
 
1762
                        formatter.WriteComment(comment.IsDocumentationComment, comment.Content);
 
1763
                        return null;
 
1764
                }
 
1765
                
 
1766
                public object VisitEventDeclaration(EventDeclaration eventDeclaration, object data)
 
1767
                {
 
1768
                        StartNode(eventDeclaration);
 
1769
                        
 
1770
                        WriteAttributes(eventDeclaration.Attributes);
 
1771
                        WriteModifiers(eventDeclaration.ModifierTokens);
 
1772
                        if (eventDeclaration.IsCustom)
 
1773
                                WriteKeyword("Custom");
 
1774
                        WriteKeyword("Event");
 
1775
                        WriteIdentifier(eventDeclaration.Name.Name);
 
1776
                        if (!eventDeclaration.IsCustom && eventDeclaration.ReturnType.IsNull)
 
1777
                                WriteCommaSeparatedListInParenthesis(eventDeclaration.Parameters, false);
 
1778
                        if (!eventDeclaration.ReturnType.IsNull) {
 
1779
                                Space();
 
1780
                                WriteKeyword("As");
 
1781
                                eventDeclaration.ReturnType.AcceptVisitor(this, data);
 
1782
                        }
 
1783
                        WriteImplementsClause(eventDeclaration.ImplementsClause);
 
1784
                        
 
1785
                        if (eventDeclaration.IsCustom) {
 
1786
                                MarkFoldStart();
 
1787
                                NewLine();
 
1788
                                Indent();
 
1789
                                
 
1790
                                eventDeclaration.AddHandlerBlock.AcceptVisitor(this, data);
 
1791
                                eventDeclaration.RemoveHandlerBlock.AcceptVisitor(this, data);
 
1792
                                eventDeclaration.RaiseEventBlock.AcceptVisitor(this, data);
 
1793
                                
 
1794
                                Unindent();
 
1795
                                WriteKeyword("End");
 
1796
                                WriteKeyword("Event");
 
1797
                                MarkFoldEnd();
 
1798
                        }
 
1799
                        NewLine();
 
1800
                        
 
1801
                        return EndNode(eventDeclaration);
 
1802
                }
 
1803
                
 
1804
                public object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data)
 
1805
                {
 
1806
                        StartNode(unaryOperatorExpression);
 
1807
                        
 
1808
                        switch (unaryOperatorExpression.Operator) {
 
1809
                                case UnaryOperatorType.Not:
 
1810
                                        WriteKeyword("Not");
 
1811
                                        break;
 
1812
                                case UnaryOperatorType.Minus:
 
1813
                                        WriteToken("-", UnaryOperatorExpression.OperatorRole);
 
1814
                                        break;
 
1815
                                case UnaryOperatorType.Plus:
 
1816
                                        WriteToken("+", UnaryOperatorExpression.OperatorRole);
 
1817
                                        break;
 
1818
                                case UnaryOperatorType.AddressOf:
 
1819
                                        WriteKeyword("AddressOf");
 
1820
                                        break;
 
1821
                                case UnaryOperatorType.Await:
 
1822
                                        WriteKeyword("Await");
 
1823
                                        break;
 
1824
                                default:
 
1825
                                        throw new Exception("Invalid value for UnaryOperatorType");
 
1826
                        }
 
1827
                        
 
1828
                        unaryOperatorExpression.Expression.AcceptVisitor(this, data);
 
1829
                        
 
1830
                        return EndNode(unaryOperatorExpression);
 
1831
                }
 
1832
                
 
1833
                public object VisitFieldInitializerExpression(FieldInitializerExpression fieldInitializerExpression, object data)
 
1834
                {
 
1835
                        StartNode(fieldInitializerExpression);
 
1836
                        
 
1837
                        if (fieldInitializerExpression.IsKey && fieldInitializerExpression.Parent is AnonymousObjectCreationExpression) {
 
1838
                                WriteKeyword("Key");
 
1839
                                Space();
 
1840
                        }
 
1841
                        
 
1842
                        WriteToken(".", FieldInitializerExpression.Roles.Dot);
 
1843
                        fieldInitializerExpression.Identifier.AcceptVisitor(this, data);
 
1844
                        
 
1845
                        Space();
 
1846
                        WriteToken("=", FieldInitializerExpression.Roles.Assign);
 
1847
                        Space();
 
1848
                        fieldInitializerExpression.Expression.AcceptVisitor(this, data);
 
1849
                        
 
1850
                        return EndNode(fieldInitializerExpression);
 
1851
                }
 
1852
                
 
1853
                public object VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression, object data)
 
1854
                {
 
1855
                        throw new NotImplementedException();
 
1856
                }
 
1857
                
 
1858
                public object VisitConditionalExpression(ConditionalExpression conditionalExpression, object data)
 
1859
                {
 
1860
                        StartNode(conditionalExpression);
 
1861
                        
 
1862
                        WriteKeyword("If");
 
1863
                        WriteToken("(", ConditionalExpression.Roles.LPar);
 
1864
                        
 
1865
                        conditionalExpression.ConditionExpression.AcceptVisitor(this, data);
 
1866
                        WriteToken(",", ConditionalExpression.Roles.Comma);
 
1867
                        Space();
 
1868
                        
 
1869
                        if (!conditionalExpression.TrueExpression.IsNull) {
 
1870
                                conditionalExpression.TrueExpression.AcceptVisitor(this, data);
 
1871
                                WriteToken(",", ConditionalExpression.Roles.Comma);
 
1872
                                Space();
 
1873
                        }
 
1874
                        
 
1875
                        conditionalExpression.FalseExpression.AcceptVisitor(this, data);
 
1876
                        
 
1877
                        WriteToken(")", ConditionalExpression.Roles.RPar);
 
1878
                        
 
1879
                        return EndNode(conditionalExpression);
 
1880
                }
 
1881
                
 
1882
                public object VisitWhileStatement(WhileStatement whileStatement, object data)
 
1883
                {
 
1884
                        StartNode(whileStatement);
 
1885
                        
 
1886
                        WriteKeyword("While");
 
1887
                        Space();
 
1888
                        whileStatement.Condition.AcceptVisitor(this, data);
 
1889
                        NewLine();
 
1890
                        Indent();
 
1891
                        whileStatement.Body.AcceptVisitor(this, data);
 
1892
                        Unindent();
 
1893
                        WriteKeyword("End");
 
1894
                        WriteKeyword("While");
 
1895
                        
 
1896
                        return EndNode(whileStatement);
 
1897
                }
 
1898
                
 
1899
                public object VisitExitStatement(ExitStatement exitStatement, object data)
 
1900
                {
 
1901
                        StartNode(exitStatement);
 
1902
                        
 
1903
                        WriteKeyword("Exit");
 
1904
                        
 
1905
                        switch (exitStatement.ExitKind) {
 
1906
                                case ExitKind.Sub:
 
1907
                                        WriteKeyword("Sub");
 
1908
                                        break;
 
1909
                                case ExitKind.Function:
 
1910
                                        WriteKeyword("Function");
 
1911
                                        break;
 
1912
                                case ExitKind.Property:
 
1913
                                        WriteKeyword("Property");
 
1914
                                        break;
 
1915
                                case ExitKind.Do:
 
1916
                                        WriteKeyword("Do");
 
1917
                                        break;
 
1918
                                case ExitKind.For:
 
1919
                                        WriteKeyword("For");
 
1920
                                        break;
 
1921
                                case ExitKind.While:
 
1922
                                        WriteKeyword("While");
 
1923
                                        break;
 
1924
                                case ExitKind.Select:
 
1925
                                        WriteKeyword("Select");
 
1926
                                        break;
 
1927
                                case ExitKind.Try:
 
1928
                                        WriteKeyword("Try");
 
1929
                                        break;
 
1930
                                default:
 
1931
                                        throw new Exception("Invalid value for ExitKind");
 
1932
                        }
 
1933
                        
 
1934
                        return EndNode(exitStatement);
 
1935
                }
 
1936
                
 
1937
                public object VisitForStatement(ForStatement forStatement, object data)
 
1938
                {
 
1939
                        StartNode(forStatement);
 
1940
                        
 
1941
                        WriteKeyword("For");
 
1942
                        forStatement.Variable.AcceptVisitor(this, data);
 
1943
                        WriteKeyword("To");
 
1944
                        forStatement.ToExpression.AcceptVisitor(this, data);
 
1945
                        if (!forStatement.StepExpression.IsNull) {
 
1946
                                WriteKeyword("Step");
 
1947
                                Space();
 
1948
                                forStatement.StepExpression.AcceptVisitor(this, data);
 
1949
                        }
 
1950
                        NewLine();
 
1951
                        Indent();
 
1952
                        forStatement.Body.AcceptVisitor(this, data);
 
1953
                        Unindent();
 
1954
                        WriteKeyword("Next");
 
1955
                        
 
1956
                        return EndNode(forStatement);
 
1957
                }
 
1958
                
 
1959
                public object VisitForEachStatement(ForEachStatement forEachStatement, object data)
 
1960
                {
 
1961
                        StartNode(forEachStatement);
 
1962
                        
 
1963
                        WriteKeyword("For");
 
1964
                        WriteKeyword("Each");
 
1965
                        forEachStatement.Variable.AcceptVisitor(this, data);
 
1966
                        Space();
 
1967
                        WriteKeyword("In");
 
1968
                        forEachStatement.InExpression.AcceptVisitor(this, data);
 
1969
                        NewLine();
 
1970
                        Indent();
 
1971
                        forEachStatement.Body.AcceptVisitor(this, data);
 
1972
                        Unindent();
 
1973
                        WriteKeyword("Next");
 
1974
                        
 
1975
                        return EndNode(forEachStatement);
 
1976
                }
 
1977
                
 
1978
                public object VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration, object data)
 
1979
                {
 
1980
                        StartNode(operatorDeclaration);
 
1981
                        
 
1982
                        WriteAttributes(operatorDeclaration.Attributes);
 
1983
                        WriteModifiers(operatorDeclaration.ModifierTokens);
 
1984
                        WriteKeyword("Operator");
 
1985
                        switch (operatorDeclaration.Operator) {
 
1986
                                case OverloadableOperatorType.Add:
 
1987
                                case OverloadableOperatorType.UnaryPlus:
 
1988
                                        WriteToken("+", OperatorDeclaration.Roles.Keyword);
 
1989
                                        break;
 
1990
                                case OverloadableOperatorType.Subtract:
 
1991
                                case OverloadableOperatorType.UnaryMinus:
 
1992
                                        WriteToken("-", OperatorDeclaration.Roles.Keyword);
 
1993
                                        break;
 
1994
                                case OverloadableOperatorType.Multiply:
 
1995
                                        WriteToken("*", OperatorDeclaration.Roles.Keyword);
 
1996
                                        break;
 
1997
                                case OverloadableOperatorType.Divide:
 
1998
                                        WriteToken("/", OperatorDeclaration.Roles.Keyword);
 
1999
                                        break;
 
2000
                                case OverloadableOperatorType.Modulus:
 
2001
                                        WriteKeyword("Mod");
 
2002
                                        break;
 
2003
                                case OverloadableOperatorType.Concat:
 
2004
                                        WriteToken("&", OperatorDeclaration.Roles.Keyword);
 
2005
                                        break;
 
2006
                                case OverloadableOperatorType.Not:
 
2007
                                        WriteKeyword("Not");
 
2008
                                        break;
 
2009
                                case OverloadableOperatorType.BitwiseAnd:
 
2010
                                        WriteKeyword("And");
 
2011
                                        break;
 
2012
                                case OverloadableOperatorType.BitwiseOr:
 
2013
                                        WriteKeyword("Or");
 
2014
                                        break;
 
2015
                                case OverloadableOperatorType.ExclusiveOr:
 
2016
                                        WriteKeyword("Xor");
 
2017
                                        break;
 
2018
                                case OverloadableOperatorType.ShiftLeft:
 
2019
                                        WriteToken("<<", OperatorDeclaration.Roles.Keyword);
 
2020
                                        break;
 
2021
                                case OverloadableOperatorType.ShiftRight:
 
2022
                                        WriteToken(">>", OperatorDeclaration.Roles.Keyword);
 
2023
                                        break;
 
2024
                                case OverloadableOperatorType.GreaterThan:
 
2025
                                        WriteToken(">", OperatorDeclaration.Roles.Keyword);
 
2026
                                        break;
 
2027
                                case OverloadableOperatorType.GreaterThanOrEqual:
 
2028
                                        WriteToken(">=", OperatorDeclaration.Roles.Keyword);
 
2029
                                        break;
 
2030
                                case OverloadableOperatorType.Equality:
 
2031
                                        WriteToken("=", OperatorDeclaration.Roles.Keyword);
 
2032
                                        break;
 
2033
                                case OverloadableOperatorType.InEquality:
 
2034
                                        WriteToken("<>", OperatorDeclaration.Roles.Keyword);
 
2035
                                        break;
 
2036
                                case OverloadableOperatorType.LessThan:
 
2037
                                        WriteToken("<", OperatorDeclaration.Roles.Keyword);
 
2038
                                        break;
 
2039
                                case OverloadableOperatorType.LessThanOrEqual:
 
2040
                                        WriteToken("<=", OperatorDeclaration.Roles.Keyword);
 
2041
                                        break;
 
2042
                                case OverloadableOperatorType.IsTrue:
 
2043
                                        WriteKeyword("IsTrue");
 
2044
                                        break;
 
2045
                                case OverloadableOperatorType.IsFalse:
 
2046
                                        WriteKeyword("IsFalse");
 
2047
                                        break;
 
2048
                                case OverloadableOperatorType.Like:
 
2049
                                        WriteKeyword("Like");
 
2050
                                        break;
 
2051
                                case OverloadableOperatorType.Power:
 
2052
                                        WriteToken("^", OperatorDeclaration.Roles.Keyword);
 
2053
                                        break;
 
2054
                                case OverloadableOperatorType.CType:
 
2055
                                        WriteKeyword("CType");
 
2056
                                        break;
 
2057
                                case OverloadableOperatorType.DivideInteger:
 
2058
                                        WriteToken("\\", OperatorDeclaration.Roles.Keyword);
 
2059
                                        break;
 
2060
                                default:
 
2061
                                        throw new Exception("Invalid value for OverloadableOperatorType");
 
2062
                        }
 
2063
                        WriteCommaSeparatedListInParenthesis(operatorDeclaration.Parameters, false);
 
2064
                        if (!operatorDeclaration.ReturnType.IsNull) {
 
2065
                                Space();
 
2066
                                WriteKeyword("As");
 
2067
                                WriteAttributes(operatorDeclaration.ReturnTypeAttributes);
 
2068
                                operatorDeclaration.ReturnType.AcceptVisitor(this, data);
 
2069
                        }
 
2070
                        if (!operatorDeclaration.Body.IsNull) {
 
2071
                                MarkFoldStart();
 
2072
                                NewLine();
 
2073
                                Indent();
 
2074
                                WriteBlock(operatorDeclaration.Body);
 
2075
                                Unindent();
 
2076
                                WriteKeyword("End");
 
2077
                                WriteKeyword("Operator");
 
2078
                                MarkFoldEnd();
 
2079
                        }
 
2080
                        NewLine();
 
2081
                        
 
2082
                        return EndNode(operatorDeclaration);
 
2083
                }
 
2084
                
 
2085
                public object VisitSelectStatement(SelectStatement selectStatement, object data)
 
2086
                {
 
2087
                        StartNode(selectStatement);
 
2088
                        
 
2089
                        WriteKeyword("Select");
 
2090
                        WriteKeyword("Case");
 
2091
                        selectStatement.Expression.AcceptVisitor(this, data);
 
2092
                        NewLine();
 
2093
                        Indent();
 
2094
                        
 
2095
                        foreach (CaseStatement stmt in selectStatement.Cases) {
 
2096
                                stmt.AcceptVisitor(this, data);
 
2097
                        }
 
2098
                        
 
2099
                        Unindent();
 
2100
                        WriteKeyword("End");
 
2101
                        WriteKeyword("Select");
 
2102
                        
 
2103
                        return EndNode(selectStatement);
 
2104
                }
 
2105
                
 
2106
                public object VisitCaseStatement(CaseStatement caseStatement, object data)
 
2107
                {
 
2108
                        StartNode(caseStatement);
 
2109
                        
 
2110
                        WriteKeyword("Case");
 
2111
                        if (caseStatement.Clauses.Count == 1 && caseStatement.Clauses.First().Expression.IsNull)
 
2112
                                WriteKeyword("Else");
 
2113
                        else {
 
2114
                                Space();
 
2115
                                WriteCommaSeparatedList(caseStatement.Clauses);
 
2116
                        }
 
2117
                        NewLine();
 
2118
                        Indent();
 
2119
                        caseStatement.Body.AcceptVisitor(this, data);
 
2120
                        Unindent();
 
2121
                        
 
2122
                        return EndNode(caseStatement);
 
2123
                }
 
2124
                
 
2125
                public object VisitSimpleCaseClause(SimpleCaseClause simpleCaseClause, object data)
 
2126
                {
 
2127
                        StartNode(simpleCaseClause);
 
2128
                        simpleCaseClause.Expression.AcceptVisitor(this, data);
 
2129
                        return EndNode(simpleCaseClause);
 
2130
                }
 
2131
                
 
2132
                public object VisitRangeCaseClause(RangeCaseClause rangeCaseClause, object data)
 
2133
                {
 
2134
                        StartNode(rangeCaseClause);
 
2135
                        rangeCaseClause.Expression.AcceptVisitor(this, data);
 
2136
                        WriteKeyword("To");
 
2137
                        rangeCaseClause.ToExpression.AcceptVisitor(this, data);
 
2138
                        return EndNode(rangeCaseClause);
 
2139
                }
 
2140
                
 
2141
                public object VisitComparisonCaseClause(ComparisonCaseClause comparisonCaseClause, object data)
 
2142
                {
 
2143
                        StartNode(comparisonCaseClause);
 
2144
                        switch (comparisonCaseClause.Operator) {
 
2145
                                case ComparisonOperator.Equality:
 
2146
                                        WriteToken("=", ComparisonCaseClause.OperatorRole);
 
2147
                                        break;
 
2148
                                case ComparisonOperator.InEquality:
 
2149
                                        WriteToken("<>", ComparisonCaseClause.OperatorRole);
 
2150
                                        break;
 
2151
                                case ComparisonOperator.LessThan:
 
2152
                                        WriteToken("<", ComparisonCaseClause.OperatorRole);
 
2153
                                        break;
 
2154
                                case ComparisonOperator.GreaterThan:
 
2155
                                        WriteToken(">", ComparisonCaseClause.OperatorRole);
 
2156
                                        break;
 
2157
                                case ComparisonOperator.LessThanOrEqual:
 
2158
                                        WriteToken("<=", ComparisonCaseClause.OperatorRole);
 
2159
                                        break;
 
2160
                                case ComparisonOperator.GreaterThanOrEqual:
 
2161
                                        WriteToken(">=", ComparisonCaseClause.OperatorRole);
 
2162
                                        break;
 
2163
                                default:
 
2164
                                        throw new Exception("Invalid value for ComparisonOperator");
 
2165
                        }
 
2166
                        Space();
 
2167
                        comparisonCaseClause.Expression.AcceptVisitor(this, data);
 
2168
                        return EndNode(comparisonCaseClause);
 
2169
                }
 
2170
 
 
2171
                
 
2172
                public object VisitYieldStatement(YieldStatement yieldStatement, object data)
 
2173
                {
 
2174
                        StartNode(yieldStatement);
 
2175
                        WriteKeyword("Yield");
 
2176
                        yieldStatement.Expression.AcceptVisitor(this, data);
 
2177
                        return EndNode(yieldStatement);
 
2178
                }
 
2179
                
 
2180
                public object VisitVariableInitializer(VariableInitializer variableInitializer, object data)
 
2181
                {
 
2182
                        StartNode(variableInitializer);
 
2183
                        
 
2184
                        variableInitializer.Identifier.AcceptVisitor(this, data);
 
2185
                        if (!variableInitializer.Type.IsNull) {
 
2186
                                WriteKeyword("As");
 
2187
                                variableInitializer.Type.AcceptVisitor(this, data);
 
2188
                        }
 
2189
                        if (!variableInitializer.Expression.IsNull) {
 
2190
                                Space();
 
2191
                                WriteToken("=", VariableInitializer.Roles.Assign);
 
2192
                                Space();
 
2193
                                variableInitializer.Expression.AcceptVisitor(this, data);
 
2194
                        }
 
2195
                        
 
2196
                        return EndNode(variableInitializer);
 
2197
                }
 
2198
                
 
2199
                public object VisitVariableDeclaratorWithTypeAndInitializer(VariableDeclaratorWithTypeAndInitializer variableDeclaratorWithTypeAndInitializer, object data)
 
2200
                {
 
2201
                        StartNode(variableDeclaratorWithTypeAndInitializer);
 
2202
                        
 
2203
                        WriteCommaSeparatedList(variableDeclaratorWithTypeAndInitializer.Identifiers);
 
2204
                        WriteKeyword("As");
 
2205
                        variableDeclaratorWithTypeAndInitializer.Type.AcceptVisitor(this, data);
 
2206
                        if (!variableDeclaratorWithTypeAndInitializer.Initializer.IsNull) {
 
2207
                                Space();
 
2208
                                WriteToken("=", VariableDeclarator.Roles.Assign);
 
2209
                                Space();
 
2210
                                variableDeclaratorWithTypeAndInitializer.Initializer.AcceptVisitor(this, data);
 
2211
                        }
 
2212
                        
 
2213
                        return EndNode(variableDeclaratorWithTypeAndInitializer);
 
2214
                }
 
2215
                
 
2216
                public object VisitVariableDeclaratorWithObjectCreation(VariableDeclaratorWithObjectCreation variableDeclaratorWithObjectCreation, object data)
 
2217
                {
 
2218
                        StartNode(variableDeclaratorWithObjectCreation);
 
2219
                        
 
2220
                        WriteCommaSeparatedList(variableDeclaratorWithObjectCreation.Identifiers);
 
2221
                        WriteKeyword("As");
 
2222
                        variableDeclaratorWithObjectCreation.Initializer.AcceptVisitor(this, data);
 
2223
                        
 
2224
                        return EndNode(variableDeclaratorWithObjectCreation);
 
2225
                }
 
2226
                
 
2227
                public object VisitDoLoopStatement(DoLoopStatement doLoopStatement, object data)
 
2228
                {
 
2229
                        StartNode(doLoopStatement);
 
2230
                        
 
2231
                        WriteKeyword("Do");
 
2232
                        if (doLoopStatement.ConditionType == ConditionType.DoUntil) {
 
2233
                                WriteKeyword("Until");
 
2234
                                doLoopStatement.Expression.AcceptVisitor(this, data);
 
2235
                        }
 
2236
                        if (doLoopStatement.ConditionType == ConditionType.DoWhile) {
 
2237
                                WriteKeyword("While");
 
2238
                                doLoopStatement.Expression.AcceptVisitor(this, data);
 
2239
                        }
 
2240
                        NewLine();
 
2241
                        Indent();
 
2242
                        doLoopStatement.Body.AcceptVisitor(this, data);
 
2243
                        Unindent();
 
2244
                        WriteKeyword("Loop");
 
2245
                        if (doLoopStatement.ConditionType == ConditionType.LoopUntil) {
 
2246
                                WriteKeyword("Until");
 
2247
                                doLoopStatement.Expression.AcceptVisitor(this, data);
 
2248
                        }
 
2249
                        if (doLoopStatement.ConditionType == ConditionType.LoopWhile) {
 
2250
                                WriteKeyword("While");
 
2251
                                doLoopStatement.Expression.AcceptVisitor(this, data);
 
2252
                        }
 
2253
                        
 
2254
                        return EndNode(doLoopStatement);
 
2255
                }
 
2256
                
 
2257
                public object VisitUsingStatement(UsingStatement usingStatement, object data)
 
2258
                {
 
2259
                        StartNode(usingStatement);
 
2260
                        
 
2261
                        WriteKeyword("Using");
 
2262
                        WriteCommaSeparatedList(usingStatement.Resources);
 
2263
                        NewLine();
 
2264
                        Indent();
 
2265
                        usingStatement.Body.AcceptVisitor(this, data);
 
2266
                        Unindent();
 
2267
                        WriteKeyword("End");
 
2268
                        WriteKeyword("Using");
 
2269
                        
 
2270
                        return EndNode(usingStatement);
 
2271
                }
 
2272
                
 
2273
                public object VisitGoToStatement(GoToStatement goToStatement, object data)
 
2274
                {
 
2275
                        StartNode(goToStatement);
 
2276
                        
 
2277
                        WriteKeyword("GoTo");
 
2278
                        goToStatement.Label.AcceptVisitor(this, data);
 
2279
                        
 
2280
                        return EndNode(goToStatement);
 
2281
                }
 
2282
                
 
2283
                public object VisitSingleLineSubLambdaExpression(SingleLineSubLambdaExpression singleLineSubLambdaExpression, object data)
 
2284
                {
 
2285
                        StartNode(singleLineSubLambdaExpression);
 
2286
                        
 
2287
                        WriteModifiers(singleLineSubLambdaExpression.ModifierTokens);
 
2288
                        WriteKeyword("Sub");
 
2289
                        WriteCommaSeparatedListInParenthesis(singleLineSubLambdaExpression.Parameters, false);
 
2290
                        Space();
 
2291
                        singleLineSubLambdaExpression.EmbeddedStatement.AcceptVisitor(this, data);
 
2292
                        
 
2293
                        return EndNode(singleLineSubLambdaExpression);
 
2294
                }
 
2295
                
 
2296
                public object VisitSingleLineFunctionLambdaExpression(SingleLineFunctionLambdaExpression singleLineFunctionLambdaExpression, object data)
 
2297
                {
 
2298
                        StartNode(singleLineFunctionLambdaExpression);
 
2299
                        
 
2300
                        WriteModifiers(singleLineFunctionLambdaExpression.ModifierTokens);
 
2301
                        WriteKeyword("Function");
 
2302
                        WriteCommaSeparatedListInParenthesis(singleLineFunctionLambdaExpression.Parameters, false);
 
2303
                        Space();
 
2304
                        singleLineFunctionLambdaExpression.EmbeddedExpression.AcceptVisitor(this, data);
 
2305
                        
 
2306
                        return EndNode(singleLineFunctionLambdaExpression);
 
2307
                }
 
2308
                
 
2309
                public object VisitMultiLineLambdaExpression(MultiLineLambdaExpression multiLineLambdaExpression, object data)
 
2310
                {
 
2311
                        StartNode(multiLineLambdaExpression);
 
2312
                        
 
2313
                        WriteModifiers(multiLineLambdaExpression.ModifierTokens);
 
2314
                        if (multiLineLambdaExpression.IsSub)
 
2315
                                WriteKeyword("Sub");
 
2316
                        else
 
2317
                                WriteKeyword("Function");
 
2318
                        WriteCommaSeparatedListInParenthesis(multiLineLambdaExpression.Parameters, false);
 
2319
                        NewLine();
 
2320
                        Indent();
 
2321
                        multiLineLambdaExpression.Body.AcceptVisitor(this, data);
 
2322
                        Unindent();
 
2323
                        WriteKeyword("End");
 
2324
                        if (multiLineLambdaExpression.IsSub)
 
2325
                                WriteKeyword("Sub");
 
2326
                        else
 
2327
                                WriteKeyword("Function");
 
2328
                        
 
2329
                        return EndNode(multiLineLambdaExpression);
 
2330
                }
 
2331
                
 
2332
                public object VisitQueryExpression(QueryExpression queryExpression, object data)
 
2333
                {
 
2334
                        StartNode(queryExpression);
 
2335
                        
 
2336
                        foreach (var op in queryExpression.QueryOperators) {
 
2337
                                op.AcceptVisitor(this, data);
 
2338
                        }
 
2339
                        
 
2340
                        return EndNode(queryExpression);
 
2341
                }
 
2342
                
 
2343
                public object VisitContinueStatement(ContinueStatement continueStatement, object data)
 
2344
                {
 
2345
                        StartNode(continueStatement);
 
2346
                        
 
2347
                        WriteKeyword("Continue");
 
2348
                        
 
2349
                        switch (continueStatement.ContinueKind) {
 
2350
                                case ContinueKind.Do:
 
2351
                                        WriteKeyword("Do");
 
2352
                                        break;
 
2353
                                case ContinueKind.For:
 
2354
                                        WriteKeyword("For");
 
2355
                                        break;
 
2356
                                case ContinueKind.While:
 
2357
                                        WriteKeyword("While");
 
2358
                                        break;
 
2359
                                default:
 
2360
                                        throw new Exception("Invalid value for ContinueKind");
 
2361
                        }
 
2362
                        
 
2363
                        return EndNode(continueStatement);
 
2364
                }
 
2365
                
 
2366
                public object VisitExternalMethodDeclaration(ExternalMethodDeclaration externalMethodDeclaration, object data)
 
2367
                {
 
2368
                        StartNode(externalMethodDeclaration);
 
2369
                        
 
2370
                        WriteAttributes(externalMethodDeclaration.Attributes);
 
2371
                        WriteModifiers(externalMethodDeclaration.ModifierTokens);
 
2372
                        WriteKeyword("Declare");
 
2373
                        switch (externalMethodDeclaration.CharsetModifier) {
 
2374
                                case CharsetModifier.None:
 
2375
                                        break;
 
2376
                                case CharsetModifier.Auto:
 
2377
                                        WriteKeyword("Auto");
 
2378
                                        break;
 
2379
                                case CharsetModifier.Unicode:
 
2380
                                        WriteKeyword("Unicode");
 
2381
                                        break;
 
2382
                                case CharsetModifier.Ansi:
 
2383
                                        WriteKeyword("Ansi");
 
2384
                                        break;
 
2385
                                default:
 
2386
                                        throw new Exception("Invalid value for CharsetModifier");
 
2387
                        }
 
2388
                        if (externalMethodDeclaration.IsSub)
 
2389
                                WriteKeyword("Sub");
 
2390
                        else
 
2391
                                WriteKeyword("Function");
 
2392
                        externalMethodDeclaration.Name.AcceptVisitor(this, data);
 
2393
                        WriteKeyword("Lib");
 
2394
                        Space();
 
2395
                        WritePrimitiveValue(externalMethodDeclaration.Library);
 
2396
                        Space();
 
2397
                        if (externalMethodDeclaration.Alias != null) {
 
2398
                                WriteKeyword("Alias");
 
2399
                                Space();
 
2400
                                WritePrimitiveValue(externalMethodDeclaration.Alias);
 
2401
                                Space();
 
2402
                        }
 
2403
                        WriteCommaSeparatedListInParenthesis(externalMethodDeclaration.Parameters, false);
 
2404
                        if (!externalMethodDeclaration.IsSub && !externalMethodDeclaration.ReturnType.IsNull) {
 
2405
                                Space();
 
2406
                                WriteKeyword("As");
 
2407
                                WriteAttributes(externalMethodDeclaration.ReturnTypeAttributes);
 
2408
                                externalMethodDeclaration.ReturnType.AcceptVisitor(this, data);
 
2409
                        }
 
2410
                        NewLine();
 
2411
                        
 
2412
                        return EndNode(externalMethodDeclaration);
 
2413
                }
 
2414
                
 
2415
                public static string ToVBNetString(PrimitiveExpression primitiveExpression)
 
2416
                {
 
2417
                        var writer = new StringWriter();
 
2418
                        new OutputVisitor(writer, new VBFormattingOptions()).WritePrimitiveValue(primitiveExpression.Value);
 
2419
                        return writer.ToString();
 
2420
                }
 
2421
                
 
2422
                public object VisitEmptyExpression(EmptyExpression emptyExpression, object data)
 
2423
                {
 
2424
                        StartNode(emptyExpression);
 
2425
                        
 
2426
                        return EndNode(emptyExpression);
 
2427
                }
 
2428
                
 
2429
                public object VisitAnonymousObjectCreationExpression(AnonymousObjectCreationExpression anonymousObjectCreationExpression, object data)
 
2430
                {
 
2431
                        StartNode(anonymousObjectCreationExpression);
 
2432
                        
 
2433
                        WriteKeyword("New");
 
2434
                        WriteKeyword("With");
 
2435
                        
 
2436
                        WriteToken("{", AnonymousObjectCreationExpression.Roles.LBrace);
 
2437
                        Space();
 
2438
                        WriteCommaSeparatedList(anonymousObjectCreationExpression.Initializer);
 
2439
                        Space();
 
2440
                        WriteToken("}", AnonymousObjectCreationExpression.Roles.RBrace);
 
2441
                        
 
2442
                        return EndNode(anonymousObjectCreationExpression);
 
2443
                }
 
2444
                
 
2445
                public object VisitCollectionRangeVariableDeclaration(CollectionRangeVariableDeclaration collectionRangeVariableDeclaration, object data)
 
2446
                {
 
2447
                        StartNode(collectionRangeVariableDeclaration);
 
2448
                        
 
2449
                        collectionRangeVariableDeclaration.Identifier.AcceptVisitor(this, data);
 
2450
                        if (!collectionRangeVariableDeclaration.Type.IsNull) {
 
2451
                                WriteKeyword("As");
 
2452
                                collectionRangeVariableDeclaration.Type.AcceptVisitor(this, data);
 
2453
                        }
 
2454
                        WriteKeyword("In");
 
2455
                        collectionRangeVariableDeclaration.Expression.AcceptVisitor(this, data);
 
2456
                        
 
2457
                        return EndNode(collectionRangeVariableDeclaration);
 
2458
                }
 
2459
                
 
2460
                public object VisitFromQueryOperator(FromQueryOperator fromQueryOperator, object data)
 
2461
                {
 
2462
                        StartNode(fromQueryOperator);
 
2463
                        
 
2464
                        WriteKeyword("From");
 
2465
                        WriteCommaSeparatedList(fromQueryOperator.Variables);
 
2466
                        
 
2467
                        return EndNode(fromQueryOperator);
 
2468
                }
 
2469
                
 
2470
                public object VisitAggregateQueryOperator(AggregateQueryOperator aggregateQueryOperator, object data)
 
2471
                {
 
2472
                        StartNode(aggregateQueryOperator);
 
2473
                        
 
2474
                        WriteKeyword("Aggregate");
 
2475
                        aggregateQueryOperator.Variable.AcceptVisitor(this, data);
 
2476
                        
 
2477
                        foreach (var operators in aggregateQueryOperator.SubQueryOperators) {
 
2478
                                operators.AcceptVisitor(this, data);
 
2479
                        }
 
2480
                        
 
2481
                        WriteKeyword("Into");
 
2482
                        WriteCommaSeparatedList(aggregateQueryOperator.IntoExpressions);
 
2483
                        
 
2484
                        return EndNode(aggregateQueryOperator);
 
2485
                }
 
2486
                
 
2487
                public object VisitSelectQueryOperator(SelectQueryOperator selectQueryOperator, object data)
 
2488
                {
 
2489
                        StartNode(selectQueryOperator);
 
2490
                        
 
2491
                        WriteKeyword("Select");
 
2492
                        WriteCommaSeparatedList(selectQueryOperator.Variables);
 
2493
                        
 
2494
                        return EndNode(selectQueryOperator);
 
2495
                }
 
2496
                
 
2497
                public object VisitDistinctQueryOperator(DistinctQueryOperator distinctQueryOperator, object data)
 
2498
                {
 
2499
                        StartNode(distinctQueryOperator);
 
2500
                        
 
2501
                        WriteKeyword("Distinct");
 
2502
                        
 
2503
                        return EndNode(distinctQueryOperator);
 
2504
                }
 
2505
                
 
2506
                public object VisitWhereQueryOperator(WhereQueryOperator whereQueryOperator, object data)
 
2507
                {
 
2508
                        StartNode(whereQueryOperator);
 
2509
                        
 
2510
                        WriteKeyword("Where");
 
2511
                        whereQueryOperator.Condition.AcceptVisitor(this, data);
 
2512
                        
 
2513
                        return EndNode(whereQueryOperator);
 
2514
                }
 
2515
                
 
2516
                public object VisitPartitionQueryOperator(PartitionQueryOperator partitionQueryOperator, object data)
 
2517
                {
 
2518
                        StartNode(partitionQueryOperator);
 
2519
                        
 
2520
                        switch (partitionQueryOperator.Kind) {
 
2521
                                case PartitionKind.Take:
 
2522
                                        WriteKeyword("Take");
 
2523
                                        break;
 
2524
                                case PartitionKind.TakeWhile:
 
2525
                                        WriteKeyword("Take");
 
2526
                                        WriteKeyword("While");
 
2527
                                        break;
 
2528
                                case PartitionKind.Skip:
 
2529
                                        WriteKeyword("Skip");
 
2530
                                        break;
 
2531
                                case PartitionKind.SkipWhile:
 
2532
                                        WriteKeyword("Skip");
 
2533
                                        WriteKeyword("While");
 
2534
                                        break;
 
2535
                                default:
 
2536
                                        throw new Exception("Invalid value for PartitionKind");
 
2537
                        }
 
2538
                        
 
2539
                        partitionQueryOperator.Expression.AcceptVisitor(this, data);
 
2540
                        
 
2541
                        return EndNode(partitionQueryOperator);
 
2542
                }
 
2543
                
 
2544
                public object VisitOrderExpression(OrderExpression orderExpression, object data)
 
2545
                {
 
2546
                        StartNode(orderExpression);
 
2547
                        
 
2548
                        orderExpression.Expression.AcceptVisitor(this, data);
 
2549
                        
 
2550
                        switch (orderExpression.Direction) {
 
2551
                                case QueryOrderingDirection.None:
 
2552
                                        break;
 
2553
                                case QueryOrderingDirection.Ascending:
 
2554
                                        WriteKeyword("Ascending");
 
2555
                                        break;
 
2556
                                case QueryOrderingDirection.Descending:
 
2557
                                        WriteKeyword("Descending");
 
2558
                                        break;
 
2559
                                default:
 
2560
                                        throw new Exception("Invalid value for QueryExpressionOrderingDirection");
 
2561
                        }
 
2562
                        
 
2563
                        return EndNode(orderExpression);
 
2564
                }
 
2565
                
 
2566
                public object VisitOrderByQueryOperator(OrderByQueryOperator orderByQueryOperator, object data)
 
2567
                {
 
2568
                        StartNode(orderByQueryOperator);
 
2569
                        
 
2570
                        WriteKeyword("Order");
 
2571
                        WriteKeyword("By");
 
2572
                        WriteCommaSeparatedList(orderByQueryOperator.Expressions);
 
2573
                        
 
2574
                        return EndNode(orderByQueryOperator);
 
2575
                }
 
2576
                
 
2577
                public object VisitLetQueryOperator(LetQueryOperator letQueryOperator, object data)
 
2578
                {
 
2579
                        StartNode(letQueryOperator);
 
2580
                        
 
2581
                        WriteKeyword("Let");
 
2582
                        WriteCommaSeparatedList(letQueryOperator.Variables);
 
2583
                        
 
2584
                        return EndNode(letQueryOperator);
 
2585
                }
 
2586
                
 
2587
                public object VisitGroupByQueryOperator(GroupByQueryOperator groupByQueryOperator, object data)
 
2588
                {
 
2589
                        StartNode(groupByQueryOperator);
 
2590
                        
 
2591
                        WriteKeyword("Group");
 
2592
                        WriteCommaSeparatedList(groupByQueryOperator.GroupExpressions);
 
2593
                        WriteKeyword("By");
 
2594
                        WriteCommaSeparatedList(groupByQueryOperator.ByExpressions);
 
2595
                        WriteKeyword("Into");
 
2596
                        WriteCommaSeparatedList(groupByQueryOperator.IntoExpressions);
 
2597
                        
 
2598
                        return EndNode(groupByQueryOperator);
 
2599
                }
 
2600
                
 
2601
                public object VisitJoinQueryOperator(JoinQueryOperator joinQueryOperator, object data)
 
2602
                {
 
2603
                        StartNode(joinQueryOperator);
 
2604
                        
 
2605
                        WriteKeyword("Join");
 
2606
                        joinQueryOperator.JoinVariable.AcceptVisitor(this, data);
 
2607
                        if (!joinQueryOperator.SubJoinQuery.IsNull) {
 
2608
                                joinQueryOperator.SubJoinQuery.AcceptVisitor(this, data);
 
2609
                        }
 
2610
                        WriteKeyword("On");
 
2611
                        bool first = true;
 
2612
                        foreach (var cond in joinQueryOperator.JoinConditions) {
 
2613
                                if (first)
 
2614
                                        first = false;
 
2615
                                else
 
2616
                                        WriteKeyword("And");
 
2617
                                cond.AcceptVisitor(this, data);
 
2618
                        }
 
2619
                        
 
2620
                        return EndNode(joinQueryOperator);
 
2621
                }
 
2622
                
 
2623
                public object VisitJoinCondition(JoinCondition joinCondition, object data)
 
2624
                {
 
2625
                        StartNode(joinCondition);
 
2626
                        
 
2627
                        joinCondition.Left.AcceptVisitor(this, data);
 
2628
                        WriteKeyword("Equals");
 
2629
                        joinCondition.Right.AcceptVisitor(this, data);
 
2630
                        
 
2631
                        return EndNode(joinCondition);
 
2632
                }
 
2633
                
 
2634
                public object VisitGroupJoinQueryOperator(GroupJoinQueryOperator groupJoinQueryOperator, object data)
 
2635
                {
 
2636
                        StartNode(groupJoinQueryOperator);
 
2637
                        
 
2638
                        WriteKeyword("Group");
 
2639
                        WriteKeyword("Join");
 
2640
                        groupJoinQueryOperator.JoinVariable.AcceptVisitor(this, data);
 
2641
                        if (!groupJoinQueryOperator.SubJoinQuery.IsNull) {
 
2642
                                groupJoinQueryOperator.SubJoinQuery.AcceptVisitor(this, data);
 
2643
                        }
 
2644
                        WriteKeyword("On");
 
2645
                        bool first = true;
 
2646
                        foreach (var cond in groupJoinQueryOperator.JoinConditions) {
 
2647
                                if (first)
 
2648
                                        first = false;
 
2649
                                else
 
2650
                                        WriteKeyword("And");
 
2651
                                cond.AcceptVisitor(this, data);
 
2652
                        }
 
2653
                        WriteKeyword("Into");
 
2654
                        WriteCommaSeparatedList(groupJoinQueryOperator.IntoExpressions);
 
2655
                        
 
2656
                        return EndNode(groupJoinQueryOperator);
 
2657
                }
 
2658
        }
 
2659
}