1
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4
// software and associated documentation files (the "Software"), to deal in the Software
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7
// to whom the Software is furnished to do so, subject to the following conditions:
9
// The above copyright notice and this permission notice shall be included in all copies or
10
// substantial portions of the Software.
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17
// DEALINGS IN THE SOFTWARE.
19
using System.Collections.Generic;
20
using System.Diagnostics;
21
using System.Globalization;
25
using System.Threading.Tasks;
26
using ICSharpCode.NRefactory.PatternMatching;
27
using ICSharpCode.NRefactory.TypeSystem;
29
namespace ICSharpCode.NRefactory.CSharp
34
public class CSharpOutputVisitor : IAstVisitor
36
readonly IOutputFormatter formatter;
37
readonly CSharpFormattingOptions policy;
38
readonly Stack<AstNode> containerStack = new Stack<AstNode> ();
39
readonly Stack<AstNode> positionStack = new Stack<AstNode> ();
42
/// Used to insert the minimal amount of spaces so that the lexer recognizes the tokens that were written.
44
LastWritten lastWritten;
58
public CSharpOutputVisitor (TextWriter textWriter, CSharpFormattingOptions formattingPolicy)
60
if (textWriter == null) {
61
throw new ArgumentNullException ("textWriter");
63
if (formattingPolicy == null) {
64
throw new ArgumentNullException ("formattingPolicy");
66
this.formatter = new TextWriterOutputFormatter (textWriter);
67
this.policy = formattingPolicy;
70
public CSharpOutputVisitor (IOutputFormatter formatter, CSharpFormattingOptions formattingPolicy)
72
if (formatter == null) {
73
throw new ArgumentNullException ("formatter");
75
if (formattingPolicy == null) {
76
throw new ArgumentNullException ("formattingPolicy");
78
this.formatter = formatter;
79
this.policy = formattingPolicy;
82
#region StartNode/EndNode
83
void StartNode(AstNode node)
85
// Ensure that nodes are visited in the proper nested order.
86
// Jumps to different subtrees are allowed only for the child of a placeholder node.
87
Debug.Assert(containerStack.Count == 0 || node.Parent == containerStack.Peek() || containerStack.Peek().NodeType == NodeType.Pattern);
88
if (positionStack.Count > 0) {
89
WriteSpecialsUpToNode(node);
91
containerStack.Push(node);
92
positionStack.Push(node.FirstChild);
93
formatter.StartNode(node);
96
void EndNode(AstNode node)
98
Debug.Assert(node == containerStack.Peek());
99
AstNode pos = positionStack.Pop();
100
Debug.Assert(pos == null || pos.Parent == node);
101
WriteSpecials(pos, null);
102
containerStack.Pop();
103
formatter.EndNode(node);
107
#region WriteSpecials
109
/// Writes all specials from start to end (exclusive). Does not touch the positionStack.
111
void WriteSpecials(AstNode start, AstNode end)
113
for (AstNode pos = start; pos != end; pos = pos.NextSibling) {
114
if (pos.Role == Roles.Comment || pos.Role == Roles.NewLine || pos.Role == Roles.PreProcessorDirective) {
115
pos.AcceptVisitor(this);
121
/// Writes all specials between the current position (in the positionStack) and the next
122
/// node with the specified role. Advances the current position.
124
void WriteSpecialsUpToRole(Role role)
126
WriteSpecialsUpToRole(role, null);
129
void WriteSpecialsUpToRole(Role role, AstNode nextNode)
131
if (positionStack.Count == 0) {
134
// Look for the role between the current position and the nextNode.
135
for (AstNode pos = positionStack.Peek(); pos != null && pos != nextNode; pos = pos.NextSibling) {
136
if (pos.Role == role) {
137
WriteSpecials(positionStack.Pop(), pos);
138
// Push the next sibling because the node matching the role is not a special,
139
// and should be considered to be already handled.
140
positionStack.Push(pos.NextSibling);
141
// This is necessary for OptionalComma() to work correctly.
148
/// Writes all specials between the current position (in the positionStack) and the specified node.
149
/// Advances the current position.
151
void WriteSpecialsUpToNode(AstNode node)
153
if (positionStack.Count == 0) {
156
for (AstNode pos = positionStack.Peek(); pos != null; pos = pos.NextSibling) {
158
WriteSpecials(positionStack.Pop(), pos);
159
// Push the next sibling because the node itself is not a special,
160
// and should be considered to be already handled.
161
positionStack.Push(pos.NextSibling);
162
// This is necessary for OptionalComma() to work correctly.
173
/// <param name="nextNode">The next node after the comma.</param>
174
/// <param name="noSpaceAfterComma">When set prevents printing a space after comma.</param>
175
void Comma(AstNode nextNode, bool noSpaceAfterComma = false)
177
WriteSpecialsUpToRole(Roles.Comma, nextNode);
178
Space(policy.SpaceBeforeBracketComma);
179
// TODO: Comma policy has changed.
180
formatter.WriteToken(",");
181
lastWritten = LastWritten.Other;
182
Space(!noSpaceAfterComma && policy.SpaceAfterBracketComma);
183
// TODO: Comma policy has changed.
187
/// Writes an optional comma, e.g. at the end of an enum declaration or in an array initializer
191
// Look if there's a comma after the current node, and insert it if it exists.
192
AstNode pos = positionStack.Peek();
193
while (pos != null && pos.NodeType == NodeType.Whitespace) {
194
pos = pos.NextSibling;
196
if (pos != null && pos.Role == Roles.Comma) {
197
Comma(null, noSpaceAfterComma: true);
202
/// Writes an optional semicolon, e.g. at the end of a type or namespace declaration.
204
void OptionalSemicolon()
206
// Look if there's a semicolon after the current node, and insert it if it exists.
207
AstNode pos = positionStack.Peek();
208
while (pos != null && pos.NodeType == NodeType.Whitespace) {
209
pos = pos.NextSibling;
211
if (pos != null && pos.Role == Roles.Semicolon) {
216
void WriteCommaSeparatedList(IEnumerable<AstNode> list)
219
foreach (AstNode node in list) {
225
node.AcceptVisitor(this);
229
void WriteCommaSeparatedListInParenthesis(IEnumerable<AstNode> list, bool spaceWithin)
234
WriteCommaSeparatedList(list);
241
void WriteCommaSeparatedList(IEnumerable<VariableInitializer> list)
243
WriteCommaSeparatedList(list.SafeCast<VariableInitializer, AstNode>());
246
void WriteCommaSeparatedList(IEnumerable<AstType> list)
248
WriteCommaSeparatedList(list.SafeCast<AstType, AstNode>());
251
void WriteCommaSeparatedListInParenthesis(IEnumerable<Expression> list, bool spaceWithin)
253
WriteCommaSeparatedListInParenthesis(list.SafeCast<Expression, AstNode>(), spaceWithin);
256
void WriteCommaSeparatedListInParenthesis(IEnumerable<ParameterDeclaration> list, bool spaceWithin)
258
WriteCommaSeparatedListInParenthesis(list.SafeCast<ParameterDeclaration, AstNode>(), spaceWithin);
263
void WriteCommaSeparatedListInBrackets(IEnumerable<ParameterDeclaration> list, bool spaceWithin)
265
WriteToken(Roles.LBracket);
268
WriteCommaSeparatedList(list);
271
WriteToken(Roles.RBracket);
274
void WriteCommaSeparatedListInBrackets(IEnumerable<Expression> list)
276
WriteToken(Roles.LBracket);
278
Space(policy.SpacesWithinBrackets);
279
WriteCommaSeparatedList(list);
280
Space(policy.SpacesWithinBrackets);
282
WriteToken(Roles.RBracket);
288
/// Writes a keyword, and all specials up to
290
void WriteKeyword(TokenRole tokenRole)
292
WriteKeyword(tokenRole.Token, tokenRole);
295
void WriteKeyword(string token, Role tokenRole = null)
297
if (tokenRole != null) {
298
WriteSpecialsUpToRole(tokenRole);
300
if (lastWritten == LastWritten.KeywordOrIdentifier) {
303
formatter.WriteKeyword(token);
304
lastWritten = LastWritten.KeywordOrIdentifier;
307
/* void WriteKeyword (string keyword, Role tokenRole)
309
WriteSpecialsUpToRole (tokenRole);
310
if (lastWritten == LastWritten.KeywordOrIdentifier)
312
formatter.WriteKeyword (keyword);
313
lastWritten = LastWritten.KeywordOrIdentifier;
316
void WriteIdentifier(string identifier, Role<Identifier> identifierRole = null)
318
WriteSpecialsUpToRole(identifierRole ?? Roles.Identifier);
319
if (IsKeyword(identifier, containerStack.Peek())) {
320
if (lastWritten == LastWritten.KeywordOrIdentifier) {
323
// this space is not strictly required, so we call Space()
324
formatter.WriteToken("@");
325
} else if (lastWritten == LastWritten.KeywordOrIdentifier) {
327
// this space is strictly required, so we directly call the formatter
329
formatter.WriteIdentifier(identifier);
330
lastWritten = LastWritten.KeywordOrIdentifier;
333
void WriteToken(TokenRole tokenRole)
335
WriteToken(tokenRole.Token, tokenRole);
338
void WriteToken(string token, Role tokenRole)
340
WriteSpecialsUpToRole(tokenRole);
341
// Avoid that two +, - or ? tokens are combined into a ++, -- or ?? token.
342
// Note that we don't need to handle tokens like = because there's no valid
343
// C# program that contains the single token twice in a row.
344
// (for +, - and &, this can happen with unary operators;
345
// for ?, this can happen in "a is int? ? b : c" or "a as int? ?? 0";
346
// and for /, this can happen with "1/ *ptr" or "1/ //comment".)
347
if (lastWritten == LastWritten.Plus && token [0] == '+'
348
|| lastWritten == LastWritten.Minus && token [0] == '-'
349
|| lastWritten == LastWritten.Ampersand && token [0] == '&'
350
|| lastWritten == LastWritten.QuestionMark && token [0] == '?'
351
|| lastWritten == LastWritten.Division && token [0] == '*') {
354
formatter.WriteToken(token);
356
lastWritten = LastWritten.Plus;
357
} else if (token == "-") {
358
lastWritten = LastWritten.Minus;
359
} else if (token == "&") {
360
lastWritten = LastWritten.Ampersand;
361
} else if (token == "?") {
362
lastWritten = LastWritten.QuestionMark;
363
} else if (token == "/") {
364
lastWritten = LastWritten.Division;
366
lastWritten = LastWritten.Other;
372
WriteToken(Roles.LPar);
377
WriteToken(Roles.RPar);
381
/// Marks the end of a statement
385
Role role = containerStack.Peek().Role;
386
// get the role of the current node
387
if (!(role == ForStatement.InitializerRole || role == ForStatement.IteratorRole || role == UsingStatement.ResourceAcquisitionRole)) {
388
WriteToken(Roles.Semicolon);
394
/// Writes a space depending on policy.
396
void Space(bool addSpace = true)
400
lastWritten = LastWritten.Whitespace;
407
lastWritten = LastWritten.Whitespace;
410
void OpenBrace(BraceStyle style)
412
WriteSpecialsUpToRole(Roles.LBrace);
413
formatter.OpenBrace(style);
414
lastWritten = LastWritten.Other;
417
void CloseBrace(BraceStyle style)
419
WriteSpecialsUpToRole(Roles.RBrace);
420
formatter.CloseBrace(style);
421
lastWritten = LastWritten.Other;
426
#region IsKeyword Test
427
static readonly HashSet<string> unconditionalKeywords = new HashSet<string> {
428
"abstract", "as", "base", "bool", "break", "byte", "case", "catch",
429
"char", "checked", "class", "const", "continue", "decimal", "default", "delegate",
430
"do", "double", "else", "enum", "event", "explicit", "extern", "false",
431
"finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit",
432
"in", "int", "interface", "internal", "is", "lock", "long", "namespace",
433
"new", "null", "object", "operator", "out", "override", "params", "private",
434
"protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short",
435
"sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw",
436
"true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort",
437
"using", "virtual", "void", "volatile", "while"
439
static readonly HashSet<string> queryKeywords = new HashSet<string> {
440
"from", "where", "join", "on", "equals", "into", "let", "orderby",
441
"ascending", "descending", "select", "group", "by"
445
/// Determines whether the specified identifier is a keyword in the given context.
447
public static bool IsKeyword(string identifier, AstNode context)
449
if (unconditionalKeywords.Contains(identifier)) {
452
foreach (AstNode ancestor in context.Ancestors) {
453
if (ancestor is QueryExpression && queryKeywords.Contains(identifier)) {
456
if (identifier == "await") {
457
// with lambdas/anonymous methods,
458
if (ancestor is LambdaExpression) {
459
return ((LambdaExpression)ancestor).IsAsync;
461
if (ancestor is AnonymousMethodExpression) {
462
return ((AnonymousMethodExpression)ancestor).IsAsync;
464
if (ancestor is EntityDeclaration) {
465
return (((EntityDeclaration)ancestor).Modifiers & Modifiers.Async) == Modifiers.Async;
473
#region Write constructs
474
void WriteTypeArguments(IEnumerable<AstType> typeArguments)
476
if (typeArguments.Any()) {
477
WriteToken(Roles.LChevron);
478
WriteCommaSeparatedList(typeArguments);
479
WriteToken(Roles.RChevron);
483
public void WriteTypeParameters(IEnumerable<TypeParameterDeclaration> typeParameters)
485
if (typeParameters.Any()) {
486
WriteToken(Roles.LChevron);
487
WriteCommaSeparatedList(typeParameters);
488
WriteToken(Roles.RChevron);
492
void WriteModifiers(IEnumerable<CSharpModifierToken> modifierTokens)
494
foreach (CSharpModifierToken modifier in modifierTokens) {
495
modifier.AcceptVisitor(this);
499
void WriteQualifiedIdentifier(IEnumerable<Identifier> identifiers)
502
foreach (Identifier ident in identifiers) {
505
if (lastWritten == LastWritten.KeywordOrIdentifier) {
509
WriteSpecialsUpToRole(Roles.Dot, ident);
510
formatter.WriteToken(".");
511
lastWritten = LastWritten.Other;
513
WriteSpecialsUpToNode(ident);
514
formatter.WriteIdentifier(ident.Name);
515
lastWritten = LastWritten.KeywordOrIdentifier;
519
void WriteEmbeddedStatement(Statement embeddedStatement)
521
if (embeddedStatement.IsNull) {
525
BlockStatement block = embeddedStatement as BlockStatement;
527
VisitBlockStatement(block);
531
embeddedStatement.AcceptVisitor(this);
532
formatter.Unindent();
536
void WriteMethodBody(BlockStatement body)
541
VisitBlockStatement(body);
545
void WriteAttributes(IEnumerable<AttributeSection> attributes)
547
foreach (AttributeSection attr in attributes) {
548
attr.AcceptVisitor(this);
552
void WritePrivateImplementationType(AstType privateImplementationType)
554
if (!privateImplementationType.IsNull) {
555
privateImplementationType.AcceptVisitor(this);
556
WriteToken(Roles.Dot);
563
public void VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression)
565
StartNode(anonymousMethodExpression);
566
if (anonymousMethodExpression.IsAsync) {
567
WriteKeyword(AnonymousMethodExpression.AsyncModifierRole);
570
WriteKeyword(AnonymousMethodExpression.DelegateKeywordRole);
571
if (anonymousMethodExpression.HasParameterList) {
572
Space(policy.SpaceBeforeMethodDeclarationParentheses);
573
WriteCommaSeparatedListInParenthesis(anonymousMethodExpression.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
575
anonymousMethodExpression.Body.AcceptVisitor(this);
576
EndNode(anonymousMethodExpression);
579
public void VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression)
581
StartNode(undocumentedExpression);
582
switch (undocumentedExpression.UndocumentedExpressionType) {
583
case UndocumentedExpressionType.ArgList:
584
case UndocumentedExpressionType.ArgListAccess:
585
WriteKeyword(UndocumentedExpression.ArglistKeywordRole);
587
case UndocumentedExpressionType.MakeRef:
588
WriteKeyword(UndocumentedExpression.MakerefKeywordRole);
590
case UndocumentedExpressionType.RefType:
591
WriteKeyword(UndocumentedExpression.ReftypeKeywordRole);
593
case UndocumentedExpressionType.RefValue:
594
WriteKeyword(UndocumentedExpression.RefvalueKeywordRole);
597
if (undocumentedExpression.Arguments.Count > 0) {
598
Space(policy.SpaceBeforeMethodCallParentheses);
599
WriteCommaSeparatedListInParenthesis(undocumentedExpression.Arguments, policy.SpaceWithinMethodCallParentheses);
601
EndNode(undocumentedExpression);
604
public void VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression)
606
StartNode(arrayCreateExpression);
607
WriteKeyword(ArrayCreateExpression.NewKeywordRole);
608
arrayCreateExpression.Type.AcceptVisitor(this);
609
if (arrayCreateExpression.Arguments.Count > 0) {
610
WriteCommaSeparatedListInBrackets(arrayCreateExpression.Arguments);
612
foreach (var specifier in arrayCreateExpression.AdditionalArraySpecifiers) {
613
specifier.AcceptVisitor(this);
615
arrayCreateExpression.Initializer.AcceptVisitor(this);
616
EndNode(arrayCreateExpression);
619
public void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
621
StartNode(arrayInitializerExpression);
622
// "new List<int> { { 1 } }" and "new List<int> { 1 }" are the same semantically.
623
// We also use the same AST for both: we always use two nested ArrayInitializerExpressions
624
// for collection initializers, even if the user did not write nested brackets.
625
// The output visitor will output nested braces only if they are necessary,
626
// or if the braces tokens exist in the AST.
627
bool bracesAreOptional = arrayInitializerExpression.Elements.Count == 1
628
&& IsObjectOrCollectionInitializer(arrayInitializerExpression.Parent)
629
&& !CanBeConfusedWithObjectInitializer(arrayInitializerExpression.Elements.Single());
630
if (bracesAreOptional && arrayInitializerExpression.LBraceToken.IsNull) {
631
arrayInitializerExpression.Elements.Single().AcceptVisitor(this);
633
PrintInitializerElements(arrayInitializerExpression.Elements);
635
EndNode(arrayInitializerExpression);
638
bool CanBeConfusedWithObjectInitializer(Expression expr)
640
// "int a; new List<int> { a = 1 };" is an object initalizers and invalid, but
641
// "int a; new List<int> { { a = 1 } };" is a valid collection initializer.
642
AssignmentExpression ae = expr as AssignmentExpression;
643
return ae != null && ae.Operator == AssignmentOperatorType.Assign;
646
bool IsObjectOrCollectionInitializer(AstNode node)
648
if (!(node is ArrayInitializerExpression)) {
651
if (node.Parent is ObjectCreateExpression) {
652
return node.Role == ObjectCreateExpression.InitializerRole;
654
if (node.Parent is NamedExpression) {
655
return node.Role == Roles.Expression;
660
void PrintInitializerElements(AstNodeCollection<Expression> elements)
663
if (policy.ArrayInitializerWrapping == Wrapping.WrapAlways) {
664
style = BraceStyle.NextLine;
666
style = BraceStyle.EndOfLine;
670
foreach (AstNode node in elements) {
674
Comma(node, noSpaceAfterComma: true);
677
node.AcceptVisitor(this);
684
public void VisitAsExpression(AsExpression asExpression)
686
StartNode(asExpression);
687
asExpression.Expression.AcceptVisitor(this);
689
WriteKeyword(AsExpression.AsKeywordRole);
691
asExpression.Type.AcceptVisitor(this);
692
EndNode(asExpression);
695
public void VisitAssignmentExpression(AssignmentExpression assignmentExpression)
697
StartNode(assignmentExpression);
698
assignmentExpression.Left.AcceptVisitor(this);
699
Space(policy.SpaceAroundAssignment);
700
WriteToken(AssignmentExpression.GetOperatorRole(assignmentExpression.Operator));
701
Space(policy.SpaceAroundAssignment);
702
assignmentExpression.Right.AcceptVisitor(this);
703
EndNode(assignmentExpression);
706
public void VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression)
708
StartNode(baseReferenceExpression);
709
WriteKeyword("base", baseReferenceExpression.Role);
710
EndNode(baseReferenceExpression);
713
public void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
715
StartNode(binaryOperatorExpression);
716
binaryOperatorExpression.Left.AcceptVisitor(this);
718
switch (binaryOperatorExpression.Operator) {
719
case BinaryOperatorType.BitwiseAnd:
720
case BinaryOperatorType.BitwiseOr:
721
case BinaryOperatorType.ExclusiveOr:
722
spacePolicy = policy.SpaceAroundBitwiseOperator;
724
case BinaryOperatorType.ConditionalAnd:
725
case BinaryOperatorType.ConditionalOr:
726
spacePolicy = policy.SpaceAroundLogicalOperator;
728
case BinaryOperatorType.GreaterThan:
729
case BinaryOperatorType.GreaterThanOrEqual:
730
case BinaryOperatorType.LessThanOrEqual:
731
case BinaryOperatorType.LessThan:
732
spacePolicy = policy.SpaceAroundRelationalOperator;
734
case BinaryOperatorType.Equality:
735
case BinaryOperatorType.InEquality:
736
spacePolicy = policy.SpaceAroundEqualityOperator;
738
case BinaryOperatorType.Add:
739
case BinaryOperatorType.Subtract:
740
spacePolicy = policy.SpaceAroundAdditiveOperator;
742
case BinaryOperatorType.Multiply:
743
case BinaryOperatorType.Divide:
744
case BinaryOperatorType.Modulus:
745
spacePolicy = policy.SpaceAroundMultiplicativeOperator;
747
case BinaryOperatorType.ShiftLeft:
748
case BinaryOperatorType.ShiftRight:
749
spacePolicy = policy.SpaceAroundShiftOperator;
751
case BinaryOperatorType.NullCoalescing:
755
throw new NotSupportedException ("Invalid value for BinaryOperatorType");
758
WriteToken(BinaryOperatorExpression.GetOperatorRole(binaryOperatorExpression.Operator));
760
binaryOperatorExpression.Right.AcceptVisitor(this);
761
EndNode(binaryOperatorExpression);
764
public void VisitCastExpression(CastExpression castExpression)
766
StartNode(castExpression);
768
Space(policy.SpacesWithinCastParentheses);
769
castExpression.Type.AcceptVisitor(this);
770
Space(policy.SpacesWithinCastParentheses);
772
Space(policy.SpaceAfterTypecast);
773
castExpression.Expression.AcceptVisitor(this);
774
EndNode(castExpression);
777
public void VisitCheckedExpression(CheckedExpression checkedExpression)
779
StartNode(checkedExpression);
780
WriteKeyword(CheckedExpression.CheckedKeywordRole);
782
Space(policy.SpacesWithinCheckedExpressionParantheses);
783
checkedExpression.Expression.AcceptVisitor(this);
784
Space(policy.SpacesWithinCheckedExpressionParantheses);
786
EndNode(checkedExpression);
789
public void VisitConditionalExpression(ConditionalExpression conditionalExpression)
791
StartNode(conditionalExpression);
792
conditionalExpression.Condition.AcceptVisitor(this);
794
Space(policy.SpaceBeforeConditionalOperatorCondition);
795
WriteToken(ConditionalExpression.QuestionMarkRole);
796
Space(policy.SpaceAfterConditionalOperatorCondition);
798
conditionalExpression.TrueExpression.AcceptVisitor(this);
800
Space(policy.SpaceBeforeConditionalOperatorSeparator);
801
WriteToken(ConditionalExpression.ColonRole);
802
Space(policy.SpaceAfterConditionalOperatorSeparator);
804
conditionalExpression.FalseExpression.AcceptVisitor(this);
806
EndNode(conditionalExpression);
809
public void VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression)
811
StartNode(defaultValueExpression);
813
WriteKeyword(DefaultValueExpression.DefaultKeywordRole);
815
Space(policy.SpacesWithinTypeOfParentheses);
816
defaultValueExpression.Type.AcceptVisitor(this);
817
Space(policy.SpacesWithinTypeOfParentheses);
820
EndNode(defaultValueExpression);
823
public void VisitDirectionExpression(DirectionExpression directionExpression)
825
StartNode(directionExpression);
827
switch (directionExpression.FieldDirection) {
828
case FieldDirection.Out:
829
WriteKeyword(DirectionExpression.OutKeywordRole);
831
case FieldDirection.Ref:
832
WriteKeyword(DirectionExpression.RefKeywordRole);
835
throw new NotSupportedException ("Invalid value for FieldDirection");
838
directionExpression.Expression.AcceptVisitor(this);
840
EndNode(directionExpression);
843
public void VisitIdentifierExpression(IdentifierExpression identifierExpression)
845
StartNode(identifierExpression);
846
WriteIdentifier(identifierExpression.Identifier);
847
WriteTypeArguments(identifierExpression.TypeArguments);
848
EndNode(identifierExpression);
851
public void VisitIndexerExpression(IndexerExpression indexerExpression)
853
StartNode(indexerExpression);
854
indexerExpression.Target.AcceptVisitor(this);
855
Space(policy.SpaceBeforeMethodCallParentheses);
856
WriteCommaSeparatedListInBrackets(indexerExpression.Arguments);
857
EndNode(indexerExpression);
860
public void VisitInvocationExpression(InvocationExpression invocationExpression)
862
StartNode(invocationExpression);
863
invocationExpression.Target.AcceptVisitor(this);
864
Space(policy.SpaceBeforeMethodCallParentheses);
865
WriteCommaSeparatedListInParenthesis(invocationExpression.Arguments, policy.SpaceWithinMethodCallParentheses);
866
EndNode(invocationExpression);
869
public void VisitIsExpression(IsExpression isExpression)
871
StartNode(isExpression);
872
isExpression.Expression.AcceptVisitor(this);
874
WriteKeyword(IsExpression.IsKeywordRole);
875
isExpression.Type.AcceptVisitor(this);
876
EndNode(isExpression);
879
public void VisitLambdaExpression(LambdaExpression lambdaExpression)
881
StartNode(lambdaExpression);
882
if (lambdaExpression.IsAsync) {
883
WriteKeyword(LambdaExpression.AsyncModifierRole);
886
if (LambdaNeedsParenthesis(lambdaExpression)) {
887
WriteCommaSeparatedListInParenthesis(lambdaExpression.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
889
lambdaExpression.Parameters.Single().AcceptVisitor(this);
892
WriteToken(LambdaExpression.ArrowRole);
894
lambdaExpression.Body.AcceptVisitor(this);
895
EndNode(lambdaExpression);
898
bool LambdaNeedsParenthesis(LambdaExpression lambdaExpression)
900
if (lambdaExpression.Parameters.Count != 1) {
903
var p = lambdaExpression.Parameters.Single();
904
return !(p.Type.IsNull && p.ParameterModifier == ParameterModifier.None);
907
public void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
909
StartNode(memberReferenceExpression);
910
memberReferenceExpression.Target.AcceptVisitor(this);
911
WriteToken(Roles.Dot);
912
WriteIdentifier(memberReferenceExpression.MemberName);
913
WriteTypeArguments(memberReferenceExpression.TypeArguments);
914
EndNode(memberReferenceExpression);
917
public void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression)
919
StartNode(namedArgumentExpression);
920
namedArgumentExpression.NameToken.AcceptVisitor(this);
921
WriteToken(Roles.Colon);
923
namedArgumentExpression.Expression.AcceptVisitor(this);
924
EndNode(namedArgumentExpression);
927
public void VisitNamedExpression(NamedExpression namedExpression)
929
StartNode(namedExpression);
930
namedExpression.NameToken.AcceptVisitor(this);
932
WriteToken(Roles.Assign);
934
namedExpression.Expression.AcceptVisitor(this);
935
EndNode(namedExpression);
938
public void VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression)
940
StartNode(nullReferenceExpression);
941
WriteKeyword("null", nullReferenceExpression.Role);
942
EndNode(nullReferenceExpression);
945
public void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
947
StartNode(objectCreateExpression);
948
WriteKeyword(ObjectCreateExpression.NewKeywordRole);
949
objectCreateExpression.Type.AcceptVisitor(this);
950
bool useParenthesis = objectCreateExpression.Arguments.Any() || objectCreateExpression.Initializer.IsNull;
951
// also use parenthesis if there is an '(' token
952
if (!objectCreateExpression.LParToken.IsNull) {
953
useParenthesis = true;
955
if (useParenthesis) {
956
Space(policy.SpaceBeforeMethodCallParentheses);
957
WriteCommaSeparatedListInParenthesis(objectCreateExpression.Arguments, policy.SpaceWithinMethodCallParentheses);
959
objectCreateExpression.Initializer.AcceptVisitor(this);
960
EndNode(objectCreateExpression);
963
public void VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression)
965
StartNode(anonymousTypeCreateExpression);
966
WriteKeyword(AnonymousTypeCreateExpression.NewKeywordRole);
967
PrintInitializerElements(anonymousTypeCreateExpression.Initializers);
968
EndNode(anonymousTypeCreateExpression);
971
public void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression)
973
StartNode(parenthesizedExpression);
975
Space(policy.SpacesWithinParentheses);
976
parenthesizedExpression.Expression.AcceptVisitor(this);
977
Space(policy.SpacesWithinParentheses);
979
EndNode(parenthesizedExpression);
982
public void VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression)
984
StartNode(pointerReferenceExpression);
985
pointerReferenceExpression.Target.AcceptVisitor(this);
986
WriteToken(PointerReferenceExpression.ArrowRole);
987
WriteIdentifier(pointerReferenceExpression.MemberName);
988
WriteTypeArguments(pointerReferenceExpression.TypeArguments);
989
EndNode(pointerReferenceExpression);
992
public void VisitEmptyExpression(EmptyExpression emptyExpression)
994
StartNode(emptyExpression);
995
EndNode(emptyExpression);
998
#region VisitPrimitiveExpression
999
public void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression)
1001
StartNode(primitiveExpression);
1002
if (!string.IsNullOrEmpty(primitiveExpression.LiteralValue)) {
1003
formatter.WriteToken(primitiveExpression.LiteralValue);
1005
WritePrimitiveValue(primitiveExpression.Value);
1007
EndNode(primitiveExpression);
1010
public static string PrintPrimitiveValue(object val)
1012
StringWriter writer = new StringWriter();
1013
CSharpOutputVisitor visitor = new CSharpOutputVisitor(writer, new CSharpFormattingOptions());
1014
visitor.WritePrimitiveValue(val);
1015
return writer.ToString();
1018
void WritePrimitiveValue(object val)
1021
// usually NullReferenceExpression should be used for this, but we'll handle it anyways
1022
WriteKeyword("null");
1028
WriteKeyword("true");
1030
WriteKeyword("false");
1035
if (val is string) {
1036
formatter.WriteToken("\"" + ConvertString(val.ToString()) + "\"");
1037
lastWritten = LastWritten.Other;
1038
} else if (val is char) {
1039
formatter.WriteToken("'" + ConvertCharLiteral((char)val) + "'");
1040
lastWritten = LastWritten.Other;
1041
} else if (val is decimal) {
1042
formatter.WriteToken(((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m");
1043
lastWritten = LastWritten.Other;
1044
} else if (val is float) {
1045
float f = (float)val;
1046
if (float.IsInfinity(f) || float.IsNaN(f)) {
1047
// Strictly speaking, these aren't PrimitiveExpressions;
1048
// but we still support writing these to make life easier for code generators.
1049
WriteKeyword("float");
1050
WriteToken(Roles.Dot);
1051
if (float.IsPositiveInfinity(f)) {
1052
WriteIdentifier("PositiveInfinity");
1053
} else if (float.IsNegativeInfinity(f)) {
1054
WriteIdentifier("NegativeInfinity");
1056
WriteIdentifier("NaN");
1060
if (f == 0 && 1 / f == float.NegativeInfinity) {
1061
// negative zero is a special case
1062
// (again, not a primitive expression, but it's better to handle
1063
// the special case here than to do it in all code generators)
1064
formatter.WriteToken("-");
1066
formatter.WriteToken(f.ToString("R", NumberFormatInfo.InvariantInfo) + "f");
1067
lastWritten = LastWritten.Other;
1068
} else if (val is double) {
1069
double f = (double)val;
1070
if (double.IsInfinity(f) || double.IsNaN(f)) {
1071
// Strictly speaking, these aren't PrimitiveExpressions;
1072
// but we still support writing these to make life easier for code generators.
1073
WriteKeyword("double");
1074
WriteToken(Roles.Dot);
1075
if (double.IsPositiveInfinity(f)) {
1076
WriteIdentifier("PositiveInfinity");
1077
} else if (double.IsNegativeInfinity(f)) {
1078
WriteIdentifier("NegativeInfinity");
1080
WriteIdentifier("NaN");
1084
if (f == 0 && 1 / f == double.NegativeInfinity) {
1085
// negative zero is a special case
1086
// (again, not a primitive expression, but it's better to handle
1087
// the special case here than to do it in all code generators)
1088
formatter.WriteToken("-");
1090
string number = f.ToString("R", NumberFormatInfo.InvariantInfo);
1091
if (number.IndexOf('.') < 0 && number.IndexOf('E') < 0) {
1094
formatter.WriteToken(number);
1095
// needs space if identifier follows number; this avoids mistaking the following identifier as type suffix
1096
lastWritten = LastWritten.KeywordOrIdentifier;
1097
} else if (val is IFormattable) {
1098
StringBuilder b = new StringBuilder ();
1099
// if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) {
1101
// b.Append(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo));
1103
b.Append(((IFormattable)val).ToString(null, NumberFormatInfo.InvariantInfo));
1105
if (val is uint || val is ulong) {
1108
if (val is long || val is ulong) {
1111
formatter.WriteToken(b.ToString());
1112
// needs space if identifier follows number; this avoids mistaking the following identifier as type suffix
1113
lastWritten = LastWritten.KeywordOrIdentifier;
1115
formatter.WriteToken(val.ToString());
1116
lastWritten = LastWritten.Other;
1120
static string ConvertCharLiteral(char ch)
1125
return ConvertChar(ch);
1129
/// Gets the escape sequence for the specified character.
1131
/// <remarks>This method does not convert ' or ".</remarks>
1132
public static string ConvertChar(char ch)
1154
if (char.IsControl(ch) || char.IsSurrogate(ch) ||
1155
// print all uncommon white spaces as numbers
1156
(char.IsWhiteSpace(ch) && ch != ' ')) {
1157
return "\\u" + ((int)ch).ToString("x4");
1159
return ch.ToString();
1165
/// Converts special characters to escape sequences within the given string.
1167
public static string ConvertString(string str)
1169
StringBuilder sb = new StringBuilder ();
1170
foreach (char ch in str) {
1174
sb.Append(ConvertChar(ch));
1177
return sb.ToString();
1182
public void VisitSizeOfExpression(SizeOfExpression sizeOfExpression)
1184
StartNode(sizeOfExpression);
1186
WriteKeyword(SizeOfExpression.SizeofKeywordRole);
1188
Space(policy.SpacesWithinSizeOfParentheses);
1189
sizeOfExpression.Type.AcceptVisitor(this);
1190
Space(policy.SpacesWithinSizeOfParentheses);
1193
EndNode(sizeOfExpression);
1196
public void VisitStackAllocExpression(StackAllocExpression stackAllocExpression)
1198
StartNode(stackAllocExpression);
1199
WriteKeyword(StackAllocExpression.StackallocKeywordRole);
1200
stackAllocExpression.Type.AcceptVisitor(this);
1201
WriteCommaSeparatedListInBrackets(new[] { stackAllocExpression.CountExpression });
1202
EndNode(stackAllocExpression);
1205
public void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
1207
StartNode(thisReferenceExpression);
1208
WriteKeyword("this", thisReferenceExpression.Role);
1209
EndNode(thisReferenceExpression);
1212
public void VisitTypeOfExpression(TypeOfExpression typeOfExpression)
1214
StartNode(typeOfExpression);
1216
WriteKeyword(TypeOfExpression.TypeofKeywordRole);
1218
Space(policy.SpacesWithinTypeOfParentheses);
1219
typeOfExpression.Type.AcceptVisitor(this);
1220
Space(policy.SpacesWithinTypeOfParentheses);
1223
EndNode(typeOfExpression);
1226
public void VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression)
1228
StartNode(typeReferenceExpression);
1229
typeReferenceExpression.Type.AcceptVisitor(this);
1230
EndNode(typeReferenceExpression);
1233
public void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
1235
StartNode(unaryOperatorExpression);
1236
UnaryOperatorType opType = unaryOperatorExpression.Operator;
1237
var opSymbol = UnaryOperatorExpression.GetOperatorRole(opType);
1238
if (opType == UnaryOperatorType.Await) {
1239
WriteKeyword(opSymbol);
1240
} else if (!(opType == UnaryOperatorType.PostIncrement || opType == UnaryOperatorType.PostDecrement)) {
1241
WriteToken(opSymbol);
1243
unaryOperatorExpression.Expression.AcceptVisitor(this);
1244
if (opType == UnaryOperatorType.PostIncrement || opType == UnaryOperatorType.PostDecrement) {
1245
WriteToken(opSymbol);
1247
EndNode(unaryOperatorExpression);
1250
public void VisitUncheckedExpression(UncheckedExpression uncheckedExpression)
1252
StartNode(uncheckedExpression);
1253
WriteKeyword(UncheckedExpression.UncheckedKeywordRole);
1255
Space(policy.SpacesWithinCheckedExpressionParantheses);
1256
uncheckedExpression.Expression.AcceptVisitor(this);
1257
Space(policy.SpacesWithinCheckedExpressionParantheses);
1259
EndNode(uncheckedExpression);
1264
#region Query Expressions
1265
public void VisitQueryExpression(QueryExpression queryExpression)
1267
StartNode(queryExpression);
1268
bool indent = !(queryExpression.Parent is QueryContinuationClause);
1274
foreach (var clause in queryExpression.Clauses) {
1278
if (!(clause is QueryContinuationClause)) {
1282
clause.AcceptVisitor(this);
1285
formatter.Unindent();
1287
EndNode(queryExpression);
1290
public void VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause)
1292
StartNode(queryContinuationClause);
1293
queryContinuationClause.PrecedingQuery.AcceptVisitor(this);
1295
WriteKeyword(QueryContinuationClause.IntoKeywordRole);
1297
queryContinuationClause.IdentifierToken.AcceptVisitor(this);
1298
EndNode(queryContinuationClause);
1301
public void VisitQueryFromClause(QueryFromClause queryFromClause)
1303
StartNode(queryFromClause);
1304
WriteKeyword(QueryFromClause.FromKeywordRole);
1305
queryFromClause.Type.AcceptVisitor(this);
1307
queryFromClause.IdentifierToken.AcceptVisitor(this);
1309
WriteKeyword(QueryFromClause.InKeywordRole);
1311
queryFromClause.Expression.AcceptVisitor(this);
1312
EndNode(queryFromClause);
1315
public void VisitQueryLetClause(QueryLetClause queryLetClause)
1317
StartNode(queryLetClause);
1318
WriteKeyword(QueryLetClause.LetKeywordRole);
1320
queryLetClause.IdentifierToken.AcceptVisitor(this);
1321
Space(policy.SpaceAroundAssignment);
1322
WriteToken(Roles.Assign);
1323
Space(policy.SpaceAroundAssignment);
1324
queryLetClause.Expression.AcceptVisitor(this);
1325
EndNode(queryLetClause);
1328
public void VisitQueryWhereClause(QueryWhereClause queryWhereClause)
1330
StartNode(queryWhereClause);
1331
WriteKeyword(QueryWhereClause.WhereKeywordRole);
1333
queryWhereClause.Condition.AcceptVisitor(this);
1334
EndNode(queryWhereClause);
1337
public void VisitQueryJoinClause(QueryJoinClause queryJoinClause)
1339
StartNode(queryJoinClause);
1340
WriteKeyword(QueryJoinClause.JoinKeywordRole);
1341
queryJoinClause.Type.AcceptVisitor(this);
1343
WriteIdentifier(queryJoinClause.JoinIdentifier, QueryJoinClause.JoinIdentifierRole);
1345
WriteKeyword(QueryJoinClause.InKeywordRole);
1347
queryJoinClause.InExpression.AcceptVisitor(this);
1349
WriteKeyword(QueryJoinClause.OnKeywordRole);
1351
queryJoinClause.OnExpression.AcceptVisitor(this);
1353
WriteKeyword(QueryJoinClause.EqualsKeywordRole);
1355
queryJoinClause.EqualsExpression.AcceptVisitor(this);
1356
if (queryJoinClause.IsGroupJoin) {
1358
WriteKeyword(QueryJoinClause.IntoKeywordRole);
1359
WriteIdentifier(queryJoinClause.IntoIdentifier, QueryJoinClause.IntoIdentifierRole);
1361
EndNode(queryJoinClause);
1364
public void VisitQueryOrderClause(QueryOrderClause queryOrderClause)
1366
StartNode(queryOrderClause);
1367
WriteKeyword(QueryOrderClause.OrderbyKeywordRole);
1369
WriteCommaSeparatedList(queryOrderClause.Orderings);
1370
EndNode(queryOrderClause);
1373
public void VisitQueryOrdering(QueryOrdering queryOrdering)
1375
StartNode(queryOrdering);
1376
queryOrdering.Expression.AcceptVisitor(this);
1377
switch (queryOrdering.Direction) {
1378
case QueryOrderingDirection.Ascending:
1380
WriteKeyword(QueryOrdering.AscendingKeywordRole);
1382
case QueryOrderingDirection.Descending:
1384
WriteKeyword(QueryOrdering.DescendingKeywordRole);
1387
EndNode(queryOrdering);
1390
public void VisitQuerySelectClause(QuerySelectClause querySelectClause)
1392
StartNode(querySelectClause);
1393
WriteKeyword(QuerySelectClause.SelectKeywordRole);
1395
querySelectClause.Expression.AcceptVisitor(this);
1396
EndNode(querySelectClause);
1399
public void VisitQueryGroupClause(QueryGroupClause queryGroupClause)
1401
StartNode(queryGroupClause);
1402
WriteKeyword(QueryGroupClause.GroupKeywordRole);
1404
queryGroupClause.Projection.AcceptVisitor(this);
1406
WriteKeyword(QueryGroupClause.ByKeywordRole);
1408
queryGroupClause.Key.AcceptVisitor(this);
1409
EndNode(queryGroupClause);
1414
#region GeneralScope
1415
public void VisitAttribute(Attribute attribute)
1417
StartNode(attribute);
1418
attribute.Type.AcceptVisitor(this);
1419
if (attribute.Arguments.Count != 0 || !attribute.GetChildByRole(Roles.LPar).IsNull) {
1420
Space(policy.SpaceBeforeMethodCallParentheses);
1421
WriteCommaSeparatedListInParenthesis(attribute.Arguments, policy.SpaceWithinMethodCallParentheses);
1426
public void VisitAttributeSection(AttributeSection attributeSection)
1428
StartNode(attributeSection);
1429
WriteToken(Roles.LBracket);
1430
if (!string.IsNullOrEmpty(attributeSection.AttributeTarget)) {
1431
WriteToken(attributeSection.AttributeTarget, Roles.AttributeTargetRole);
1432
WriteToken(Roles.Colon);
1435
WriteCommaSeparatedList(attributeSection.Attributes);
1436
WriteToken(Roles.RBracket);
1437
if (attributeSection.Parent is ParameterDeclaration || attributeSection.Parent is TypeParameterDeclaration) {
1442
EndNode(attributeSection);
1445
public void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)
1447
StartNode(delegateDeclaration);
1448
WriteAttributes(delegateDeclaration.Attributes);
1449
WriteModifiers(delegateDeclaration.ModifierTokens);
1450
WriteKeyword(Roles.DelegateKeyword);
1451
delegateDeclaration.ReturnType.AcceptVisitor(this);
1453
delegateDeclaration.NameToken.AcceptVisitor(this);
1454
WriteTypeParameters(delegateDeclaration.TypeParameters);
1455
Space(policy.SpaceBeforeDelegateDeclarationParentheses);
1456
WriteCommaSeparatedListInParenthesis(delegateDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
1457
foreach (Constraint constraint in delegateDeclaration.Constraints) {
1458
constraint.AcceptVisitor(this);
1461
EndNode(delegateDeclaration);
1464
public void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
1466
StartNode(namespaceDeclaration);
1467
WriteKeyword(Roles.NamespaceKeyword);
1468
WriteQualifiedIdentifier(namespaceDeclaration.Identifiers);
1469
OpenBrace(policy.NamespaceBraceStyle);
1470
foreach (var member in namespaceDeclaration.Members) {
1471
member.AcceptVisitor(this);
1473
CloseBrace(policy.NamespaceBraceStyle);
1474
OptionalSemicolon();
1476
EndNode(namespaceDeclaration);
1479
public void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
1481
StartNode(typeDeclaration);
1482
WriteAttributes(typeDeclaration.Attributes);
1483
WriteModifiers(typeDeclaration.ModifierTokens);
1484
BraceStyle braceStyle;
1485
switch (typeDeclaration.ClassType) {
1486
case ClassType.Enum:
1487
WriteKeyword(Roles.EnumKeyword);
1488
braceStyle = policy.EnumBraceStyle;
1490
case ClassType.Interface:
1491
WriteKeyword(Roles.InterfaceKeyword);
1492
braceStyle = policy.InterfaceBraceStyle;
1494
case ClassType.Struct:
1495
WriteKeyword(Roles.StructKeyword);
1496
braceStyle = policy.StructBraceStyle;
1499
WriteKeyword(Roles.ClassKeyword);
1500
braceStyle = policy.ClassBraceStyle;
1503
typeDeclaration.NameToken.AcceptVisitor(this);
1504
WriteTypeParameters(typeDeclaration.TypeParameters);
1505
if (typeDeclaration.BaseTypes.Any()) {
1507
WriteToken(Roles.Colon);
1509
WriteCommaSeparatedList(typeDeclaration.BaseTypes);
1511
foreach (Constraint constraint in typeDeclaration.Constraints) {
1512
constraint.AcceptVisitor(this);
1514
OpenBrace(braceStyle);
1515
if (typeDeclaration.ClassType == ClassType.Enum) {
1517
foreach (var member in typeDeclaration.Members) {
1521
Comma(member, noSpaceAfterComma: true);
1524
member.AcceptVisitor(this);
1529
foreach (var member in typeDeclaration.Members) {
1530
member.AcceptVisitor(this);
1533
CloseBrace(braceStyle);
1534
OptionalSemicolon();
1536
EndNode(typeDeclaration);
1539
public void VisitUsingAliasDeclaration(UsingAliasDeclaration usingAliasDeclaration)
1541
StartNode(usingAliasDeclaration);
1542
WriteKeyword(UsingAliasDeclaration.UsingKeywordRole);
1543
WriteIdentifier(usingAliasDeclaration.Alias, UsingAliasDeclaration.AliasRole);
1544
Space(policy.SpaceAroundEqualityOperator);
1545
WriteToken(Roles.Assign);
1546
Space(policy.SpaceAroundEqualityOperator);
1547
usingAliasDeclaration.Import.AcceptVisitor(this);
1549
EndNode(usingAliasDeclaration);
1552
public void VisitUsingDeclaration(UsingDeclaration usingDeclaration)
1554
StartNode(usingDeclaration);
1555
WriteKeyword(UsingDeclaration.UsingKeywordRole);
1556
usingDeclaration.Import.AcceptVisitor(this);
1558
EndNode(usingDeclaration);
1561
public void VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration)
1563
StartNode(externAliasDeclaration);
1564
WriteKeyword(Roles.ExternKeyword);
1566
WriteKeyword(Roles.AliasKeyword);
1568
externAliasDeclaration.NameToken.AcceptVisitor(this);
1570
EndNode(externAliasDeclaration);
1576
public void VisitBlockStatement(BlockStatement blockStatement)
1578
StartNode(blockStatement);
1580
if (blockStatement.Parent is AnonymousMethodExpression || blockStatement.Parent is LambdaExpression) {
1581
style = policy.AnonymousMethodBraceStyle;
1582
} else if (blockStatement.Parent is ConstructorDeclaration) {
1583
style = policy.ConstructorBraceStyle;
1584
} else if (blockStatement.Parent is DestructorDeclaration) {
1585
style = policy.DestructorBraceStyle;
1586
} else if (blockStatement.Parent is MethodDeclaration) {
1587
style = policy.MethodBraceStyle;
1588
} else if (blockStatement.Parent is Accessor) {
1589
if (blockStatement.Parent.Role == PropertyDeclaration.GetterRole) {
1590
style = policy.PropertyGetBraceStyle;
1591
} else if (blockStatement.Parent.Role == PropertyDeclaration.SetterRole) {
1592
style = policy.PropertySetBraceStyle;
1593
} else if (blockStatement.Parent.Role == CustomEventDeclaration.AddAccessorRole) {
1594
style = policy.EventAddBraceStyle;
1595
} else if (blockStatement.Parent.Role == CustomEventDeclaration.RemoveAccessorRole) {
1596
style = policy.EventRemoveBraceStyle;
1598
style = policy.StatementBraceStyle;
1601
style = policy.StatementBraceStyle;
1604
foreach (var node in blockStatement.Statements) {
1605
node.AcceptVisitor(this);
1608
if (!(blockStatement.Parent is Expression))
1610
EndNode(blockStatement);
1613
public void VisitBreakStatement(BreakStatement breakStatement)
1615
StartNode(breakStatement);
1616
WriteKeyword("break");
1618
EndNode(breakStatement);
1621
public void VisitCheckedStatement(CheckedStatement checkedStatement)
1623
StartNode(checkedStatement);
1624
WriteKeyword(CheckedStatement.CheckedKeywordRole);
1625
checkedStatement.Body.AcceptVisitor(this);
1626
EndNode(checkedStatement);
1629
public void VisitContinueStatement(ContinueStatement continueStatement)
1631
StartNode(continueStatement);
1632
WriteKeyword("continue");
1634
EndNode(continueStatement);
1637
public void VisitDoWhileStatement(DoWhileStatement doWhileStatement)
1639
StartNode(doWhileStatement);
1640
WriteKeyword(DoWhileStatement.DoKeywordRole);
1641
WriteEmbeddedStatement(doWhileStatement.EmbeddedStatement);
1642
WriteKeyword(DoWhileStatement.WhileKeywordRole);
1643
Space(policy.SpaceBeforeWhileParentheses);
1645
Space(policy.SpacesWithinWhileParentheses);
1646
doWhileStatement.Condition.AcceptVisitor(this);
1647
Space(policy.SpacesWithinWhileParentheses);
1650
EndNode(doWhileStatement);
1653
public void VisitEmptyStatement(EmptyStatement emptyStatement)
1655
StartNode(emptyStatement);
1657
EndNode(emptyStatement);
1660
public void VisitExpressionStatement(ExpressionStatement expressionStatement)
1662
StartNode(expressionStatement);
1663
expressionStatement.Expression.AcceptVisitor(this);
1665
EndNode(expressionStatement);
1668
public void VisitFixedStatement(FixedStatement fixedStatement)
1670
StartNode(fixedStatement);
1671
WriteKeyword(FixedStatement.FixedKeywordRole);
1672
Space(policy.SpaceBeforeUsingParentheses);
1674
Space(policy.SpacesWithinUsingParentheses);
1675
fixedStatement.Type.AcceptVisitor(this);
1677
WriteCommaSeparatedList(fixedStatement.Variables);
1678
Space(policy.SpacesWithinUsingParentheses);
1680
WriteEmbeddedStatement(fixedStatement.EmbeddedStatement);
1681
EndNode(fixedStatement);
1684
public void VisitForeachStatement(ForeachStatement foreachStatement)
1686
StartNode(foreachStatement);
1687
WriteKeyword(ForeachStatement.ForeachKeywordRole);
1688
Space(policy.SpaceBeforeForeachParentheses);
1690
Space(policy.SpacesWithinForeachParentheses);
1691
foreachStatement.VariableType.AcceptVisitor(this);
1693
foreachStatement.VariableNameToken.AcceptVisitor(this);
1694
WriteKeyword(ForeachStatement.InKeywordRole);
1696
foreachStatement.InExpression.AcceptVisitor(this);
1697
Space(policy.SpacesWithinForeachParentheses);
1699
WriteEmbeddedStatement(foreachStatement.EmbeddedStatement);
1700
EndNode(foreachStatement);
1703
public void VisitForStatement(ForStatement forStatement)
1705
StartNode(forStatement);
1706
WriteKeyword(ForStatement.ForKeywordRole);
1707
Space(policy.SpaceBeforeForParentheses);
1709
Space(policy.SpacesWithinForParentheses);
1711
WriteCommaSeparatedList(forStatement.Initializers);
1712
Space(policy.SpaceBeforeForSemicolon);
1713
WriteToken(Roles.Semicolon);
1714
Space(policy.SpaceAfterForSemicolon);
1716
forStatement.Condition.AcceptVisitor(this);
1717
Space(policy.SpaceBeforeForSemicolon);
1718
WriteToken(Roles.Semicolon);
1719
if (forStatement.Iterators.Any()) {
1720
Space(policy.SpaceAfterForSemicolon);
1721
WriteCommaSeparatedList(forStatement.Iterators);
1724
Space(policy.SpacesWithinForParentheses);
1726
WriteEmbeddedStatement(forStatement.EmbeddedStatement);
1727
EndNode(forStatement);
1730
public void VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement)
1732
StartNode(gotoCaseStatement);
1733
WriteKeyword(GotoCaseStatement.GotoKeywordRole);
1734
WriteKeyword(GotoCaseStatement.CaseKeywordRole);
1736
gotoCaseStatement.LabelExpression.AcceptVisitor(this);
1738
EndNode(gotoCaseStatement);
1741
public void VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement)
1743
StartNode(gotoDefaultStatement);
1744
WriteKeyword(GotoDefaultStatement.GotoKeywordRole);
1745
WriteKeyword(GotoDefaultStatement.DefaultKeywordRole);
1747
EndNode(gotoDefaultStatement);
1750
public void VisitGotoStatement(GotoStatement gotoStatement)
1752
StartNode(gotoStatement);
1753
WriteKeyword(GotoStatement.GotoKeywordRole);
1754
WriteIdentifier(gotoStatement.Label);
1756
EndNode(gotoStatement);
1759
public void VisitIfElseStatement(IfElseStatement ifElseStatement)
1761
StartNode(ifElseStatement);
1762
WriteKeyword(IfElseStatement.IfKeywordRole);
1763
Space(policy.SpaceBeforeIfParentheses);
1765
Space(policy.SpacesWithinIfParentheses);
1766
ifElseStatement.Condition.AcceptVisitor(this);
1767
Space(policy.SpacesWithinIfParentheses);
1769
WriteEmbeddedStatement(ifElseStatement.TrueStatement);
1770
if (!ifElseStatement.FalseStatement.IsNull) {
1771
WriteKeyword(IfElseStatement.ElseKeywordRole);
1772
WriteEmbeddedStatement(ifElseStatement.FalseStatement);
1774
EndNode(ifElseStatement);
1777
public void VisitLabelStatement(LabelStatement labelStatement)
1779
StartNode(labelStatement);
1780
WriteIdentifier(labelStatement.Label);
1781
WriteToken(Roles.Colon);
1782
bool foundLabelledStatement = false;
1783
for (AstNode tmp = labelStatement.NextSibling; tmp != null; tmp = tmp.NextSibling) {
1784
if (tmp.Role == labelStatement.Role) {
1785
foundLabelledStatement = true;
1788
if (!foundLabelledStatement) {
1789
// introduce an EmptyStatement so that the output becomes syntactically valid
1790
WriteToken(Roles.Semicolon);
1793
EndNode(labelStatement);
1796
public void VisitLockStatement(LockStatement lockStatement)
1798
StartNode(lockStatement);
1799
WriteKeyword(LockStatement.LockKeywordRole);
1800
Space(policy.SpaceBeforeLockParentheses);
1802
Space(policy.SpacesWithinLockParentheses);
1803
lockStatement.Expression.AcceptVisitor(this);
1804
Space(policy.SpacesWithinLockParentheses);
1806
WriteEmbeddedStatement(lockStatement.EmbeddedStatement);
1807
EndNode(lockStatement);
1810
public void VisitReturnStatement(ReturnStatement returnStatement)
1812
StartNode(returnStatement);
1813
WriteKeyword(ReturnStatement.ReturnKeywordRole);
1814
if (!returnStatement.Expression.IsNull) {
1816
returnStatement.Expression.AcceptVisitor(this);
1819
EndNode(returnStatement);
1822
public void VisitSwitchStatement(SwitchStatement switchStatement)
1824
StartNode(switchStatement);
1825
WriteKeyword(SwitchStatement.SwitchKeywordRole);
1826
Space(policy.SpaceBeforeSwitchParentheses);
1828
Space(policy.SpacesWithinSwitchParentheses);
1829
switchStatement.Expression.AcceptVisitor(this);
1830
Space(policy.SpacesWithinSwitchParentheses);
1832
OpenBrace(policy.StatementBraceStyle);
1833
if (!policy.IndentSwitchBody) {
1834
formatter.Unindent();
1837
foreach (var section in switchStatement.SwitchSections) {
1838
section.AcceptVisitor(this);
1841
if (!policy.IndentSwitchBody) {
1844
CloseBrace(policy.StatementBraceStyle);
1846
EndNode(switchStatement);
1849
public void VisitSwitchSection(SwitchSection switchSection)
1851
StartNode(switchSection);
1853
foreach (var label in switchSection.CaseLabels) {
1857
label.AcceptVisitor(this);
1860
bool isBlock = switchSection.Statements.Count == 1 && switchSection.Statements.Single() is BlockStatement;
1861
if (policy.IndentCaseBody && !isBlock) {
1868
foreach (var statement in switchSection.Statements) {
1869
statement.AcceptVisitor(this);
1872
if (policy.IndentCaseBody && !isBlock) {
1873
formatter.Unindent();
1876
EndNode(switchSection);
1879
public void VisitCaseLabel(CaseLabel caseLabel)
1881
StartNode(caseLabel);
1882
if (caseLabel.Expression.IsNull) {
1883
WriteKeyword(CaseLabel.DefaultKeywordRole);
1885
WriteKeyword(CaseLabel.CaseKeywordRole);
1887
caseLabel.Expression.AcceptVisitor(this);
1889
WriteToken(Roles.Colon);
1893
public void VisitThrowStatement(ThrowStatement throwStatement)
1895
StartNode(throwStatement);
1896
WriteKeyword(ThrowStatement.ThrowKeywordRole);
1897
if (!throwStatement.Expression.IsNull) {
1899
throwStatement.Expression.AcceptVisitor(this);
1902
EndNode(throwStatement);
1905
public void VisitTryCatchStatement(TryCatchStatement tryCatchStatement)
1907
StartNode(tryCatchStatement);
1908
WriteKeyword(TryCatchStatement.TryKeywordRole);
1909
tryCatchStatement.TryBlock.AcceptVisitor(this);
1910
foreach (var catchClause in tryCatchStatement.CatchClauses) {
1911
catchClause.AcceptVisitor(this);
1913
if (!tryCatchStatement.FinallyBlock.IsNull) {
1914
WriteKeyword(TryCatchStatement.FinallyKeywordRole);
1915
tryCatchStatement.FinallyBlock.AcceptVisitor(this);
1917
EndNode(tryCatchStatement);
1920
public void VisitCatchClause(CatchClause catchClause)
1922
StartNode(catchClause);
1923
WriteKeyword(CatchClause.CatchKeywordRole);
1924
if (!catchClause.Type.IsNull) {
1925
Space(policy.SpaceBeforeCatchParentheses);
1927
Space(policy.SpacesWithinCatchParentheses);
1928
catchClause.Type.AcceptVisitor(this);
1929
if (!string.IsNullOrEmpty(catchClause.VariableName)) {
1931
catchClause.VariableNameToken.AcceptVisitor(this);
1933
Space(policy.SpacesWithinCatchParentheses);
1936
catchClause.Body.AcceptVisitor(this);
1937
EndNode(catchClause);
1940
public void VisitUncheckedStatement(UncheckedStatement uncheckedStatement)
1942
StartNode(uncheckedStatement);
1943
WriteKeyword(UncheckedStatement.UncheckedKeywordRole);
1944
uncheckedStatement.Body.AcceptVisitor(this);
1945
EndNode(uncheckedStatement);
1948
public void VisitUnsafeStatement(UnsafeStatement unsafeStatement)
1950
StartNode(unsafeStatement);
1951
WriteKeyword(UnsafeStatement.UnsafeKeywordRole);
1952
unsafeStatement.Body.AcceptVisitor(this);
1953
EndNode(unsafeStatement);
1956
public void VisitUsingStatement(UsingStatement usingStatement)
1958
StartNode(usingStatement);
1959
WriteKeyword(UsingStatement.UsingKeywordRole);
1960
Space(policy.SpaceBeforeUsingParentheses);
1962
Space(policy.SpacesWithinUsingParentheses);
1964
usingStatement.ResourceAcquisition.AcceptVisitor(this);
1966
Space(policy.SpacesWithinUsingParentheses);
1969
WriteEmbeddedStatement(usingStatement.EmbeddedStatement);
1971
EndNode(usingStatement);
1974
public void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement)
1976
StartNode(variableDeclarationStatement);
1977
WriteModifiers(variableDeclarationStatement.GetChildrenByRole(VariableDeclarationStatement.ModifierRole));
1978
variableDeclarationStatement.Type.AcceptVisitor(this);
1980
WriteCommaSeparatedList(variableDeclarationStatement.Variables);
1982
EndNode(variableDeclarationStatement);
1985
public void VisitWhileStatement(WhileStatement whileStatement)
1987
StartNode(whileStatement);
1988
WriteKeyword(WhileStatement.WhileKeywordRole);
1989
Space(policy.SpaceBeforeWhileParentheses);
1991
Space(policy.SpacesWithinWhileParentheses);
1992
whileStatement.Condition.AcceptVisitor(this);
1993
Space(policy.SpacesWithinWhileParentheses);
1995
WriteEmbeddedStatement(whileStatement.EmbeddedStatement);
1996
EndNode(whileStatement);
1999
public void VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement)
2001
StartNode(yieldBreakStatement);
2002
WriteKeyword(YieldBreakStatement.YieldKeywordRole);
2003
WriteKeyword(YieldBreakStatement.BreakKeywordRole);
2005
EndNode(yieldBreakStatement);
2008
public void VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement)
2010
StartNode(yieldReturnStatement);
2011
WriteKeyword(YieldReturnStatement.YieldKeywordRole);
2012
WriteKeyword(YieldReturnStatement.ReturnKeywordRole);
2014
yieldReturnStatement.Expression.AcceptVisitor(this);
2016
EndNode(yieldReturnStatement);
2022
public void VisitAccessor(Accessor accessor)
2024
StartNode(accessor);
2025
WriteAttributes(accessor.Attributes);
2026
WriteModifiers(accessor.ModifierTokens);
2027
if (accessor.Role == PropertyDeclaration.GetterRole) {
2028
WriteKeyword("get");
2029
} else if (accessor.Role == PropertyDeclaration.SetterRole) {
2030
WriteKeyword("set");
2031
} else if (accessor.Role == CustomEventDeclaration.AddAccessorRole) {
2032
WriteKeyword("add");
2033
} else if (accessor.Role == CustomEventDeclaration.RemoveAccessorRole) {
2034
WriteKeyword("remove");
2036
WriteMethodBody(accessor.Body);
2040
public void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
2042
StartNode(constructorDeclaration);
2043
WriteAttributes(constructorDeclaration.Attributes);
2044
WriteModifiers(constructorDeclaration.ModifierTokens);
2045
TypeDeclaration type = constructorDeclaration.Parent as TypeDeclaration;
2046
var nameToken = constructorDeclaration.NameToken;
2047
if (!nameToken.IsNull)
2048
StartNode(nameToken);
2049
WriteIdentifier(type != null ? type.Name : constructorDeclaration.Name);
2050
if (!nameToken.IsNull)
2052
Space(policy.SpaceBeforeConstructorDeclarationParentheses);
2053
WriteCommaSeparatedListInParenthesis(constructorDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2054
if (!constructorDeclaration.Initializer.IsNull) {
2056
constructorDeclaration.Initializer.AcceptVisitor(this);
2058
WriteMethodBody(constructorDeclaration.Body);
2059
EndNode(constructorDeclaration);
2062
public void VisitConstructorInitializer(ConstructorInitializer constructorInitializer)
2064
StartNode(constructorInitializer);
2065
WriteToken(Roles.Colon);
2067
if (constructorInitializer.ConstructorInitializerType == ConstructorInitializerType.This) {
2068
WriteKeyword(ConstructorInitializer.ThisKeywordRole);
2070
WriteKeyword(ConstructorInitializer.BaseKeywordRole);
2072
Space(policy.SpaceBeforeMethodCallParentheses);
2073
WriteCommaSeparatedListInParenthesis(constructorInitializer.Arguments, policy.SpaceWithinMethodCallParentheses);
2074
EndNode(constructorInitializer);
2077
public void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)
2079
StartNode(destructorDeclaration);
2080
WriteAttributes(destructorDeclaration.Attributes);
2081
WriteModifiers(destructorDeclaration.ModifierTokens);
2082
WriteToken(DestructorDeclaration.TildeRole);
2083
TypeDeclaration type = destructorDeclaration.Parent as TypeDeclaration;
2084
var nameToken = destructorDeclaration.NameToken;
2085
if (!nameToken.IsNull)
2086
StartNode(nameToken);
2087
WriteIdentifier(type != null ? type.Name : destructorDeclaration.Name);
2088
if (!nameToken.IsNull)
2090
Space(policy.SpaceBeforeConstructorDeclarationParentheses);
2093
WriteMethodBody(destructorDeclaration.Body);
2094
EndNode(destructorDeclaration);
2097
public void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration)
2099
StartNode(enumMemberDeclaration);
2100
WriteAttributes(enumMemberDeclaration.Attributes);
2101
WriteModifiers(enumMemberDeclaration.ModifierTokens);
2102
enumMemberDeclaration.NameToken.AcceptVisitor(this);
2103
if (!enumMemberDeclaration.Initializer.IsNull) {
2104
Space(policy.SpaceAroundAssignment);
2105
WriteToken(Roles.Assign);
2106
Space(policy.SpaceAroundAssignment);
2107
enumMemberDeclaration.Initializer.AcceptVisitor(this);
2109
EndNode(enumMemberDeclaration);
2112
public void VisitEventDeclaration(EventDeclaration eventDeclaration)
2114
StartNode(eventDeclaration);
2115
WriteAttributes(eventDeclaration.Attributes);
2116
WriteModifiers(eventDeclaration.ModifierTokens);
2117
WriteKeyword(EventDeclaration.EventKeywordRole);
2118
eventDeclaration.ReturnType.AcceptVisitor(this);
2120
WriteCommaSeparatedList(eventDeclaration.Variables);
2122
EndNode(eventDeclaration);
2125
public void VisitCustomEventDeclaration(CustomEventDeclaration customEventDeclaration)
2127
StartNode(customEventDeclaration);
2128
WriteAttributes(customEventDeclaration.Attributes);
2129
WriteModifiers(customEventDeclaration.ModifierTokens);
2130
WriteKeyword(CustomEventDeclaration.EventKeywordRole);
2131
customEventDeclaration.ReturnType.AcceptVisitor(this);
2133
WritePrivateImplementationType(customEventDeclaration.PrivateImplementationType);
2134
customEventDeclaration.NameToken.AcceptVisitor(this);
2135
OpenBrace(policy.EventBraceStyle);
2136
// output add/remove in their original order
2137
foreach (AstNode node in customEventDeclaration.Children) {
2138
if (node.Role == CustomEventDeclaration.AddAccessorRole || node.Role == CustomEventDeclaration.RemoveAccessorRole) {
2139
node.AcceptVisitor(this);
2142
CloseBrace(policy.EventBraceStyle);
2144
EndNode(customEventDeclaration);
2147
public void VisitFieldDeclaration(FieldDeclaration fieldDeclaration)
2149
StartNode(fieldDeclaration);
2150
WriteAttributes(fieldDeclaration.Attributes);
2151
WriteModifiers(fieldDeclaration.ModifierTokens);
2152
fieldDeclaration.ReturnType.AcceptVisitor(this);
2154
WriteCommaSeparatedList(fieldDeclaration.Variables);
2156
EndNode(fieldDeclaration);
2159
public void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration)
2161
StartNode(fixedFieldDeclaration);
2162
WriteAttributes(fixedFieldDeclaration.Attributes);
2163
WriteModifiers(fixedFieldDeclaration.ModifierTokens);
2164
WriteKeyword(FixedFieldDeclaration.FixedKeywordRole);
2166
fixedFieldDeclaration.ReturnType.AcceptVisitor(this);
2168
WriteCommaSeparatedList(fixedFieldDeclaration.Variables);
2170
EndNode(fixedFieldDeclaration);
2173
public void VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer)
2175
StartNode(fixedVariableInitializer);
2176
fixedVariableInitializer.NameToken.AcceptVisitor(this);
2177
if (!fixedVariableInitializer.CountExpression.IsNull) {
2178
WriteToken(Roles.LBracket);
2179
Space(policy.SpacesWithinBrackets);
2180
fixedVariableInitializer.CountExpression.AcceptVisitor(this);
2181
Space(policy.SpacesWithinBrackets);
2182
WriteToken(Roles.RBracket);
2184
EndNode(fixedVariableInitializer);
2187
public void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
2189
StartNode(indexerDeclaration);
2190
WriteAttributes(indexerDeclaration.Attributes);
2191
WriteModifiers(indexerDeclaration.ModifierTokens);
2192
indexerDeclaration.ReturnType.AcceptVisitor(this);
2194
WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType);
2195
WriteKeyword(IndexerDeclaration.ThisKeywordRole);
2196
Space(policy.SpaceBeforeMethodDeclarationParentheses);
2197
WriteCommaSeparatedListInBrackets(indexerDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2198
OpenBrace(policy.PropertyBraceStyle);
2199
// output get/set in their original order
2200
foreach (AstNode node in indexerDeclaration.Children) {
2201
if (node.Role == IndexerDeclaration.GetterRole || node.Role == IndexerDeclaration.SetterRole) {
2202
node.AcceptVisitor(this);
2205
CloseBrace(policy.PropertyBraceStyle);
2207
EndNode(indexerDeclaration);
2210
public void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
2212
StartNode(methodDeclaration);
2213
WriteAttributes(methodDeclaration.Attributes);
2214
WriteModifiers(methodDeclaration.ModifierTokens);
2215
methodDeclaration.ReturnType.AcceptVisitor(this);
2217
WritePrivateImplementationType(methodDeclaration.PrivateImplementationType);
2218
methodDeclaration.NameToken.AcceptVisitor(this);
2219
WriteTypeParameters(methodDeclaration.TypeParameters);
2220
Space(policy.SpaceBeforeMethodDeclarationParentheses);
2221
WriteCommaSeparatedListInParenthesis(methodDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2222
foreach (Constraint constraint in methodDeclaration.Constraints) {
2223
constraint.AcceptVisitor(this);
2225
WriteMethodBody(methodDeclaration.Body);
2226
EndNode(methodDeclaration);
2229
public void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
2231
StartNode(operatorDeclaration);
2232
WriteAttributes(operatorDeclaration.Attributes);
2233
WriteModifiers(operatorDeclaration.ModifierTokens);
2234
if (operatorDeclaration.OperatorType == OperatorType.Explicit) {
2235
WriteKeyword(OperatorDeclaration.ExplicitRole);
2236
} else if (operatorDeclaration.OperatorType == OperatorType.Implicit) {
2237
WriteKeyword(OperatorDeclaration.ImplicitRole);
2239
operatorDeclaration.ReturnType.AcceptVisitor(this);
2241
WriteKeyword(OperatorDeclaration.OperatorKeywordRole);
2243
if (operatorDeclaration.OperatorType == OperatorType.Explicit
2244
|| operatorDeclaration.OperatorType == OperatorType.Implicit) {
2245
operatorDeclaration.ReturnType.AcceptVisitor(this);
2247
WriteToken(OperatorDeclaration.GetToken(operatorDeclaration.OperatorType), OperatorDeclaration.GetRole(operatorDeclaration.OperatorType));
2249
Space(policy.SpaceBeforeMethodDeclarationParentheses);
2250
WriteCommaSeparatedListInParenthesis(operatorDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2251
WriteMethodBody(operatorDeclaration.Body);
2252
EndNode(operatorDeclaration);
2255
public void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
2257
StartNode(parameterDeclaration);
2258
WriteAttributes(parameterDeclaration.Attributes);
2259
switch (parameterDeclaration.ParameterModifier) {
2260
case ParameterModifier.Ref:
2261
WriteKeyword(ParameterDeclaration.RefModifierRole);
2263
case ParameterModifier.Out:
2264
WriteKeyword(ParameterDeclaration.OutModifierRole);
2266
case ParameterModifier.Params:
2267
WriteKeyword(ParameterDeclaration.ParamsModifierRole);
2269
case ParameterModifier.This:
2270
WriteKeyword(ParameterDeclaration.ThisModifierRole);
2273
parameterDeclaration.Type.AcceptVisitor(this);
2274
if (!parameterDeclaration.Type.IsNull && !string.IsNullOrEmpty(parameterDeclaration.Name)) {
2277
if (!string.IsNullOrEmpty(parameterDeclaration.Name)) {
2278
parameterDeclaration.NameToken.AcceptVisitor(this);
2280
if (!parameterDeclaration.DefaultExpression.IsNull) {
2281
Space(policy.SpaceAroundAssignment);
2282
WriteToken(Roles.Assign);
2283
Space(policy.SpaceAroundAssignment);
2284
parameterDeclaration.DefaultExpression.AcceptVisitor(this);
2286
EndNode(parameterDeclaration);
2289
public void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
2291
StartNode(propertyDeclaration);
2292
WriteAttributes(propertyDeclaration.Attributes);
2293
WriteModifiers(propertyDeclaration.ModifierTokens);
2294
propertyDeclaration.ReturnType.AcceptVisitor(this);
2296
WritePrivateImplementationType(propertyDeclaration.PrivateImplementationType);
2297
propertyDeclaration.NameToken.AcceptVisitor(this);
2298
OpenBrace(policy.PropertyBraceStyle);
2299
// output get/set in their original order
2300
foreach (AstNode node in propertyDeclaration.Children) {
2301
if (node.Role == IndexerDeclaration.GetterRole || node.Role == IndexerDeclaration.SetterRole) {
2302
node.AcceptVisitor(this);
2305
CloseBrace(policy.PropertyBraceStyle);
2307
EndNode(propertyDeclaration);
2313
public void VisitVariableInitializer(VariableInitializer variableInitializer)
2315
StartNode(variableInitializer);
2316
variableInitializer.NameToken.AcceptVisitor(this);
2317
if (!variableInitializer.Initializer.IsNull) {
2318
Space(policy.SpaceAroundAssignment);
2319
WriteToken(Roles.Assign);
2320
Space(policy.SpaceAroundAssignment);
2321
variableInitializer.Initializer.AcceptVisitor(this);
2323
EndNode(variableInitializer);
2326
public void VisitSyntaxTree(SyntaxTree syntaxTree)
2328
// don't do node tracking as we visit all children directly
2329
foreach (AstNode node in syntaxTree.Children) {
2330
node.AcceptVisitor(this);
2334
public void VisitSimpleType(SimpleType simpleType)
2336
StartNode(simpleType);
2337
WriteIdentifier(simpleType.Identifier);
2338
WriteTypeArguments(simpleType.TypeArguments);
2339
EndNode(simpleType);
2342
public void VisitMemberType(MemberType memberType)
2344
StartNode(memberType);
2345
memberType.Target.AcceptVisitor(this);
2346
if (memberType.IsDoubleColon) {
2347
WriteToken(Roles.DoubleColon);
2349
WriteToken(Roles.Dot);
2351
WriteIdentifier(memberType.MemberName);
2352
WriteTypeArguments(memberType.TypeArguments);
2353
EndNode(memberType);
2356
public void VisitComposedType(ComposedType composedType)
2358
StartNode(composedType);
2359
composedType.BaseType.AcceptVisitor(this);
2360
if (composedType.HasNullableSpecifier) {
2361
WriteToken(ComposedType.NullableRole);
2363
for (int i = 0; i < composedType.PointerRank; i++) {
2364
WriteToken(ComposedType.PointerRole);
2366
foreach (var node in composedType.ArraySpecifiers) {
2367
node.AcceptVisitor(this);
2369
EndNode(composedType);
2372
public void VisitArraySpecifier(ArraySpecifier arraySpecifier)
2374
StartNode(arraySpecifier);
2375
WriteToken(Roles.LBracket);
2376
foreach (var comma in arraySpecifier.GetChildrenByRole(Roles.Comma)) {
2377
WriteSpecialsUpToNode(comma);
2378
formatter.WriteToken(",");
2379
lastWritten = LastWritten.Other;
2381
WriteToken(Roles.RBracket);
2382
EndNode(arraySpecifier);
2385
public void VisitPrimitiveType(PrimitiveType primitiveType)
2387
StartNode(primitiveType);
2388
WriteKeyword(primitiveType.Keyword);
2389
if (primitiveType.Keyword == "new") {
2394
EndNode(primitiveType);
2397
public void VisitComment(Comment comment)
2399
if (lastWritten == LastWritten.Division) {
2400
// When there's a comment starting after a division operator
2401
// "1.0 / /*comment*/a", then we need to insert a space in front of the comment.
2404
formatter.StartNode(comment);
2405
formatter.WriteComment(comment.CommentType, comment.Content);
2406
formatter.EndNode(comment);
2407
lastWritten = LastWritten.Whitespace;
2410
public void VisitNewLine(NewLineNode newLineNode)
2412
// formatter.StartNode(newLineNode);
2413
// formatter.NewLine();
2414
// formatter.EndNode(newLineNode);
2417
public void VisitWhitespace(WhitespaceNode whitespaceNode)
2422
public void VisitText(TextNode textNode)
2427
public void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective)
2429
formatter.StartNode(preProcessorDirective);
2430
formatter.WritePreProcessorDirective(preProcessorDirective.Type, preProcessorDirective.Argument);
2431
formatter.EndNode(preProcessorDirective);
2432
lastWritten = LastWritten.Whitespace;
2435
public void VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration)
2437
StartNode(typeParameterDeclaration);
2438
WriteAttributes(typeParameterDeclaration.Attributes);
2439
switch (typeParameterDeclaration.Variance) {
2440
case VarianceModifier.Invariant:
2442
case VarianceModifier.Covariant:
2443
WriteKeyword(TypeParameterDeclaration.OutVarianceKeywordRole);
2445
case VarianceModifier.Contravariant:
2446
WriteKeyword(TypeParameterDeclaration.InVarianceKeywordRole);
2449
throw new NotSupportedException ("Invalid value for VarianceModifier");
2451
typeParameterDeclaration.NameToken.AcceptVisitor(this);
2452
EndNode(typeParameterDeclaration);
2455
public void VisitConstraint(Constraint constraint)
2457
StartNode(constraint);
2459
WriteKeyword(Roles.WhereKeyword);
2460
WriteIdentifier(constraint.TypeParameter.Identifier);
2462
WriteToken(Roles.Colon);
2464
WriteCommaSeparatedList(constraint.BaseTypes);
2465
EndNode(constraint);
2468
public void VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode)
2470
CSharpModifierToken mod = cSharpTokenNode as CSharpModifierToken;
2473
WriteKeyword(CSharpModifierToken.GetModifierName(mod.Modifier));
2476
throw new NotSupportedException ("Should never visit individual tokens");
2480
public void VisitIdentifier(Identifier identifier)
2482
StartNode(identifier);
2483
WriteIdentifier(identifier.Name);
2484
EndNode(identifier);
2489
#region Pattern Nodes
2490
public void VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern)
2492
StartNode(placeholder);
2493
VisitNodeInPattern(pattern);
2494
EndNode(placeholder);
2497
void VisitAnyNode(AnyNode anyNode)
2499
if (!string.IsNullOrEmpty(anyNode.GroupName)) {
2500
WriteIdentifier(anyNode.GroupName);
2501
WriteToken(Roles.Colon);
2505
void VisitBackreference(Backreference backreference)
2507
WriteKeyword("backreference");
2509
WriteIdentifier(backreference.ReferencedGroupName);
2513
void VisitIdentifierExpressionBackreference(IdentifierExpressionBackreference identifierExpressionBackreference)
2515
WriteKeyword("identifierBackreference");
2517
WriteIdentifier(identifierExpressionBackreference.ReferencedGroupName);
2521
void VisitChoice(Choice choice)
2523
WriteKeyword("choice");
2528
foreach (INode alternative in choice) {
2529
VisitNodeInPattern(alternative);
2530
if (alternative != choice.Last()) {
2531
WriteToken(Roles.Comma);
2535
formatter.Unindent();
2539
void VisitNamedNode(NamedNode namedNode)
2541
if (!string.IsNullOrEmpty(namedNode.GroupName)) {
2542
WriteIdentifier(namedNode.GroupName);
2543
WriteToken(Roles.Colon);
2545
VisitNodeInPattern(namedNode.ChildNode);
2548
void VisitRepeat(Repeat repeat)
2550
WriteKeyword("repeat");
2552
if (repeat.MinCount != 0 || repeat.MaxCount != int.MaxValue) {
2553
WriteIdentifier(repeat.MinCount.ToString());
2554
WriteToken(Roles.Comma);
2555
WriteIdentifier(repeat.MaxCount.ToString());
2556
WriteToken(Roles.Comma);
2558
VisitNodeInPattern(repeat.ChildNode);
2562
void VisitOptionalNode(OptionalNode optionalNode)
2564
WriteKeyword("optional");
2566
VisitNodeInPattern(optionalNode.ChildNode);
2570
void VisitNodeInPattern(INode childNode)
2572
if (childNode is AstNode) {
2573
((AstNode)childNode).AcceptVisitor(this);
2574
} else if (childNode is IdentifierExpressionBackreference) {
2575
VisitIdentifierExpressionBackreference((IdentifierExpressionBackreference)childNode);
2576
} else if (childNode is Choice) {
2577
VisitChoice((Choice)childNode);
2578
} else if (childNode is AnyNode) {
2579
VisitAnyNode((AnyNode)childNode);
2580
} else if (childNode is Backreference) {
2581
VisitBackreference((Backreference)childNode);
2582
} else if (childNode is NamedNode) {
2583
VisitNamedNode((NamedNode)childNode);
2584
} else if (childNode is OptionalNode) {
2585
VisitOptionalNode((OptionalNode)childNode);
2586
} else if (childNode is Repeat) {
2587
VisitRepeat((Repeat)childNode);
2589
WritePrimitiveValue(childNode);
2594
#region Documentation Reference
2595
public void VisitDocumentationReference(DocumentationReference documentationReference)
2597
StartNode(documentationReference);
2598
if (!documentationReference.DeclaringType.IsNull) {
2599
documentationReference.DeclaringType.AcceptVisitor(this);
2600
if (documentationReference.EntityType != EntityType.TypeDefinition) {
2601
WriteToken(Roles.Dot);
2604
switch (documentationReference.EntityType) {
2605
case EntityType.TypeDefinition:
2606
// we already printed the DeclaringType
2608
case EntityType.Indexer:
2609
WriteKeyword(IndexerDeclaration.ThisKeywordRole);
2611
case EntityType.Operator:
2612
var opType = documentationReference.OperatorType;
2613
if (opType == OperatorType.Explicit) {
2614
WriteKeyword(OperatorDeclaration.ExplicitRole);
2615
} else if (opType == OperatorType.Implicit) {
2616
WriteKeyword(OperatorDeclaration.ImplicitRole);
2618
WriteKeyword(OperatorDeclaration.OperatorKeywordRole);
2620
if (opType == OperatorType.Explicit || opType == OperatorType.Implicit) {
2621
documentationReference.ConversionOperatorReturnType.AcceptVisitor(this);
2623
WriteToken(OperatorDeclaration.GetToken(opType), OperatorDeclaration.GetRole(opType));
2627
WriteIdentifier(documentationReference.MemberName);
2630
WriteTypeArguments(documentationReference.TypeArguments);
2631
if (documentationReference.HasParameterList) {
2632
Space(policy.SpaceBeforeMethodDeclarationParentheses);
2633
if (documentationReference.EntityType == EntityType.Indexer) {
2634
WriteCommaSeparatedListInBrackets(documentationReference.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2636
WriteCommaSeparatedListInParenthesis(documentationReference.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2639
EndNode(documentationReference);