1
// Copyright (c) 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
void WritePrimitiveValue(object val)
1013
// usually NullReferenceExpression should be used for this, but we'll handle it anyways
1014
WriteKeyword("null");
1020
WriteKeyword("true");
1022
WriteKeyword("false");
1027
if (val is string) {
1028
formatter.WriteToken("\"" + ConvertString(val.ToString()) + "\"");
1029
lastWritten = LastWritten.Other;
1030
} else if (val is char) {
1031
formatter.WriteToken("'" + ConvertCharLiteral((char)val) + "'");
1032
lastWritten = LastWritten.Other;
1033
} else if (val is decimal) {
1034
formatter.WriteToken(((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m");
1035
lastWritten = LastWritten.Other;
1036
} else if (val is float) {
1037
float f = (float)val;
1038
if (float.IsInfinity(f) || float.IsNaN(f)) {
1039
// Strictly speaking, these aren't PrimitiveExpressions;
1040
// but we still support writing these to make life easier for code generators.
1041
WriteKeyword("float");
1042
WriteToken(Roles.Dot);
1043
if (float.IsPositiveInfinity(f)) {
1044
WriteIdentifier("PositiveInfinity");
1045
} else if (float.IsNegativeInfinity(f)) {
1046
WriteIdentifier("NegativeInfinity");
1048
WriteIdentifier("NaN");
1052
formatter.WriteToken(f.ToString("R", NumberFormatInfo.InvariantInfo) + "f");
1053
lastWritten = LastWritten.Other;
1054
} else if (val is double) {
1055
double f = (double)val;
1056
if (double.IsInfinity(f) || double.IsNaN(f)) {
1057
// Strictly speaking, these aren't PrimitiveExpressions;
1058
// but we still support writing these to make life easier for code generators.
1059
WriteKeyword("double");
1060
WriteToken(Roles.Dot);
1061
if (double.IsPositiveInfinity(f)) {
1062
WriteIdentifier("PositiveInfinity");
1063
} else if (double.IsNegativeInfinity(f)) {
1064
WriteIdentifier("NegativeInfinity");
1066
WriteIdentifier("NaN");
1070
string number = f.ToString("R", NumberFormatInfo.InvariantInfo);
1071
if (number.IndexOf('.') < 0 && number.IndexOf('E') < 0) {
1074
formatter.WriteToken(number);
1075
// needs space if identifier follows number; this avoids mistaking the following identifier as type suffix
1076
lastWritten = LastWritten.KeywordOrIdentifier;
1077
} else if (val is IFormattable) {
1078
StringBuilder b = new StringBuilder ();
1079
// if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) {
1081
// b.Append(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo));
1083
b.Append(((IFormattable)val).ToString(null, NumberFormatInfo.InvariantInfo));
1085
if (val is uint || val is ulong) {
1088
if (val is long || val is ulong) {
1091
formatter.WriteToken(b.ToString());
1092
// needs space if identifier follows number; this avoids mistaking the following identifier as type suffix
1093
lastWritten = LastWritten.KeywordOrIdentifier;
1095
formatter.WriteToken(val.ToString());
1096
lastWritten = LastWritten.Other;
1100
static string ConvertCharLiteral(char ch)
1105
return ConvertChar(ch);
1109
/// Gets the escape sequence for the specified character.
1111
/// <remarks>This method does not convert ' or ".</remarks>
1112
public static string ConvertChar(char ch)
1134
if (char.IsControl(ch) || char.IsSurrogate(ch) ||
1135
// print all uncommon white spaces as numbers
1136
(char.IsWhiteSpace(ch) && ch != ' ')) {
1137
return "\\u" + ((int)ch).ToString("x4");
1139
return ch.ToString();
1145
/// Converts special characters to escape sequences within the given string.
1147
public static string ConvertString(string str)
1149
StringBuilder sb = new StringBuilder ();
1150
foreach (char ch in str) {
1154
sb.Append(ConvertChar(ch));
1157
return sb.ToString();
1162
public void VisitSizeOfExpression(SizeOfExpression sizeOfExpression)
1164
StartNode(sizeOfExpression);
1166
WriteKeyword(SizeOfExpression.SizeofKeywordRole);
1168
Space(policy.SpacesWithinSizeOfParentheses);
1169
sizeOfExpression.Type.AcceptVisitor(this);
1170
Space(policy.SpacesWithinSizeOfParentheses);
1173
EndNode(sizeOfExpression);
1176
public void VisitStackAllocExpression(StackAllocExpression stackAllocExpression)
1178
StartNode(stackAllocExpression);
1179
WriteKeyword(StackAllocExpression.StackallocKeywordRole);
1180
stackAllocExpression.Type.AcceptVisitor(this);
1181
WriteCommaSeparatedListInBrackets(new[] { stackAllocExpression.CountExpression });
1182
EndNode(stackAllocExpression);
1185
public void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
1187
StartNode(thisReferenceExpression);
1188
WriteKeyword("this", thisReferenceExpression.Role);
1189
EndNode(thisReferenceExpression);
1192
public void VisitTypeOfExpression(TypeOfExpression typeOfExpression)
1194
StartNode(typeOfExpression);
1196
WriteKeyword(TypeOfExpression.TypeofKeywordRole);
1198
Space(policy.SpacesWithinTypeOfParentheses);
1199
typeOfExpression.Type.AcceptVisitor(this);
1200
Space(policy.SpacesWithinTypeOfParentheses);
1203
EndNode(typeOfExpression);
1206
public void VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression)
1208
StartNode(typeReferenceExpression);
1209
typeReferenceExpression.Type.AcceptVisitor(this);
1210
EndNode(typeReferenceExpression);
1213
public void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
1215
StartNode(unaryOperatorExpression);
1216
UnaryOperatorType opType = unaryOperatorExpression.Operator;
1217
var opSymbol = UnaryOperatorExpression.GetOperatorRole(opType);
1218
if (opType == UnaryOperatorType.Await) {
1219
WriteKeyword(opSymbol);
1220
} else if (!(opType == UnaryOperatorType.PostIncrement || opType == UnaryOperatorType.PostDecrement)) {
1221
WriteToken(opSymbol);
1223
unaryOperatorExpression.Expression.AcceptVisitor(this);
1224
if (opType == UnaryOperatorType.PostIncrement || opType == UnaryOperatorType.PostDecrement) {
1225
WriteToken(opSymbol);
1227
EndNode(unaryOperatorExpression);
1230
public void VisitUncheckedExpression(UncheckedExpression uncheckedExpression)
1232
StartNode(uncheckedExpression);
1233
WriteKeyword(UncheckedExpression.UncheckedKeywordRole);
1235
Space(policy.SpacesWithinCheckedExpressionParantheses);
1236
uncheckedExpression.Expression.AcceptVisitor(this);
1237
Space(policy.SpacesWithinCheckedExpressionParantheses);
1239
EndNode(uncheckedExpression);
1244
#region Query Expressions
1245
public void VisitQueryExpression(QueryExpression queryExpression)
1247
StartNode(queryExpression);
1248
bool indent = !(queryExpression.Parent is QueryContinuationClause);
1254
foreach (var clause in queryExpression.Clauses) {
1258
if (!(clause is QueryContinuationClause)) {
1262
clause.AcceptVisitor(this);
1265
formatter.Unindent();
1267
EndNode(queryExpression);
1270
public void VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause)
1272
StartNode(queryContinuationClause);
1273
queryContinuationClause.PrecedingQuery.AcceptVisitor(this);
1275
WriteKeyword(QueryContinuationClause.IntoKeywordRole);
1277
queryContinuationClause.IdentifierToken.AcceptVisitor(this);
1278
EndNode(queryContinuationClause);
1281
public void VisitQueryFromClause(QueryFromClause queryFromClause)
1283
StartNode(queryFromClause);
1284
WriteKeyword(QueryFromClause.FromKeywordRole);
1285
queryFromClause.Type.AcceptVisitor(this);
1287
queryFromClause.IdentifierToken.AcceptVisitor(this);
1289
WriteKeyword(QueryFromClause.InKeywordRole);
1291
queryFromClause.Expression.AcceptVisitor(this);
1292
EndNode(queryFromClause);
1295
public void VisitQueryLetClause(QueryLetClause queryLetClause)
1297
StartNode(queryLetClause);
1298
WriteKeyword(QueryLetClause.LetKeywordRole);
1300
queryLetClause.IdentifierToken.AcceptVisitor(this);
1301
Space(policy.SpaceAroundAssignment);
1302
WriteToken(Roles.Assign);
1303
Space(policy.SpaceAroundAssignment);
1304
queryLetClause.Expression.AcceptVisitor(this);
1305
EndNode(queryLetClause);
1308
public void VisitQueryWhereClause(QueryWhereClause queryWhereClause)
1310
StartNode(queryWhereClause);
1311
WriteKeyword(QueryWhereClause.WhereKeywordRole);
1313
queryWhereClause.Condition.AcceptVisitor(this);
1314
EndNode(queryWhereClause);
1317
public void VisitQueryJoinClause(QueryJoinClause queryJoinClause)
1319
StartNode(queryJoinClause);
1320
WriteKeyword(QueryJoinClause.JoinKeywordRole);
1321
queryJoinClause.Type.AcceptVisitor(this);
1323
WriteIdentifier(queryJoinClause.JoinIdentifier, QueryJoinClause.JoinIdentifierRole);
1325
WriteKeyword(QueryJoinClause.InKeywordRole);
1327
queryJoinClause.InExpression.AcceptVisitor(this);
1329
WriteKeyword(QueryJoinClause.OnKeywordRole);
1331
queryJoinClause.OnExpression.AcceptVisitor(this);
1333
WriteKeyword(QueryJoinClause.EqualsKeywordRole);
1335
queryJoinClause.EqualsExpression.AcceptVisitor(this);
1336
if (queryJoinClause.IsGroupJoin) {
1338
WriteKeyword(QueryJoinClause.IntoKeywordRole);
1339
WriteIdentifier(queryJoinClause.IntoIdentifier, QueryJoinClause.IntoIdentifierRole);
1341
EndNode(queryJoinClause);
1344
public void VisitQueryOrderClause(QueryOrderClause queryOrderClause)
1346
StartNode(queryOrderClause);
1347
WriteKeyword(QueryOrderClause.OrderbyKeywordRole);
1349
WriteCommaSeparatedList(queryOrderClause.Orderings);
1350
EndNode(queryOrderClause);
1353
public void VisitQueryOrdering(QueryOrdering queryOrdering)
1355
StartNode(queryOrdering);
1356
queryOrdering.Expression.AcceptVisitor(this);
1357
switch (queryOrdering.Direction) {
1358
case QueryOrderingDirection.Ascending:
1360
WriteKeyword(QueryOrdering.AscendingKeywordRole);
1362
case QueryOrderingDirection.Descending:
1364
WriteKeyword(QueryOrdering.DescendingKeywordRole);
1367
EndNode(queryOrdering);
1370
public void VisitQuerySelectClause(QuerySelectClause querySelectClause)
1372
StartNode(querySelectClause);
1373
WriteKeyword(QuerySelectClause.SelectKeywordRole);
1375
querySelectClause.Expression.AcceptVisitor(this);
1376
EndNode(querySelectClause);
1379
public void VisitQueryGroupClause(QueryGroupClause queryGroupClause)
1381
StartNode(queryGroupClause);
1382
WriteKeyword(QueryGroupClause.GroupKeywordRole);
1384
queryGroupClause.Projection.AcceptVisitor(this);
1386
WriteKeyword(QueryGroupClause.ByKeywordRole);
1388
queryGroupClause.Key.AcceptVisitor(this);
1389
EndNode(queryGroupClause);
1394
#region GeneralScope
1395
public void VisitAttribute(Attribute attribute)
1397
StartNode(attribute);
1398
attribute.Type.AcceptVisitor(this);
1399
if (attribute.Arguments.Count != 0 || !attribute.GetChildByRole(Roles.LPar).IsNull) {
1400
Space(policy.SpaceBeforeMethodCallParentheses);
1401
WriteCommaSeparatedListInParenthesis(attribute.Arguments, policy.SpaceWithinMethodCallParentheses);
1406
public void VisitAttributeSection(AttributeSection attributeSection)
1408
StartNode(attributeSection);
1409
WriteToken(Roles.LBracket);
1410
if (!string.IsNullOrEmpty(attributeSection.AttributeTarget)) {
1411
WriteToken(attributeSection.AttributeTarget, Roles.AttributeTargetRole);
1412
WriteToken(Roles.Colon);
1415
WriteCommaSeparatedList(attributeSection.Attributes);
1416
WriteToken(Roles.RBracket);
1417
if (attributeSection.Parent is ParameterDeclaration || attributeSection.Parent is TypeParameterDeclaration) {
1422
EndNode(attributeSection);
1425
public void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)
1427
StartNode(delegateDeclaration);
1428
WriteAttributes(delegateDeclaration.Attributes);
1429
WriteModifiers(delegateDeclaration.ModifierTokens);
1430
WriteKeyword(Roles.DelegateKeyword);
1431
delegateDeclaration.ReturnType.AcceptVisitor(this);
1433
delegateDeclaration.NameToken.AcceptVisitor(this);
1434
WriteTypeParameters(delegateDeclaration.TypeParameters);
1435
Space(policy.SpaceBeforeDelegateDeclarationParentheses);
1436
WriteCommaSeparatedListInParenthesis(delegateDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
1437
foreach (Constraint constraint in delegateDeclaration.Constraints) {
1438
constraint.AcceptVisitor(this);
1441
EndNode(delegateDeclaration);
1444
public void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
1446
StartNode(namespaceDeclaration);
1447
WriteKeyword(Roles.NamespaceKeyword);
1448
WriteQualifiedIdentifier(namespaceDeclaration.Identifiers);
1449
OpenBrace(policy.NamespaceBraceStyle);
1450
foreach (var member in namespaceDeclaration.Members) {
1451
member.AcceptVisitor(this);
1453
CloseBrace(policy.NamespaceBraceStyle);
1454
OptionalSemicolon();
1456
EndNode(namespaceDeclaration);
1459
public void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
1461
StartNode(typeDeclaration);
1462
WriteAttributes(typeDeclaration.Attributes);
1463
WriteModifiers(typeDeclaration.ModifierTokens);
1464
BraceStyle braceStyle;
1465
switch (typeDeclaration.ClassType) {
1466
case ClassType.Enum:
1467
WriteKeyword(Roles.EnumKeyword);
1468
braceStyle = policy.EnumBraceStyle;
1470
case ClassType.Interface:
1471
WriteKeyword(Roles.InterfaceKeyword);
1472
braceStyle = policy.InterfaceBraceStyle;
1474
case ClassType.Struct:
1475
WriteKeyword(Roles.StructKeyword);
1476
braceStyle = policy.StructBraceStyle;
1479
WriteKeyword(Roles.ClassKeyword);
1480
braceStyle = policy.ClassBraceStyle;
1483
typeDeclaration.NameToken.AcceptVisitor(this);
1484
WriteTypeParameters(typeDeclaration.TypeParameters);
1485
if (typeDeclaration.BaseTypes.Any()) {
1487
WriteToken(Roles.Colon);
1489
WriteCommaSeparatedList(typeDeclaration.BaseTypes);
1491
foreach (Constraint constraint in typeDeclaration.Constraints) {
1492
constraint.AcceptVisitor(this);
1494
OpenBrace(braceStyle);
1495
if (typeDeclaration.ClassType == ClassType.Enum) {
1497
foreach (var member in typeDeclaration.Members) {
1501
Comma(member, noSpaceAfterComma: true);
1504
member.AcceptVisitor(this);
1509
foreach (var member in typeDeclaration.Members) {
1510
member.AcceptVisitor(this);
1513
CloseBrace(braceStyle);
1514
OptionalSemicolon();
1516
EndNode(typeDeclaration);
1519
public void VisitUsingAliasDeclaration(UsingAliasDeclaration usingAliasDeclaration)
1521
StartNode(usingAliasDeclaration);
1522
WriteKeyword(UsingAliasDeclaration.UsingKeywordRole);
1523
WriteIdentifier(usingAliasDeclaration.Alias, UsingAliasDeclaration.AliasRole);
1524
Space(policy.SpaceAroundEqualityOperator);
1525
WriteToken(Roles.Assign);
1526
Space(policy.SpaceAroundEqualityOperator);
1527
usingAliasDeclaration.Import.AcceptVisitor(this);
1529
EndNode(usingAliasDeclaration);
1532
public void VisitUsingDeclaration(UsingDeclaration usingDeclaration)
1534
StartNode(usingDeclaration);
1535
WriteKeyword(UsingDeclaration.UsingKeywordRole);
1536
usingDeclaration.Import.AcceptVisitor(this);
1538
EndNode(usingDeclaration);
1541
public void VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration)
1543
StartNode(externAliasDeclaration);
1544
WriteKeyword(Roles.ExternKeyword);
1546
WriteKeyword(Roles.AliasKeyword);
1548
externAliasDeclaration.NameToken.AcceptVisitor(this);
1550
EndNode(externAliasDeclaration);
1556
public void VisitBlockStatement(BlockStatement blockStatement)
1558
StartNode(blockStatement);
1560
if (blockStatement.Parent is AnonymousMethodExpression || blockStatement.Parent is LambdaExpression) {
1561
style = policy.AnonymousMethodBraceStyle;
1562
} else if (blockStatement.Parent is ConstructorDeclaration) {
1563
style = policy.ConstructorBraceStyle;
1564
} else if (blockStatement.Parent is DestructorDeclaration) {
1565
style = policy.DestructorBraceStyle;
1566
} else if (blockStatement.Parent is MethodDeclaration) {
1567
style = policy.MethodBraceStyle;
1568
} else if (blockStatement.Parent is Accessor) {
1569
if (blockStatement.Parent.Role == PropertyDeclaration.GetterRole) {
1570
style = policy.PropertyGetBraceStyle;
1571
} else if (blockStatement.Parent.Role == PropertyDeclaration.SetterRole) {
1572
style = policy.PropertySetBraceStyle;
1573
} else if (blockStatement.Parent.Role == CustomEventDeclaration.AddAccessorRole) {
1574
style = policy.EventAddBraceStyle;
1575
} else if (blockStatement.Parent.Role == CustomEventDeclaration.RemoveAccessorRole) {
1576
style = policy.EventRemoveBraceStyle;
1578
style = policy.StatementBraceStyle;
1581
style = policy.StatementBraceStyle;
1584
foreach (var node in blockStatement.Statements) {
1585
node.AcceptVisitor(this);
1588
if (!(blockStatement.Parent is Expression))
1590
EndNode(blockStatement);
1593
public void VisitBreakStatement(BreakStatement breakStatement)
1595
StartNode(breakStatement);
1596
WriteKeyword("break");
1598
EndNode(breakStatement);
1601
public void VisitCheckedStatement(CheckedStatement checkedStatement)
1603
StartNode(checkedStatement);
1604
WriteKeyword(CheckedStatement.CheckedKeywordRole);
1605
checkedStatement.Body.AcceptVisitor(this);
1606
EndNode(checkedStatement);
1609
public void VisitContinueStatement(ContinueStatement continueStatement)
1611
StartNode(continueStatement);
1612
WriteKeyword("continue");
1614
EndNode(continueStatement);
1617
public void VisitDoWhileStatement(DoWhileStatement doWhileStatement)
1619
StartNode(doWhileStatement);
1620
WriteKeyword(DoWhileStatement.DoKeywordRole);
1621
WriteEmbeddedStatement(doWhileStatement.EmbeddedStatement);
1622
WriteKeyword(DoWhileStatement.WhileKeywordRole);
1623
Space(policy.SpaceBeforeWhileParentheses);
1625
Space(policy.SpacesWithinWhileParentheses);
1626
doWhileStatement.Condition.AcceptVisitor(this);
1627
Space(policy.SpacesWithinWhileParentheses);
1630
EndNode(doWhileStatement);
1633
public void VisitEmptyStatement(EmptyStatement emptyStatement)
1635
StartNode(emptyStatement);
1637
EndNode(emptyStatement);
1640
public void VisitExpressionStatement(ExpressionStatement expressionStatement)
1642
StartNode(expressionStatement);
1643
expressionStatement.Expression.AcceptVisitor(this);
1645
EndNode(expressionStatement);
1648
public void VisitFixedStatement(FixedStatement fixedStatement)
1650
StartNode(fixedStatement);
1651
WriteKeyword(FixedStatement.FixedKeywordRole);
1652
Space(policy.SpaceBeforeUsingParentheses);
1654
Space(policy.SpacesWithinUsingParentheses);
1655
fixedStatement.Type.AcceptVisitor(this);
1657
WriteCommaSeparatedList(fixedStatement.Variables);
1658
Space(policy.SpacesWithinUsingParentheses);
1660
WriteEmbeddedStatement(fixedStatement.EmbeddedStatement);
1661
EndNode(fixedStatement);
1664
public void VisitForeachStatement(ForeachStatement foreachStatement)
1666
StartNode(foreachStatement);
1667
WriteKeyword(ForeachStatement.ForeachKeywordRole);
1668
Space(policy.SpaceBeforeForeachParentheses);
1670
Space(policy.SpacesWithinForeachParentheses);
1671
foreachStatement.VariableType.AcceptVisitor(this);
1673
foreachStatement.VariableNameToken.AcceptVisitor(this);
1674
WriteKeyword(ForeachStatement.InKeywordRole);
1676
foreachStatement.InExpression.AcceptVisitor(this);
1677
Space(policy.SpacesWithinForeachParentheses);
1679
WriteEmbeddedStatement(foreachStatement.EmbeddedStatement);
1680
EndNode(foreachStatement);
1683
public void VisitForStatement(ForStatement forStatement)
1685
StartNode(forStatement);
1686
WriteKeyword(ForStatement.ForKeywordRole);
1687
Space(policy.SpaceBeforeForParentheses);
1689
Space(policy.SpacesWithinForParentheses);
1691
WriteCommaSeparatedList(forStatement.Initializers);
1692
Space(policy.SpaceBeforeForSemicolon);
1693
WriteToken(Roles.Semicolon);
1694
Space(policy.SpaceAfterForSemicolon);
1696
forStatement.Condition.AcceptVisitor(this);
1697
Space(policy.SpaceBeforeForSemicolon);
1698
WriteToken(Roles.Semicolon);
1699
if (forStatement.Iterators.Any()) {
1700
Space(policy.SpaceAfterForSemicolon);
1701
WriteCommaSeparatedList(forStatement.Iterators);
1704
Space(policy.SpacesWithinForParentheses);
1706
WriteEmbeddedStatement(forStatement.EmbeddedStatement);
1707
EndNode(forStatement);
1710
public void VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement)
1712
StartNode(gotoCaseStatement);
1713
WriteKeyword(GotoCaseStatement.GotoKeywordRole);
1714
WriteKeyword(GotoCaseStatement.CaseKeywordRole);
1716
gotoCaseStatement.LabelExpression.AcceptVisitor(this);
1718
EndNode(gotoCaseStatement);
1721
public void VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement)
1723
StartNode(gotoDefaultStatement);
1724
WriteKeyword(GotoDefaultStatement.GotoKeywordRole);
1725
WriteKeyword(GotoDefaultStatement.DefaultKeywordRole);
1727
EndNode(gotoDefaultStatement);
1730
public void VisitGotoStatement(GotoStatement gotoStatement)
1732
StartNode(gotoStatement);
1733
WriteKeyword(GotoStatement.GotoKeywordRole);
1734
WriteIdentifier(gotoStatement.Label);
1736
EndNode(gotoStatement);
1739
public void VisitIfElseStatement(IfElseStatement ifElseStatement)
1741
StartNode(ifElseStatement);
1742
WriteKeyword(IfElseStatement.IfKeywordRole);
1743
Space(policy.SpaceBeforeIfParentheses);
1745
Space(policy.SpacesWithinIfParentheses);
1746
ifElseStatement.Condition.AcceptVisitor(this);
1747
Space(policy.SpacesWithinIfParentheses);
1749
WriteEmbeddedStatement(ifElseStatement.TrueStatement);
1750
if (!ifElseStatement.FalseStatement.IsNull) {
1751
WriteKeyword(IfElseStatement.ElseKeywordRole);
1752
WriteEmbeddedStatement(ifElseStatement.FalseStatement);
1754
EndNode(ifElseStatement);
1757
public void VisitLabelStatement(LabelStatement labelStatement)
1759
StartNode(labelStatement);
1760
WriteIdentifier(labelStatement.Label);
1761
WriteToken(Roles.Colon);
1762
bool foundLabelledStatement = false;
1763
for (AstNode tmp = labelStatement.NextSibling; tmp != null; tmp = tmp.NextSibling) {
1764
if (tmp.Role == labelStatement.Role) {
1765
foundLabelledStatement = true;
1768
if (!foundLabelledStatement) {
1769
// introduce an EmptyStatement so that the output becomes syntactically valid
1770
WriteToken(Roles.Semicolon);
1773
EndNode(labelStatement);
1776
public void VisitLockStatement(LockStatement lockStatement)
1778
StartNode(lockStatement);
1779
WriteKeyword(LockStatement.LockKeywordRole);
1780
Space(policy.SpaceBeforeLockParentheses);
1782
Space(policy.SpacesWithinLockParentheses);
1783
lockStatement.Expression.AcceptVisitor(this);
1784
Space(policy.SpacesWithinLockParentheses);
1786
WriteEmbeddedStatement(lockStatement.EmbeddedStatement);
1787
EndNode(lockStatement);
1790
public void VisitReturnStatement(ReturnStatement returnStatement)
1792
StartNode(returnStatement);
1793
WriteKeyword(ReturnStatement.ReturnKeywordRole);
1794
if (!returnStatement.Expression.IsNull) {
1796
returnStatement.Expression.AcceptVisitor(this);
1799
EndNode(returnStatement);
1802
public void VisitSwitchStatement(SwitchStatement switchStatement)
1804
StartNode(switchStatement);
1805
WriteKeyword(SwitchStatement.SwitchKeywordRole);
1806
Space(policy.SpaceBeforeSwitchParentheses);
1808
Space(policy.SpacesWithinSwitchParentheses);
1809
switchStatement.Expression.AcceptVisitor(this);
1810
Space(policy.SpacesWithinSwitchParentheses);
1812
OpenBrace(policy.StatementBraceStyle);
1813
if (!policy.IndentSwitchBody) {
1814
formatter.Unindent();
1817
foreach (var section in switchStatement.SwitchSections) {
1818
section.AcceptVisitor(this);
1821
if (!policy.IndentSwitchBody) {
1824
CloseBrace(policy.StatementBraceStyle);
1826
EndNode(switchStatement);
1829
public void VisitSwitchSection(SwitchSection switchSection)
1831
StartNode(switchSection);
1833
foreach (var label in switchSection.CaseLabels) {
1837
label.AcceptVisitor(this);
1840
bool isBlock = switchSection.Statements.Count == 1 && switchSection.Statements.Single() is BlockStatement;
1841
if (policy.IndentCaseBody && !isBlock) {
1848
foreach (var statement in switchSection.Statements) {
1849
statement.AcceptVisitor(this);
1852
if (policy.IndentCaseBody && !isBlock) {
1853
formatter.Unindent();
1856
EndNode(switchSection);
1859
public void VisitCaseLabel(CaseLabel caseLabel)
1861
StartNode(caseLabel);
1862
if (caseLabel.Expression.IsNull) {
1863
WriteKeyword(CaseLabel.DefaultKeywordRole);
1865
WriteKeyword(CaseLabel.CaseKeywordRole);
1867
caseLabel.Expression.AcceptVisitor(this);
1869
WriteToken(Roles.Colon);
1873
public void VisitThrowStatement(ThrowStatement throwStatement)
1875
StartNode(throwStatement);
1876
WriteKeyword(ThrowStatement.ThrowKeywordRole);
1877
if (!throwStatement.Expression.IsNull) {
1879
throwStatement.Expression.AcceptVisitor(this);
1882
EndNode(throwStatement);
1885
public void VisitTryCatchStatement(TryCatchStatement tryCatchStatement)
1887
StartNode(tryCatchStatement);
1888
WriteKeyword(TryCatchStatement.TryKeywordRole);
1889
tryCatchStatement.TryBlock.AcceptVisitor(this);
1890
foreach (var catchClause in tryCatchStatement.CatchClauses) {
1891
catchClause.AcceptVisitor(this);
1893
if (!tryCatchStatement.FinallyBlock.IsNull) {
1894
WriteKeyword(TryCatchStatement.FinallyKeywordRole);
1895
tryCatchStatement.FinallyBlock.AcceptVisitor(this);
1897
EndNode(tryCatchStatement);
1900
public void VisitCatchClause(CatchClause catchClause)
1902
StartNode(catchClause);
1903
WriteKeyword(CatchClause.CatchKeywordRole);
1904
if (!catchClause.Type.IsNull) {
1905
Space(policy.SpaceBeforeCatchParentheses);
1907
Space(policy.SpacesWithinCatchParentheses);
1908
catchClause.Type.AcceptVisitor(this);
1909
if (!string.IsNullOrEmpty(catchClause.VariableName)) {
1911
catchClause.VariableNameToken.AcceptVisitor(this);
1913
Space(policy.SpacesWithinCatchParentheses);
1916
catchClause.Body.AcceptVisitor(this);
1917
EndNode(catchClause);
1920
public void VisitUncheckedStatement(UncheckedStatement uncheckedStatement)
1922
StartNode(uncheckedStatement);
1923
WriteKeyword(UncheckedStatement.UncheckedKeywordRole);
1924
uncheckedStatement.Body.AcceptVisitor(this);
1925
EndNode(uncheckedStatement);
1928
public void VisitUnsafeStatement(UnsafeStatement unsafeStatement)
1930
StartNode(unsafeStatement);
1931
WriteKeyword(UnsafeStatement.UnsafeKeywordRole);
1932
unsafeStatement.Body.AcceptVisitor(this);
1933
EndNode(unsafeStatement);
1936
public void VisitUsingStatement(UsingStatement usingStatement)
1938
StartNode(usingStatement);
1939
WriteKeyword(UsingStatement.UsingKeywordRole);
1940
Space(policy.SpaceBeforeUsingParentheses);
1942
Space(policy.SpacesWithinUsingParentheses);
1944
usingStatement.ResourceAcquisition.AcceptVisitor(this);
1946
Space(policy.SpacesWithinUsingParentheses);
1949
WriteEmbeddedStatement(usingStatement.EmbeddedStatement);
1951
EndNode(usingStatement);
1954
public void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement)
1956
StartNode(variableDeclarationStatement);
1957
WriteModifiers(variableDeclarationStatement.GetChildrenByRole(VariableDeclarationStatement.ModifierRole));
1958
variableDeclarationStatement.Type.AcceptVisitor(this);
1960
WriteCommaSeparatedList(variableDeclarationStatement.Variables);
1962
EndNode(variableDeclarationStatement);
1965
public void VisitWhileStatement(WhileStatement whileStatement)
1967
StartNode(whileStatement);
1968
WriteKeyword(WhileStatement.WhileKeywordRole);
1969
Space(policy.SpaceBeforeWhileParentheses);
1971
Space(policy.SpacesWithinWhileParentheses);
1972
whileStatement.Condition.AcceptVisitor(this);
1973
Space(policy.SpacesWithinWhileParentheses);
1975
WriteEmbeddedStatement(whileStatement.EmbeddedStatement);
1976
EndNode(whileStatement);
1979
public void VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement)
1981
StartNode(yieldBreakStatement);
1982
WriteKeyword(YieldBreakStatement.YieldKeywordRole);
1983
WriteKeyword(YieldBreakStatement.BreakKeywordRole);
1985
EndNode(yieldBreakStatement);
1988
public void VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement)
1990
StartNode(yieldReturnStatement);
1991
WriteKeyword(YieldReturnStatement.YieldKeywordRole);
1992
WriteKeyword(YieldReturnStatement.ReturnKeywordRole);
1994
yieldReturnStatement.Expression.AcceptVisitor(this);
1996
EndNode(yieldReturnStatement);
2002
public void VisitAccessor(Accessor accessor)
2004
StartNode(accessor);
2005
WriteAttributes(accessor.Attributes);
2006
WriteModifiers(accessor.ModifierTokens);
2007
if (accessor.Role == PropertyDeclaration.GetterRole) {
2008
WriteKeyword("get");
2009
} else if (accessor.Role == PropertyDeclaration.SetterRole) {
2010
WriteKeyword("set");
2011
} else if (accessor.Role == CustomEventDeclaration.AddAccessorRole) {
2012
WriteKeyword("add");
2013
} else if (accessor.Role == CustomEventDeclaration.RemoveAccessorRole) {
2014
WriteKeyword("remove");
2016
WriteMethodBody(accessor.Body);
2020
public void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
2022
StartNode(constructorDeclaration);
2023
WriteAttributes(constructorDeclaration.Attributes);
2024
WriteModifiers(constructorDeclaration.ModifierTokens);
2025
TypeDeclaration type = constructorDeclaration.Parent as TypeDeclaration;
2026
StartNode(constructorDeclaration.NameToken);
2027
WriteIdentifier(type != null ? type.Name : constructorDeclaration.Name);
2028
EndNode(constructorDeclaration.NameToken);
2029
Space(policy.SpaceBeforeConstructorDeclarationParentheses);
2030
WriteCommaSeparatedListInParenthesis(constructorDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2031
if (!constructorDeclaration.Initializer.IsNull) {
2033
constructorDeclaration.Initializer.AcceptVisitor(this);
2035
WriteMethodBody(constructorDeclaration.Body);
2036
EndNode(constructorDeclaration);
2039
public void VisitConstructorInitializer(ConstructorInitializer constructorInitializer)
2041
StartNode(constructorInitializer);
2042
WriteToken(Roles.Colon);
2044
if (constructorInitializer.ConstructorInitializerType == ConstructorInitializerType.This) {
2045
WriteKeyword(ConstructorInitializer.ThisKeywordRole);
2047
WriteKeyword(ConstructorInitializer.BaseKeywordRole);
2049
Space(policy.SpaceBeforeMethodCallParentheses);
2050
WriteCommaSeparatedListInParenthesis(constructorInitializer.Arguments, policy.SpaceWithinMethodCallParentheses);
2051
EndNode(constructorInitializer);
2054
public void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)
2056
StartNode(destructorDeclaration);
2057
WriteAttributes(destructorDeclaration.Attributes);
2058
WriteModifiers(destructorDeclaration.ModifierTokens);
2059
WriteToken(DestructorDeclaration.TildeRole);
2060
TypeDeclaration type = destructorDeclaration.Parent as TypeDeclaration;
2061
StartNode(destructorDeclaration.NameToken);
2062
WriteIdentifier(type != null ? type.Name : destructorDeclaration.Name);
2063
EndNode(destructorDeclaration.NameToken);
2064
Space(policy.SpaceBeforeConstructorDeclarationParentheses);
2067
WriteMethodBody(destructorDeclaration.Body);
2068
EndNode(destructorDeclaration);
2071
public void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration)
2073
StartNode(enumMemberDeclaration);
2074
WriteAttributes(enumMemberDeclaration.Attributes);
2075
WriteModifiers(enumMemberDeclaration.ModifierTokens);
2076
enumMemberDeclaration.NameToken.AcceptVisitor(this);
2077
if (!enumMemberDeclaration.Initializer.IsNull) {
2078
Space(policy.SpaceAroundAssignment);
2079
WriteToken(Roles.Assign);
2080
Space(policy.SpaceAroundAssignment);
2081
enumMemberDeclaration.Initializer.AcceptVisitor(this);
2083
EndNode(enumMemberDeclaration);
2086
public void VisitEventDeclaration(EventDeclaration eventDeclaration)
2088
StartNode(eventDeclaration);
2089
WriteAttributes(eventDeclaration.Attributes);
2090
WriteModifiers(eventDeclaration.ModifierTokens);
2091
WriteKeyword(EventDeclaration.EventKeywordRole);
2092
eventDeclaration.ReturnType.AcceptVisitor(this);
2094
WriteCommaSeparatedList(eventDeclaration.Variables);
2096
EndNode(eventDeclaration);
2099
public void VisitCustomEventDeclaration(CustomEventDeclaration customEventDeclaration)
2101
StartNode(customEventDeclaration);
2102
WriteAttributes(customEventDeclaration.Attributes);
2103
WriteModifiers(customEventDeclaration.ModifierTokens);
2104
WriteKeyword(CustomEventDeclaration.EventKeywordRole);
2105
customEventDeclaration.ReturnType.AcceptVisitor(this);
2107
WritePrivateImplementationType(customEventDeclaration.PrivateImplementationType);
2108
customEventDeclaration.NameToken.AcceptVisitor(this);
2109
OpenBrace(policy.EventBraceStyle);
2110
// output add/remove in their original order
2111
foreach (AstNode node in customEventDeclaration.Children) {
2112
if (node.Role == CustomEventDeclaration.AddAccessorRole || node.Role == CustomEventDeclaration.RemoveAccessorRole) {
2113
node.AcceptVisitor(this);
2116
CloseBrace(policy.EventBraceStyle);
2118
EndNode(customEventDeclaration);
2121
public void VisitFieldDeclaration(FieldDeclaration fieldDeclaration)
2123
StartNode(fieldDeclaration);
2124
WriteAttributes(fieldDeclaration.Attributes);
2125
WriteModifiers(fieldDeclaration.ModifierTokens);
2126
fieldDeclaration.ReturnType.AcceptVisitor(this);
2128
WriteCommaSeparatedList(fieldDeclaration.Variables);
2130
EndNode(fieldDeclaration);
2133
public void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration)
2135
StartNode(fixedFieldDeclaration);
2136
WriteAttributes(fixedFieldDeclaration.Attributes);
2137
WriteModifiers(fixedFieldDeclaration.ModifierTokens);
2138
WriteKeyword(FixedFieldDeclaration.FixedKeywordRole);
2140
fixedFieldDeclaration.ReturnType.AcceptVisitor(this);
2142
WriteCommaSeparatedList(fixedFieldDeclaration.Variables);
2144
EndNode(fixedFieldDeclaration);
2147
public void VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer)
2149
StartNode(fixedVariableInitializer);
2150
fixedVariableInitializer.NameToken.AcceptVisitor(this);
2151
if (!fixedVariableInitializer.CountExpression.IsNull) {
2152
WriteToken(Roles.LBracket);
2153
Space(policy.SpacesWithinBrackets);
2154
fixedVariableInitializer.CountExpression.AcceptVisitor(this);
2155
Space(policy.SpacesWithinBrackets);
2156
WriteToken(Roles.RBracket);
2158
EndNode(fixedVariableInitializer);
2161
public void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
2163
StartNode(indexerDeclaration);
2164
WriteAttributes(indexerDeclaration.Attributes);
2165
WriteModifiers(indexerDeclaration.ModifierTokens);
2166
indexerDeclaration.ReturnType.AcceptVisitor(this);
2167
WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType);
2168
WriteKeyword(IndexerDeclaration.ThisKeywordRole);
2169
Space(policy.SpaceBeforeMethodDeclarationParentheses);
2170
WriteCommaSeparatedListInBrackets(indexerDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2171
OpenBrace(policy.PropertyBraceStyle);
2172
// output get/set in their original order
2173
foreach (AstNode node in indexerDeclaration.Children) {
2174
if (node.Role == IndexerDeclaration.GetterRole || node.Role == IndexerDeclaration.SetterRole) {
2175
node.AcceptVisitor(this);
2178
CloseBrace(policy.PropertyBraceStyle);
2180
EndNode(indexerDeclaration);
2183
public void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
2185
StartNode(methodDeclaration);
2186
WriteAttributes(methodDeclaration.Attributes);
2187
WriteModifiers(methodDeclaration.ModifierTokens);
2188
methodDeclaration.ReturnType.AcceptVisitor(this);
2190
WritePrivateImplementationType(methodDeclaration.PrivateImplementationType);
2191
methodDeclaration.NameToken.AcceptVisitor(this);
2192
WriteTypeParameters(methodDeclaration.TypeParameters);
2193
Space(policy.SpaceBeforeMethodDeclarationParentheses);
2194
WriteCommaSeparatedListInParenthesis(methodDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2195
foreach (Constraint constraint in methodDeclaration.Constraints) {
2196
constraint.AcceptVisitor(this);
2198
WriteMethodBody(methodDeclaration.Body);
2199
EndNode(methodDeclaration);
2202
public void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
2204
StartNode(operatorDeclaration);
2205
WriteAttributes(operatorDeclaration.Attributes);
2206
WriteModifiers(operatorDeclaration.ModifierTokens);
2207
if (operatorDeclaration.OperatorType == OperatorType.Explicit) {
2208
WriteKeyword(OperatorDeclaration.ExplicitRole);
2209
} else if (operatorDeclaration.OperatorType == OperatorType.Implicit) {
2210
WriteKeyword(OperatorDeclaration.ImplicitRole);
2212
operatorDeclaration.ReturnType.AcceptVisitor(this);
2214
WriteKeyword(OperatorDeclaration.OperatorKeywordRole);
2216
if (operatorDeclaration.OperatorType == OperatorType.Explicit
2217
|| operatorDeclaration.OperatorType == OperatorType.Implicit) {
2218
operatorDeclaration.ReturnType.AcceptVisitor(this);
2220
WriteToken(OperatorDeclaration.GetToken(operatorDeclaration.OperatorType), OperatorDeclaration.GetRole(operatorDeclaration.OperatorType));
2222
Space(policy.SpaceBeforeMethodDeclarationParentheses);
2223
WriteCommaSeparatedListInParenthesis(operatorDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2224
WriteMethodBody(operatorDeclaration.Body);
2225
EndNode(operatorDeclaration);
2228
public void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
2230
StartNode(parameterDeclaration);
2231
WriteAttributes(parameterDeclaration.Attributes);
2232
switch (parameterDeclaration.ParameterModifier) {
2233
case ParameterModifier.Ref:
2234
WriteKeyword(ParameterDeclaration.RefModifierRole);
2236
case ParameterModifier.Out:
2237
WriteKeyword(ParameterDeclaration.OutModifierRole);
2239
case ParameterModifier.Params:
2240
WriteKeyword(ParameterDeclaration.ParamsModifierRole);
2242
case ParameterModifier.This:
2243
WriteKeyword(ParameterDeclaration.ThisModifierRole);
2246
parameterDeclaration.Type.AcceptVisitor(this);
2247
if (!parameterDeclaration.Type.IsNull && !string.IsNullOrEmpty(parameterDeclaration.Name)) {
2250
if (!string.IsNullOrEmpty(parameterDeclaration.Name)) {
2251
parameterDeclaration.NameToken.AcceptVisitor(this);
2253
if (!parameterDeclaration.DefaultExpression.IsNull) {
2254
Space(policy.SpaceAroundAssignment);
2255
WriteToken(Roles.Assign);
2256
Space(policy.SpaceAroundAssignment);
2257
parameterDeclaration.DefaultExpression.AcceptVisitor(this);
2259
EndNode(parameterDeclaration);
2262
public void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
2264
StartNode(propertyDeclaration);
2265
WriteAttributes(propertyDeclaration.Attributes);
2266
WriteModifiers(propertyDeclaration.ModifierTokens);
2267
propertyDeclaration.ReturnType.AcceptVisitor(this);
2269
WritePrivateImplementationType(propertyDeclaration.PrivateImplementationType);
2270
propertyDeclaration.NameToken.AcceptVisitor(this);
2271
OpenBrace(policy.PropertyBraceStyle);
2272
// output get/set in their original order
2273
foreach (AstNode node in propertyDeclaration.Children) {
2274
if (node.Role == IndexerDeclaration.GetterRole || node.Role == IndexerDeclaration.SetterRole) {
2275
node.AcceptVisitor(this);
2278
CloseBrace(policy.PropertyBraceStyle);
2280
EndNode(propertyDeclaration);
2286
public void VisitVariableInitializer(VariableInitializer variableInitializer)
2288
StartNode(variableInitializer);
2289
variableInitializer.NameToken.AcceptVisitor(this);
2290
if (!variableInitializer.Initializer.IsNull) {
2291
Space(policy.SpaceAroundAssignment);
2292
WriteToken(Roles.Assign);
2293
Space(policy.SpaceAroundAssignment);
2294
variableInitializer.Initializer.AcceptVisitor(this);
2296
EndNode(variableInitializer);
2299
public void VisitCompilationUnit(CompilationUnit compilationUnit)
2301
// don't do node tracking as we visit all children directly
2302
foreach (AstNode node in compilationUnit.Children) {
2303
node.AcceptVisitor(this);
2307
public void VisitSimpleType(SimpleType simpleType)
2309
StartNode(simpleType);
2310
WriteIdentifier(simpleType.Identifier);
2311
WriteTypeArguments(simpleType.TypeArguments);
2312
EndNode(simpleType);
2315
public void VisitMemberType(MemberType memberType)
2317
StartNode(memberType);
2318
memberType.Target.AcceptVisitor(this);
2319
if (memberType.IsDoubleColon) {
2320
WriteToken(Roles.DoubleColon);
2322
WriteToken(Roles.Dot);
2324
WriteIdentifier(memberType.MemberName);
2325
WriteTypeArguments(memberType.TypeArguments);
2326
EndNode(memberType);
2329
public void VisitComposedType(ComposedType composedType)
2331
StartNode(composedType);
2332
composedType.BaseType.AcceptVisitor(this);
2333
if (composedType.HasNullableSpecifier) {
2334
WriteToken(ComposedType.NullableRole);
2336
for (int i = 0; i < composedType.PointerRank; i++) {
2337
WriteToken(ComposedType.PointerRole);
2339
foreach (var node in composedType.ArraySpecifiers) {
2340
node.AcceptVisitor(this);
2342
EndNode(composedType);
2345
public void VisitArraySpecifier(ArraySpecifier arraySpecifier)
2347
StartNode(arraySpecifier);
2348
WriteToken(Roles.LBracket);
2349
foreach (var comma in arraySpecifier.GetChildrenByRole(Roles.Comma)) {
2350
WriteSpecialsUpToNode(comma);
2351
formatter.WriteToken(",");
2352
lastWritten = LastWritten.Other;
2354
WriteToken(Roles.RBracket);
2355
EndNode(arraySpecifier);
2358
public void VisitPrimitiveType(PrimitiveType primitiveType)
2360
StartNode(primitiveType);
2361
WriteKeyword(primitiveType.Keyword);
2362
if (primitiveType.Keyword == "new") {
2367
EndNode(primitiveType);
2370
public void VisitComment(Comment comment)
2372
if (lastWritten == LastWritten.Division) {
2373
// When there's a comment starting after a division operator
2374
// "1.0 / /*comment*/a", then we need to insert a space in front of the comment.
2377
formatter.StartNode(comment);
2378
formatter.WriteComment(comment.CommentType, comment.Content);
2379
formatter.EndNode(comment);
2380
lastWritten = LastWritten.Whitespace;
2383
public void VisitNewLine(NewLineNode newLineNode)
2385
formatter.StartNode(newLineNode);
2386
formatter.NewLine();
2387
formatter.EndNode(newLineNode);
2390
public void VisitWhitespace(WhitespaceNode whitespaceNode)
2395
public void VisitText(TextNode textNode)
2400
public void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective)
2402
formatter.StartNode(preProcessorDirective);
2403
formatter.WritePreProcessorDirective(preProcessorDirective.Type, preProcessorDirective.Argument);
2404
formatter.EndNode(preProcessorDirective);
2405
lastWritten = LastWritten.Whitespace;
2408
public void VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration)
2410
StartNode(typeParameterDeclaration);
2411
WriteAttributes(typeParameterDeclaration.Attributes);
2412
switch (typeParameterDeclaration.Variance) {
2413
case VarianceModifier.Invariant:
2415
case VarianceModifier.Covariant:
2416
WriteKeyword(TypeParameterDeclaration.OutVarianceKeywordRole);
2418
case VarianceModifier.Contravariant:
2419
WriteKeyword(TypeParameterDeclaration.InVarianceKeywordRole);
2422
throw new NotSupportedException ("Invalid value for VarianceModifier");
2424
typeParameterDeclaration.NameToken.AcceptVisitor(this);
2425
EndNode(typeParameterDeclaration);
2428
public void VisitConstraint(Constraint constraint)
2430
StartNode(constraint);
2432
WriteKeyword(Roles.WhereKeyword);
2433
WriteIdentifier(constraint.TypeParameter.Identifier);
2435
WriteToken(Roles.Colon);
2437
WriteCommaSeparatedList(constraint.BaseTypes);
2438
EndNode(constraint);
2441
public void VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode)
2443
CSharpModifierToken mod = cSharpTokenNode as CSharpModifierToken;
2446
WriteKeyword(CSharpModifierToken.GetModifierName(mod.Modifier));
2449
throw new NotSupportedException ("Should never visit individual tokens");
2453
public void VisitIdentifier(Identifier identifier)
2455
StartNode(identifier);
2456
WriteIdentifier(identifier.Name);
2457
EndNode(identifier);
2462
#region Pattern Nodes
2463
public void VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern)
2465
StartNode(placeholder);
2466
VisitNodeInPattern(pattern);
2467
EndNode(placeholder);
2470
void VisitAnyNode(AnyNode anyNode)
2472
if (!string.IsNullOrEmpty(anyNode.GroupName)) {
2473
WriteIdentifier(anyNode.GroupName);
2474
WriteToken(Roles.Colon);
2478
void VisitBackreference(Backreference backreference)
2480
WriteKeyword("backreference");
2482
WriteIdentifier(backreference.ReferencedGroupName);
2486
void VisitIdentifierExpressionBackreference(IdentifierExpressionBackreference identifierExpressionBackreference)
2488
WriteKeyword("identifierBackreference");
2490
WriteIdentifier(identifierExpressionBackreference.ReferencedGroupName);
2494
void VisitChoice(Choice choice)
2496
WriteKeyword("choice");
2501
foreach (INode alternative in choice) {
2502
VisitNodeInPattern(alternative);
2503
if (alternative != choice.Last()) {
2504
WriteToken(Roles.Comma);
2508
formatter.Unindent();
2512
void VisitNamedNode(NamedNode namedNode)
2514
if (!string.IsNullOrEmpty(namedNode.GroupName)) {
2515
WriteIdentifier(namedNode.GroupName);
2516
WriteToken(Roles.Colon);
2518
VisitNodeInPattern(namedNode.ChildNode);
2521
void VisitRepeat(Repeat repeat)
2523
WriteKeyword("repeat");
2525
if (repeat.MinCount != 0 || repeat.MaxCount != int.MaxValue) {
2526
WriteIdentifier(repeat.MinCount.ToString());
2527
WriteToken(Roles.Comma);
2528
WriteIdentifier(repeat.MaxCount.ToString());
2529
WriteToken(Roles.Comma);
2531
VisitNodeInPattern(repeat.ChildNode);
2535
void VisitOptionalNode(OptionalNode optionalNode)
2537
WriteKeyword("optional");
2539
VisitNodeInPattern(optionalNode.ChildNode);
2543
void VisitNodeInPattern(INode childNode)
2545
if (childNode is AstNode) {
2546
((AstNode)childNode).AcceptVisitor(this);
2547
} else if (childNode is IdentifierExpressionBackreference) {
2548
VisitIdentifierExpressionBackreference((IdentifierExpressionBackreference)childNode);
2549
} else if (childNode is Choice) {
2550
VisitChoice((Choice)childNode);
2551
} else if (childNode is AnyNode) {
2552
VisitAnyNode((AnyNode)childNode);
2553
} else if (childNode is Backreference) {
2554
VisitBackreference((Backreference)childNode);
2555
} else if (childNode is NamedNode) {
2556
VisitNamedNode((NamedNode)childNode);
2557
} else if (childNode is OptionalNode) {
2558
VisitOptionalNode((OptionalNode)childNode);
2559
} else if (childNode is Repeat) {
2560
VisitRepeat((Repeat)childNode);
2562
WritePrimitiveValue(childNode);
2567
#region Documentation Reference
2568
public void VisitDocumentationReference(DocumentationReference documentationReference)
2570
StartNode(documentationReference);
2571
if (!documentationReference.DeclaringType.IsNull) {
2572
documentationReference.DeclaringType.AcceptVisitor(this);
2573
if (documentationReference.EntityType != EntityType.TypeDefinition) {
2574
WriteToken(Roles.Dot);
2577
switch (documentationReference.EntityType) {
2578
case EntityType.TypeDefinition:
2579
// we already printed the DeclaringType
2581
case EntityType.Indexer:
2582
WriteKeyword(IndexerDeclaration.ThisKeywordRole);
2584
case EntityType.Operator:
2585
var opType = documentationReference.OperatorType;
2586
if (opType == OperatorType.Explicit) {
2587
WriteKeyword(OperatorDeclaration.ExplicitRole);
2588
} else if (opType == OperatorType.Implicit) {
2589
WriteKeyword(OperatorDeclaration.ImplicitRole);
2591
WriteKeyword(OperatorDeclaration.OperatorKeywordRole);
2593
if (opType == OperatorType.Explicit || opType == OperatorType.Implicit) {
2594
documentationReference.ConversionOperatorReturnType.AcceptVisitor(this);
2596
WriteToken(OperatorDeclaration.GetToken(opType), OperatorDeclaration.GetRole(opType));
2600
WriteIdentifier(documentationReference.MemberName);
2603
WriteTypeArguments(documentationReference.TypeArguments);
2604
if (documentationReference.HasParameterList) {
2605
Space(policy.SpaceBeforeMethodDeclarationParentheses);
2606
if (documentationReference.EntityType == EntityType.Indexer) {
2607
WriteCommaSeparatedListInBrackets(documentationReference.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2609
WriteCommaSeparatedListInParenthesis(documentationReference.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
2612
EndNode(documentationReference);