PageRenderTime 60ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs

http://github.com/icsharpcode/ILSpy
C# | 2401 lines | 2116 code | 206 blank | 79 comment | 303 complexity | ca4679c15229cbd6d703f5311952c450 MD5 | raw file
Possible License(s): LGPL-2.1, MIT, CC-BY-SA-3.0
  1. // Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Diagnostics;
  21. using System.Globalization;
  22. using System.IO;
  23. using System.Linq;
  24. using System.Text;
  25. using System.Threading.Tasks;
  26. using ICSharpCode.NRefactory.PatternMatching;
  27. using ICSharpCode.NRefactory.TypeSystem;
  28. using ICSharpCode.NRefactory.CSharp;
  29. namespace ICSharpCode.NRefactory.CSharp
  30. {
  31. /// <summary>
  32. /// Outputs the AST.
  33. /// </summary>
  34. public class CSharpOutputVisitor : IAstVisitor
  35. {
  36. readonly TokenWriter writer;
  37. readonly CSharpFormattingOptions policy;
  38. readonly Stack<AstNode> containerStack = new Stack<AstNode> ();
  39. public CSharpOutputVisitor (TextWriter textWriter, CSharpFormattingOptions formattingPolicy)
  40. {
  41. if (textWriter == null) {
  42. throw new ArgumentNullException ("textWriter");
  43. }
  44. if (formattingPolicy == null) {
  45. throw new ArgumentNullException ("formattingPolicy");
  46. }
  47. this.writer = TokenWriter.Create(textWriter);
  48. this.policy = formattingPolicy;
  49. }
  50. public CSharpOutputVisitor (TokenWriter writer, CSharpFormattingOptions formattingPolicy)
  51. {
  52. if (writer == null) {
  53. throw new ArgumentNullException ("writer");
  54. }
  55. if (formattingPolicy == null) {
  56. throw new ArgumentNullException ("formattingPolicy");
  57. }
  58. this.writer = new InsertSpecialsDecorator(new InsertRequiredSpacesDecorator(writer));
  59. this.policy = formattingPolicy;
  60. }
  61. #region StartNode/EndNode
  62. void StartNode(AstNode node)
  63. {
  64. // Ensure that nodes are visited in the proper nested order.
  65. // Jumps to different subtrees are allowed only for the child of a placeholder node.
  66. Debug.Assert(containerStack.Count == 0 || node.Parent == containerStack.Peek() || containerStack.Peek().NodeType == NodeType.Pattern);
  67. containerStack.Push(node);
  68. writer.StartNode(node);
  69. }
  70. void EndNode(AstNode node)
  71. {
  72. Debug.Assert(node == containerStack.Peek());
  73. containerStack.Pop();
  74. writer.EndNode(node);
  75. }
  76. #endregion
  77. #region Comma
  78. /// <summary>
  79. /// Writes a comma.
  80. /// </summary>
  81. /// <param name="nextNode">The next node after the comma.</param>
  82. /// <param name="noSpaceAfterComma">When set prevents printing a space after comma.</param>
  83. void Comma(AstNode nextNode, bool noSpaceAfterComma = false)
  84. {
  85. Space(policy.SpaceBeforeBracketComma);
  86. // TODO: Comma policy has changed.
  87. writer.WriteToken(Roles.Comma, ",");
  88. Space(!noSpaceAfterComma && policy.SpaceAfterBracketComma);
  89. // TODO: Comma policy has changed.
  90. }
  91. /// <summary>
  92. /// Writes an optional comma, e.g. at the end of an enum declaration or in an array initializer
  93. /// </summary>
  94. void OptionalComma(AstNode pos)
  95. {
  96. // Look if there's a comma after the current node, and insert it if it exists.
  97. while (pos != null && pos.NodeType == NodeType.Whitespace) {
  98. pos = pos.NextSibling;
  99. }
  100. if (pos != null && pos.Role == Roles.Comma) {
  101. Comma(null, noSpaceAfterComma: true);
  102. }
  103. }
  104. /// <summary>
  105. /// Writes an optional semicolon, e.g. at the end of a type or namespace declaration.
  106. /// </summary>
  107. void OptionalSemicolon(AstNode pos)
  108. {
  109. // Look if there's a semicolon after the current node, and insert it if it exists.
  110. while (pos != null && pos.NodeType == NodeType.Whitespace) {
  111. pos = pos.PrevSibling;
  112. }
  113. if (pos != null && pos.Role == Roles.Semicolon) {
  114. Semicolon();
  115. }
  116. }
  117. void WriteCommaSeparatedList(IEnumerable<AstNode> list)
  118. {
  119. bool isFirst = true;
  120. foreach (AstNode node in list) {
  121. if (isFirst) {
  122. isFirst = false;
  123. } else {
  124. Comma(node);
  125. }
  126. node.AcceptVisitor(this);
  127. }
  128. }
  129. void WriteCommaSeparatedListInParenthesis(IEnumerable<AstNode> list, bool spaceWithin)
  130. {
  131. LPar();
  132. if (list.Any()) {
  133. Space(spaceWithin);
  134. WriteCommaSeparatedList(list);
  135. Space(spaceWithin);
  136. }
  137. RPar();
  138. }
  139. #if DOTNET35
  140. void WriteCommaSeparatedList(IEnumerable<VariableInitializer> list)
  141. {
  142. WriteCommaSeparatedList(list.SafeCast<VariableInitializer, AstNode>());
  143. }
  144. void WriteCommaSeparatedList(IEnumerable<AstType> list)
  145. {
  146. WriteCommaSeparatedList(list.SafeCast<AstType, AstNode>());
  147. }
  148. void WriteCommaSeparatedListInParenthesis(IEnumerable<Expression> list, bool spaceWithin)
  149. {
  150. WriteCommaSeparatedListInParenthesis(list.SafeCast<Expression, AstNode>(), spaceWithin);
  151. }
  152. void WriteCommaSeparatedListInParenthesis(IEnumerable<ParameterDeclaration> list, bool spaceWithin)
  153. {
  154. WriteCommaSeparatedListInParenthesis(list.SafeCast<ParameterDeclaration, AstNode>(), spaceWithin);
  155. }
  156. #endif
  157. void WriteCommaSeparatedListInBrackets(IEnumerable<ParameterDeclaration> list, bool spaceWithin)
  158. {
  159. WriteToken(Roles.LBracket);
  160. if (list.Any()) {
  161. Space(spaceWithin);
  162. WriteCommaSeparatedList(list);
  163. Space(spaceWithin);
  164. }
  165. WriteToken(Roles.RBracket);
  166. }
  167. void WriteCommaSeparatedListInBrackets(IEnumerable<Expression> list)
  168. {
  169. WriteToken(Roles.LBracket);
  170. if (list.Any()) {
  171. Space(policy.SpacesWithinBrackets);
  172. WriteCommaSeparatedList(list);
  173. Space(policy.SpacesWithinBrackets);
  174. }
  175. WriteToken(Roles.RBracket);
  176. }
  177. #endregion
  178. #region Write tokens
  179. bool isAtStartOfLine = true;
  180. /// <summary>
  181. /// Writes a keyword, and all specials up to
  182. /// </summary>
  183. void WriteKeyword(TokenRole tokenRole)
  184. {
  185. WriteKeyword(tokenRole.Token, tokenRole);
  186. }
  187. void WriteKeyword(string token, Role tokenRole = null)
  188. {
  189. writer.WriteKeyword(tokenRole, token);
  190. isAtStartOfLine = false;
  191. }
  192. void WriteIdentifier(Identifier identifier)
  193. {
  194. writer.WriteIdentifier(identifier);
  195. isAtStartOfLine = false;
  196. }
  197. void WriteIdentifier(string identifier)
  198. {
  199. AstType.Create(identifier).AcceptVisitor(this);
  200. isAtStartOfLine = false;
  201. }
  202. void WriteToken(TokenRole tokenRole)
  203. {
  204. WriteToken(tokenRole.Token, tokenRole);
  205. }
  206. void WriteToken(string token, Role tokenRole)
  207. {
  208. writer.WriteToken(tokenRole, token);
  209. isAtStartOfLine = false;
  210. }
  211. void LPar()
  212. {
  213. WriteToken(Roles.LPar);
  214. }
  215. void RPar()
  216. {
  217. WriteToken(Roles.RPar);
  218. }
  219. /// <summary>
  220. /// Marks the end of a statement
  221. /// </summary>
  222. void Semicolon()
  223. {
  224. Role role = containerStack.Peek().Role;
  225. // get the role of the current node
  226. if (!(role == ForStatement.InitializerRole || role == ForStatement.IteratorRole || role == UsingStatement.ResourceAcquisitionRole)) {
  227. WriteToken(Roles.Semicolon);
  228. NewLine();
  229. }
  230. }
  231. /// <summary>
  232. /// Writes a space depending on policy.
  233. /// </summary>
  234. void Space(bool addSpace = true)
  235. {
  236. if (addSpace) {
  237. writer.Space();
  238. }
  239. }
  240. void NewLine()
  241. {
  242. writer.NewLine();
  243. isAtStartOfLine = true;
  244. }
  245. void OpenBrace(BraceStyle style)
  246. {
  247. switch (style) {
  248. case BraceStyle.DoNotChange:
  249. case BraceStyle.EndOfLine:
  250. case BraceStyle.BannerStyle:
  251. if (!isAtStartOfLine)
  252. writer.Space();
  253. writer.WriteToken(Roles.LBrace, "{");
  254. break;
  255. case BraceStyle.EndOfLineWithoutSpace:
  256. writer.WriteToken(Roles.LBrace, "{");
  257. break;
  258. case BraceStyle.NextLine:
  259. if (!isAtStartOfLine)
  260. NewLine();
  261. writer.WriteToken(Roles.LBrace, "{");
  262. break;
  263. case BraceStyle.NextLineShifted:
  264. NewLine();
  265. writer.Indent();
  266. writer.WriteToken(Roles.LBrace, "{");
  267. NewLine();
  268. return;
  269. case BraceStyle.NextLineShifted2:
  270. NewLine();
  271. writer.Indent();
  272. writer.WriteToken(Roles.LBrace, "{");
  273. break;
  274. default:
  275. throw new ArgumentOutOfRangeException ();
  276. }
  277. writer.Indent();
  278. NewLine();
  279. }
  280. void CloseBrace(BraceStyle style)
  281. {
  282. switch (style) {
  283. case BraceStyle.DoNotChange:
  284. case BraceStyle.EndOfLine:
  285. case BraceStyle.EndOfLineWithoutSpace:
  286. case BraceStyle.NextLine:
  287. writer.Unindent();
  288. writer.WriteToken(Roles.RBrace, "}");
  289. isAtStartOfLine = false;
  290. break;
  291. case BraceStyle.BannerStyle:
  292. case BraceStyle.NextLineShifted:
  293. writer.WriteToken(Roles.RBrace, "}");
  294. isAtStartOfLine = false;
  295. writer.Unindent();
  296. break;
  297. case BraceStyle.NextLineShifted2:
  298. writer.Unindent();
  299. writer.WriteToken(Roles.RBrace, "}");
  300. isAtStartOfLine = false;
  301. writer.Unindent();
  302. break;
  303. default:
  304. throw new ArgumentOutOfRangeException();
  305. }
  306. }
  307. #endregion
  308. #region IsKeyword Test
  309. static readonly HashSet<string> unconditionalKeywords = new HashSet<string> {
  310. "abstract", "as", "base", "bool", "break", "byte", "case", "catch",
  311. "char", "checked", "class", "const", "continue", "decimal", "default", "delegate",
  312. "do", "double", "else", "enum", "event", "explicit", "extern", "false",
  313. "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit",
  314. "in", "int", "interface", "internal", "is", "lock", "long", "namespace",
  315. "new", "null", "object", "operator", "out", "override", "params", "private",
  316. "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short",
  317. "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw",
  318. "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort",
  319. "using", "virtual", "void", "volatile", "while"
  320. };
  321. static readonly HashSet<string> queryKeywords = new HashSet<string> {
  322. "from", "where", "join", "on", "equals", "into", "let", "orderby",
  323. "ascending", "descending", "select", "group", "by"
  324. };
  325. /// <summary>
  326. /// Determines whether the specified identifier is a keyword in the given context.
  327. /// </summary>
  328. public static bool IsKeyword(string identifier, AstNode context)
  329. {
  330. if (unconditionalKeywords.Contains(identifier)) {
  331. return true;
  332. }
  333. foreach (AstNode ancestor in context.Ancestors) {
  334. if (ancestor is QueryExpression && queryKeywords.Contains(identifier)) {
  335. return true;
  336. }
  337. if (identifier == "await") {
  338. // with lambdas/anonymous methods,
  339. if (ancestor is LambdaExpression) {
  340. return ((LambdaExpression)ancestor).IsAsync;
  341. }
  342. if (ancestor is AnonymousMethodExpression) {
  343. return ((AnonymousMethodExpression)ancestor).IsAsync;
  344. }
  345. if (ancestor is EntityDeclaration) {
  346. return (((EntityDeclaration)ancestor).Modifiers & Modifiers.Async) == Modifiers.Async;
  347. }
  348. }
  349. }
  350. return false;
  351. }
  352. #endregion
  353. #region Write constructs
  354. void WriteTypeArguments(IEnumerable<AstType> typeArguments)
  355. {
  356. if (typeArguments.Any()) {
  357. WriteToken(Roles.LChevron);
  358. WriteCommaSeparatedList(typeArguments);
  359. WriteToken(Roles.RChevron);
  360. }
  361. }
  362. public void WriteTypeParameters(IEnumerable<TypeParameterDeclaration> typeParameters)
  363. {
  364. if (typeParameters.Any()) {
  365. WriteToken(Roles.LChevron);
  366. WriteCommaSeparatedList(typeParameters);
  367. WriteToken(Roles.RChevron);
  368. }
  369. }
  370. void WriteModifiers(IEnumerable<CSharpModifierToken> modifierTokens)
  371. {
  372. foreach (CSharpModifierToken modifier in modifierTokens) {
  373. modifier.AcceptVisitor(this);
  374. }
  375. }
  376. void WriteQualifiedIdentifier(IEnumerable<Identifier> identifiers)
  377. {
  378. bool first = true;
  379. foreach (Identifier ident in identifiers) {
  380. if (first) {
  381. first = false;
  382. } else {
  383. writer.WriteToken(Roles.Dot, ".");
  384. }
  385. writer.WriteIdentifier(ident);
  386. }
  387. }
  388. void WriteEmbeddedStatement(Statement embeddedStatement)
  389. {
  390. if (embeddedStatement.IsNull) {
  391. NewLine();
  392. return;
  393. }
  394. BlockStatement block = embeddedStatement as BlockStatement;
  395. if (block != null) {
  396. VisitBlockStatement(block);
  397. } else {
  398. NewLine();
  399. writer.Indent();
  400. embeddedStatement.AcceptVisitor(this);
  401. writer.Unindent();
  402. }
  403. }
  404. void WriteMethodBody(BlockStatement body)
  405. {
  406. if (body.IsNull) {
  407. Semicolon();
  408. } else {
  409. VisitBlockStatement(body);
  410. }
  411. }
  412. void WriteAttributes(IEnumerable<AttributeSection> attributes)
  413. {
  414. foreach (AttributeSection attr in attributes) {
  415. attr.AcceptVisitor(this);
  416. }
  417. }
  418. void WritePrivateImplementationType(AstType privateImplementationType)
  419. {
  420. if (!privateImplementationType.IsNull) {
  421. privateImplementationType.AcceptVisitor(this);
  422. WriteToken(Roles.Dot);
  423. }
  424. }
  425. #endregion
  426. #region Expressions
  427. public void VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression)
  428. {
  429. StartNode(anonymousMethodExpression);
  430. if (anonymousMethodExpression.IsAsync) {
  431. WriteKeyword(AnonymousMethodExpression.AsyncModifierRole);
  432. Space();
  433. }
  434. WriteKeyword(AnonymousMethodExpression.DelegateKeywordRole);
  435. if (anonymousMethodExpression.HasParameterList) {
  436. Space(policy.SpaceBeforeMethodDeclarationParentheses);
  437. WriteCommaSeparatedListInParenthesis(anonymousMethodExpression.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
  438. }
  439. anonymousMethodExpression.Body.AcceptVisitor(this);
  440. EndNode(anonymousMethodExpression);
  441. }
  442. public void VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression)
  443. {
  444. StartNode(undocumentedExpression);
  445. switch (undocumentedExpression.UndocumentedExpressionType) {
  446. case UndocumentedExpressionType.ArgList:
  447. case UndocumentedExpressionType.ArgListAccess:
  448. WriteKeyword(UndocumentedExpression.ArglistKeywordRole);
  449. break;
  450. case UndocumentedExpressionType.MakeRef:
  451. WriteKeyword(UndocumentedExpression.MakerefKeywordRole);
  452. break;
  453. case UndocumentedExpressionType.RefType:
  454. WriteKeyword(UndocumentedExpression.ReftypeKeywordRole);
  455. break;
  456. case UndocumentedExpressionType.RefValue:
  457. WriteKeyword(UndocumentedExpression.RefvalueKeywordRole);
  458. break;
  459. }
  460. if (undocumentedExpression.Arguments.Count > 0) {
  461. Space(policy.SpaceBeforeMethodCallParentheses);
  462. WriteCommaSeparatedListInParenthesis(undocumentedExpression.Arguments, policy.SpaceWithinMethodCallParentheses);
  463. }
  464. EndNode(undocumentedExpression);
  465. }
  466. public void VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression)
  467. {
  468. StartNode(arrayCreateExpression);
  469. WriteKeyword(ArrayCreateExpression.NewKeywordRole);
  470. arrayCreateExpression.Type.AcceptVisitor(this);
  471. if (arrayCreateExpression.Arguments.Count > 0) {
  472. WriteCommaSeparatedListInBrackets(arrayCreateExpression.Arguments);
  473. }
  474. foreach (var specifier in arrayCreateExpression.AdditionalArraySpecifiers) {
  475. specifier.AcceptVisitor(this);
  476. }
  477. arrayCreateExpression.Initializer.AcceptVisitor(this);
  478. EndNode(arrayCreateExpression);
  479. }
  480. public void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
  481. {
  482. StartNode(arrayInitializerExpression);
  483. // "new List<int> { { 1 } }" and "new List<int> { 1 }" are the same semantically.
  484. // We also use the same AST for both: we always use two nested ArrayInitializerExpressions
  485. // for collection initializers, even if the user did not write nested brackets.
  486. // The output visitor will output nested braces only if they are necessary,
  487. // or if the braces tokens exist in the AST.
  488. bool bracesAreOptional = arrayInitializerExpression.Elements.Count == 1
  489. && IsObjectOrCollectionInitializer(arrayInitializerExpression.Parent)
  490. && !CanBeConfusedWithObjectInitializer(arrayInitializerExpression.Elements.Single());
  491. if (bracesAreOptional && arrayInitializerExpression.LBraceToken.IsNull) {
  492. arrayInitializerExpression.Elements.Single().AcceptVisitor(this);
  493. } else {
  494. PrintInitializerElements(arrayInitializerExpression.Elements);
  495. }
  496. EndNode(arrayInitializerExpression);
  497. }
  498. bool CanBeConfusedWithObjectInitializer(Expression expr)
  499. {
  500. // "int a; new List<int> { a = 1 };" is an object initalizers and invalid, but
  501. // "int a; new List<int> { { a = 1 } };" is a valid collection initializer.
  502. AssignmentExpression ae = expr as AssignmentExpression;
  503. return ae != null && ae.Operator == AssignmentOperatorType.Assign;
  504. }
  505. bool IsObjectOrCollectionInitializer(AstNode node)
  506. {
  507. if (!(node is ArrayInitializerExpression)) {
  508. return false;
  509. }
  510. if (node.Parent is ObjectCreateExpression) {
  511. return node.Role == ObjectCreateExpression.InitializerRole;
  512. }
  513. if (node.Parent is NamedExpression) {
  514. return node.Role == Roles.Expression;
  515. }
  516. return false;
  517. }
  518. void PrintInitializerElements(AstNodeCollection<Expression> elements)
  519. {
  520. BraceStyle style;
  521. if (policy.ArrayInitializerWrapping == Wrapping.WrapAlways) {
  522. style = BraceStyle.NextLine;
  523. } else {
  524. style = BraceStyle.EndOfLine;
  525. }
  526. OpenBrace(style);
  527. bool isFirst = true;
  528. AstNode last = null;
  529. foreach (AstNode node in elements) {
  530. if (isFirst) {
  531. isFirst = false;
  532. } else {
  533. Comma(node, noSpaceAfterComma: true);
  534. NewLine();
  535. }
  536. last = node;
  537. node.AcceptVisitor(this);
  538. }
  539. if (last != null)
  540. OptionalComma(last.NextSibling);
  541. NewLine();
  542. CloseBrace(style);
  543. }
  544. public void VisitAsExpression(AsExpression asExpression)
  545. {
  546. StartNode(asExpression);
  547. asExpression.Expression.AcceptVisitor(this);
  548. Space();
  549. WriteKeyword(AsExpression.AsKeywordRole);
  550. Space();
  551. asExpression.Type.AcceptVisitor(this);
  552. EndNode(asExpression);
  553. }
  554. public void VisitAssignmentExpression(AssignmentExpression assignmentExpression)
  555. {
  556. StartNode(assignmentExpression);
  557. assignmentExpression.Left.AcceptVisitor(this);
  558. Space(policy.SpaceAroundAssignment);
  559. WriteToken(AssignmentExpression.GetOperatorRole(assignmentExpression.Operator));
  560. Space(policy.SpaceAroundAssignment);
  561. assignmentExpression.Right.AcceptVisitor(this);
  562. EndNode(assignmentExpression);
  563. }
  564. public void VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression)
  565. {
  566. StartNode(baseReferenceExpression);
  567. WriteKeyword("base", baseReferenceExpression.Role);
  568. EndNode(baseReferenceExpression);
  569. }
  570. public void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
  571. {
  572. StartNode(binaryOperatorExpression);
  573. binaryOperatorExpression.Left.AcceptVisitor(this);
  574. bool spacePolicy;
  575. switch (binaryOperatorExpression.Operator) {
  576. case BinaryOperatorType.BitwiseAnd:
  577. case BinaryOperatorType.BitwiseOr:
  578. case BinaryOperatorType.ExclusiveOr:
  579. spacePolicy = policy.SpaceAroundBitwiseOperator;
  580. break;
  581. case BinaryOperatorType.ConditionalAnd:
  582. case BinaryOperatorType.ConditionalOr:
  583. spacePolicy = policy.SpaceAroundLogicalOperator;
  584. break;
  585. case BinaryOperatorType.GreaterThan:
  586. case BinaryOperatorType.GreaterThanOrEqual:
  587. case BinaryOperatorType.LessThanOrEqual:
  588. case BinaryOperatorType.LessThan:
  589. spacePolicy = policy.SpaceAroundRelationalOperator;
  590. break;
  591. case BinaryOperatorType.Equality:
  592. case BinaryOperatorType.InEquality:
  593. spacePolicy = policy.SpaceAroundEqualityOperator;
  594. break;
  595. case BinaryOperatorType.Add:
  596. case BinaryOperatorType.Subtract:
  597. spacePolicy = policy.SpaceAroundAdditiveOperator;
  598. break;
  599. case BinaryOperatorType.Multiply:
  600. case BinaryOperatorType.Divide:
  601. case BinaryOperatorType.Modulus:
  602. spacePolicy = policy.SpaceAroundMultiplicativeOperator;
  603. break;
  604. case BinaryOperatorType.ShiftLeft:
  605. case BinaryOperatorType.ShiftRight:
  606. spacePolicy = policy.SpaceAroundShiftOperator;
  607. break;
  608. case BinaryOperatorType.NullCoalescing:
  609. spacePolicy = true;
  610. break;
  611. default:
  612. throw new NotSupportedException ("Invalid value for BinaryOperatorType");
  613. }
  614. Space(spacePolicy);
  615. WriteToken(BinaryOperatorExpression.GetOperatorRole(binaryOperatorExpression.Operator));
  616. Space(spacePolicy);
  617. binaryOperatorExpression.Right.AcceptVisitor(this);
  618. EndNode(binaryOperatorExpression);
  619. }
  620. public void VisitCastExpression(CastExpression castExpression)
  621. {
  622. StartNode(castExpression);
  623. LPar();
  624. Space(policy.SpacesWithinCastParentheses);
  625. castExpression.Type.AcceptVisitor(this);
  626. Space(policy.SpacesWithinCastParentheses);
  627. RPar();
  628. Space(policy.SpaceAfterTypecast);
  629. castExpression.Expression.AcceptVisitor(this);
  630. EndNode(castExpression);
  631. }
  632. public void VisitCheckedExpression(CheckedExpression checkedExpression)
  633. {
  634. StartNode(checkedExpression);
  635. WriteKeyword(CheckedExpression.CheckedKeywordRole);
  636. LPar();
  637. Space(policy.SpacesWithinCheckedExpressionParantheses);
  638. checkedExpression.Expression.AcceptVisitor(this);
  639. Space(policy.SpacesWithinCheckedExpressionParantheses);
  640. RPar();
  641. EndNode(checkedExpression);
  642. }
  643. public void VisitConditionalExpression(ConditionalExpression conditionalExpression)
  644. {
  645. StartNode(conditionalExpression);
  646. conditionalExpression.Condition.AcceptVisitor(this);
  647. Space(policy.SpaceBeforeConditionalOperatorCondition);
  648. WriteToken(ConditionalExpression.QuestionMarkRole);
  649. Space(policy.SpaceAfterConditionalOperatorCondition);
  650. conditionalExpression.TrueExpression.AcceptVisitor(this);
  651. Space(policy.SpaceBeforeConditionalOperatorSeparator);
  652. WriteToken(ConditionalExpression.ColonRole);
  653. Space(policy.SpaceAfterConditionalOperatorSeparator);
  654. conditionalExpression.FalseExpression.AcceptVisitor(this);
  655. EndNode(conditionalExpression);
  656. }
  657. public void VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression)
  658. {
  659. StartNode(defaultValueExpression);
  660. WriteKeyword(DefaultValueExpression.DefaultKeywordRole);
  661. LPar();
  662. Space(policy.SpacesWithinTypeOfParentheses);
  663. defaultValueExpression.Type.AcceptVisitor(this);
  664. Space(policy.SpacesWithinTypeOfParentheses);
  665. RPar();
  666. EndNode(defaultValueExpression);
  667. }
  668. public void VisitDirectionExpression(DirectionExpression directionExpression)
  669. {
  670. StartNode(directionExpression);
  671. switch (directionExpression.FieldDirection) {
  672. case FieldDirection.Out:
  673. WriteKeyword(DirectionExpression.OutKeywordRole);
  674. break;
  675. case FieldDirection.Ref:
  676. WriteKeyword(DirectionExpression.RefKeywordRole);
  677. break;
  678. default:
  679. throw new NotSupportedException ("Invalid value for FieldDirection");
  680. }
  681. Space();
  682. directionExpression.Expression.AcceptVisitor(this);
  683. EndNode(directionExpression);
  684. }
  685. public void VisitIdentifierExpression(IdentifierExpression identifierExpression)
  686. {
  687. StartNode(identifierExpression);
  688. WriteIdentifier(identifierExpression.IdentifierToken);
  689. WriteTypeArguments(identifierExpression.TypeArguments);
  690. EndNode(identifierExpression);
  691. }
  692. public void VisitIndexerExpression(IndexerExpression indexerExpression)
  693. {
  694. StartNode(indexerExpression);
  695. indexerExpression.Target.AcceptVisitor(this);
  696. Space(policy.SpaceBeforeMethodCallParentheses);
  697. WriteCommaSeparatedListInBrackets(indexerExpression.Arguments);
  698. EndNode(indexerExpression);
  699. }
  700. public void VisitInvocationExpression(InvocationExpression invocationExpression)
  701. {
  702. StartNode(invocationExpression);
  703. invocationExpression.Target.AcceptVisitor(this);
  704. Space(policy.SpaceBeforeMethodCallParentheses);
  705. WriteCommaSeparatedListInParenthesis(invocationExpression.Arguments, policy.SpaceWithinMethodCallParentheses);
  706. EndNode(invocationExpression);
  707. }
  708. public void VisitIsExpression(IsExpression isExpression)
  709. {
  710. StartNode(isExpression);
  711. isExpression.Expression.AcceptVisitor(this);
  712. Space();
  713. WriteKeyword(IsExpression.IsKeywordRole);
  714. isExpression.Type.AcceptVisitor(this);
  715. EndNode(isExpression);
  716. }
  717. public void VisitLambdaExpression(LambdaExpression lambdaExpression)
  718. {
  719. StartNode(lambdaExpression);
  720. if (lambdaExpression.IsAsync) {
  721. WriteKeyword(LambdaExpression.AsyncModifierRole);
  722. Space();
  723. }
  724. if (LambdaNeedsParenthesis(lambdaExpression)) {
  725. WriteCommaSeparatedListInParenthesis(lambdaExpression.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
  726. } else {
  727. lambdaExpression.Parameters.Single().AcceptVisitor(this);
  728. }
  729. Space();
  730. WriteToken(LambdaExpression.ArrowRole);
  731. Space();
  732. lambdaExpression.Body.AcceptVisitor(this);
  733. EndNode(lambdaExpression);
  734. }
  735. bool LambdaNeedsParenthesis(LambdaExpression lambdaExpression)
  736. {
  737. if (lambdaExpression.Parameters.Count != 1) {
  738. return true;
  739. }
  740. var p = lambdaExpression.Parameters.Single();
  741. return !(p.Type.IsNull && p.ParameterModifier == ParameterModifier.None);
  742. }
  743. public void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
  744. {
  745. StartNode(memberReferenceExpression);
  746. memberReferenceExpression.Target.AcceptVisitor(this);
  747. WriteToken(Roles.Dot);
  748. WriteIdentifier(memberReferenceExpression.MemberNameToken);
  749. WriteTypeArguments(memberReferenceExpression.TypeArguments);
  750. EndNode(memberReferenceExpression);
  751. }
  752. public void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression)
  753. {
  754. StartNode(namedArgumentExpression);
  755. WriteIdentifier(namedArgumentExpression.NameToken);
  756. WriteToken(Roles.Colon);
  757. Space();
  758. namedArgumentExpression.Expression.AcceptVisitor(this);
  759. EndNode(namedArgumentExpression);
  760. }
  761. public void VisitNamedExpression(NamedExpression namedExpression)
  762. {
  763. StartNode(namedExpression);
  764. WriteIdentifier(namedExpression.NameToken);
  765. Space();
  766. WriteToken(Roles.Assign);
  767. Space();
  768. namedExpression.Expression.AcceptVisitor(this);
  769. EndNode(namedExpression);
  770. }
  771. public void VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression)
  772. {
  773. StartNode(nullReferenceExpression);
  774. writer.WritePrimitiveValue(null);
  775. EndNode(nullReferenceExpression);
  776. }
  777. public void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
  778. {
  779. StartNode(objectCreateExpression);
  780. WriteKeyword(ObjectCreateExpression.NewKeywordRole);
  781. objectCreateExpression.Type.AcceptVisitor(this);
  782. bool useParenthesis = objectCreateExpression.Arguments.Any() || objectCreateExpression.Initializer.IsNull;
  783. // also use parenthesis if there is an '(' token
  784. if (!objectCreateExpression.LParToken.IsNull) {
  785. useParenthesis = true;
  786. }
  787. if (useParenthesis) {
  788. Space(policy.SpaceBeforeMethodCallParentheses);
  789. WriteCommaSeparatedListInParenthesis(objectCreateExpression.Arguments, policy.SpaceWithinMethodCallParentheses);
  790. }
  791. objectCreateExpression.Initializer.AcceptVisitor(this);
  792. EndNode(objectCreateExpression);
  793. }
  794. public void VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression)
  795. {
  796. StartNode(anonymousTypeCreateExpression);
  797. WriteKeyword(AnonymousTypeCreateExpression.NewKeywordRole);
  798. PrintInitializerElements(anonymousTypeCreateExpression.Initializers);
  799. EndNode(anonymousTypeCreateExpression);
  800. }
  801. public void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression)
  802. {
  803. StartNode(parenthesizedExpression);
  804. LPar();
  805. Space(policy.SpacesWithinParentheses);
  806. parenthesizedExpression.Expression.AcceptVisitor(this);
  807. Space(policy.SpacesWithinParentheses);
  808. RPar();
  809. EndNode(parenthesizedExpression);
  810. }
  811. public void VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression)
  812. {
  813. StartNode(pointerReferenceExpression);
  814. pointerReferenceExpression.Target.AcceptVisitor(this);
  815. WriteToken(PointerReferenceExpression.ArrowRole);
  816. WriteIdentifier(pointerReferenceExpression.MemberNameToken);
  817. WriteTypeArguments(pointerReferenceExpression.TypeArguments);
  818. EndNode(pointerReferenceExpression);
  819. }
  820. #region VisitPrimitiveExpression
  821. public void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression)
  822. {
  823. StartNode(primitiveExpression);
  824. writer.WritePrimitiveValue(primitiveExpression.Value, primitiveExpression.UnsafeLiteralValue);
  825. EndNode(primitiveExpression);
  826. }
  827. #endregion
  828. public void VisitSizeOfExpression(SizeOfExpression sizeOfExpression)
  829. {
  830. StartNode(sizeOfExpression);
  831. WriteKeyword(SizeOfExpression.SizeofKeywordRole);
  832. LPar();
  833. Space(policy.SpacesWithinSizeOfParentheses);
  834. sizeOfExpression.Type.AcceptVisitor(this);
  835. Space(policy.SpacesWithinSizeOfParentheses);
  836. RPar();
  837. EndNode(sizeOfExpression);
  838. }
  839. public void VisitStackAllocExpression(StackAllocExpression stackAllocExpression)
  840. {
  841. StartNode(stackAllocExpression);
  842. WriteKeyword(StackAllocExpression.StackallocKeywordRole);
  843. stackAllocExpression.Type.AcceptVisitor(this);
  844. WriteCommaSeparatedListInBrackets(new[] { stackAllocExpression.CountExpression });
  845. EndNode(stackAllocExpression);
  846. }
  847. public void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
  848. {
  849. StartNode(thisReferenceExpression);
  850. WriteKeyword("this", thisReferenceExpression.Role);
  851. EndNode(thisReferenceExpression);
  852. }
  853. public void VisitTypeOfExpression(TypeOfExpression typeOfExpression)
  854. {
  855. StartNode(typeOfExpression);
  856. WriteKeyword(TypeOfExpression.TypeofKeywordRole);
  857. LPar();
  858. Space(policy.SpacesWithinTypeOfParentheses);
  859. typeOfExpression.Type.AcceptVisitor(this);
  860. Space(policy.SpacesWithinTypeOfParentheses);
  861. RPar();
  862. EndNode(typeOfExpression);
  863. }
  864. public void VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression)
  865. {
  866. StartNode(typeReferenceExpression);
  867. typeReferenceExpression.Type.AcceptVisitor(this);
  868. EndNode(typeReferenceExpression);
  869. }
  870. public void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
  871. {
  872. StartNode(unaryOperatorExpression);
  873. UnaryOperatorType opType = unaryOperatorExpression.Operator;
  874. var opSymbol = UnaryOperatorExpression.GetOperatorRole(opType);
  875. if (opType == UnaryOperatorType.Await) {
  876. WriteKeyword(opSymbol);
  877. } else if (!(opType == UnaryOperatorType.PostIncrement || opType == UnaryOperatorType.PostDecrement)) {
  878. WriteToken(opSymbol);
  879. }
  880. unaryOperatorExpression.Expression.AcceptVisitor(this);
  881. if (opType == UnaryOperatorType.PostIncrement || opType == UnaryOperatorType.PostDecrement) {
  882. WriteToken(opSymbol);
  883. }
  884. EndNode(unaryOperatorExpression);
  885. }
  886. public void VisitUncheckedExpression(UncheckedExpression uncheckedExpression)
  887. {
  888. StartNode(uncheckedExpression);
  889. WriteKeyword(UncheckedExpression.UncheckedKeywordRole);
  890. LPar();
  891. Space(policy.SpacesWithinCheckedExpressionParantheses);
  892. uncheckedExpression.Expression.AcceptVisitor(this);
  893. Space(policy.SpacesWithinCheckedExpressionParantheses);
  894. RPar();
  895. EndNode(uncheckedExpression);
  896. }
  897. #endregion
  898. #region Query Expressions
  899. public void VisitQueryExpression(QueryExpression queryExpression)
  900. {
  901. StartNode(queryExpression);
  902. bool indent = queryExpression.Parent is QueryClause && !(queryExpression.Parent is QueryContinuationClause);
  903. if (indent) {
  904. writer.Indent();
  905. NewLine();
  906. }
  907. bool first = true;
  908. foreach (var clause in queryExpression.Clauses) {
  909. if (first) {
  910. first = false;
  911. } else {
  912. if (!(clause is QueryContinuationClause)) {
  913. NewLine();
  914. }
  915. }
  916. clause.AcceptVisitor(this);
  917. }
  918. if (indent) {
  919. writer.Unindent();
  920. }
  921. EndNode(queryExpression);
  922. }
  923. public void VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause)
  924. {
  925. StartNode(queryContinuationClause);
  926. queryContinuationClause.PrecedingQuery.AcceptVisitor(this);
  927. Space();
  928. WriteKeyword(QueryContinuationClause.IntoKeywordRole);
  929. Space();
  930. WriteIdentifier(queryContinuationClause.IdentifierToken);
  931. EndNode(queryContinuationClause);
  932. }
  933. public void VisitQueryFromClause(QueryFromClause queryFromClause)
  934. {
  935. StartNode(queryFromClause);
  936. WriteKeyword(QueryFromClause.FromKeywordRole);
  937. queryFromClause.Type.AcceptVisitor(this);
  938. Space();
  939. WriteIdentifier(queryFromClause.IdentifierToken);
  940. Space();
  941. WriteKeyword(QueryFromClause.InKeywordRole);
  942. Space();
  943. queryFromClause.Expression.AcceptVisitor(this);
  944. EndNode(queryFromClause);
  945. }
  946. public void VisitQueryLetClause(QueryLetClause queryLetClause)
  947. {
  948. StartNode(queryLetClause);
  949. WriteKeyword(QueryLetClause.LetKeywordRole);
  950. Space();
  951. WriteIdentifier(queryLetClause.IdentifierToken);
  952. Space(policy.SpaceAroundAssignment);
  953. WriteToken(Roles.Assign);
  954. Space(policy.SpaceAroundAssignment);
  955. queryLetClause.Expression.AcceptVisitor(this);
  956. EndNode(queryLetClause);
  957. }
  958. public void VisitQueryWhereClause(QueryWhereClause queryWhereClause)
  959. {
  960. StartNode(queryWhereClause);
  961. WriteKeyword(QueryWhereClause.WhereKeywordRole);
  962. Space();
  963. queryWhereClause.Condition.AcceptVisitor(this);
  964. EndNode(queryWhereClause);
  965. }
  966. public void VisitQueryJoinClause(QueryJoinClause queryJoinClause)
  967. {
  968. StartNode(queryJoinClause);
  969. WriteKeyword(QueryJoinClause.JoinKeywordRole);
  970. queryJoinClause.Type.AcceptVisitor(this);
  971. Space();
  972. WriteIdentifier(queryJoinClause.JoinIdentifierToken);
  973. Space();
  974. WriteKeyword(QueryJoinClause.InKeywordRole);
  975. Space();
  976. queryJoinClause.InExpression.AcceptVisitor(this);
  977. Space();
  978. WriteKeyword(QueryJoinClause.OnKeywordRole);
  979. Space();
  980. queryJoinClause.OnExpression.AcceptVisitor(this);
  981. Space();
  982. WriteKeyword(QueryJoinClause.EqualsKeywordRole);
  983. Space();
  984. queryJoinClause.EqualsExpression.AcceptVisitor(this);
  985. if (queryJoinClause.IsGroupJoin) {
  986. Space();
  987. WriteKeyword(QueryJoinClause.IntoKeywordRole);
  988. WriteIdentifier(queryJoinClause.IntoIdentifierToken);
  989. }
  990. EndNode(queryJoinClause);
  991. }
  992. public void VisitQueryOrderClause(QueryOrderClause queryOrderClause)
  993. {
  994. StartNode(queryOrderClause);
  995. WriteKeyword(QueryOrderClause.OrderbyKeywordRole);
  996. Space();
  997. WriteCommaSeparatedList(queryOrderClause.Orderings);
  998. EndNode(queryOrderClause);
  999. }
  1000. public void VisitQueryOrdering(QueryOrdering queryOrdering)
  1001. {
  1002. StartNode(queryOrdering);
  1003. queryOrdering.Expression.AcceptVisitor(this);
  1004. switch (queryOrdering.Direction) {
  1005. case QueryOrderingDirection.Ascending:
  1006. Space();
  1007. WriteKeyword(QueryOrdering.AscendingKeywordRole);
  1008. break;
  1009. case QueryOrderingDirection.Descending:
  1010. Space();
  1011. WriteKeyword(QueryOrdering.DescendingKeywordRole);
  1012. break;
  1013. }
  1014. EndNode(queryOrdering);
  1015. }
  1016. public void VisitQuerySelectClause(QuerySelectClause querySelectClause)
  1017. {
  1018. StartNode(querySelectClause);
  1019. WriteKeyword(QuerySelectClause.SelectKeywordRole);
  1020. Space();
  1021. querySelectClause.Expression.AcceptVisitor(this);
  1022. EndNode(querySelectClause);
  1023. }
  1024. public void VisitQueryGroupClause(QueryGroupClause queryGroupClause)
  1025. {
  1026. StartNode(queryGroupClause);
  1027. WriteKeyword(QueryGroupClause.GroupKeywordRole);
  1028. Space();
  1029. queryGroupClause.Projection.AcceptVisitor(this);
  1030. Space();
  1031. WriteKeyword(QueryGroupClause.ByKeywordRole);
  1032. Space();
  1033. queryGroupClause.Key.AcceptVisitor(this);
  1034. EndNode(queryGroupClause);
  1035. }
  1036. #endregion
  1037. #region GeneralScope
  1038. public void VisitAttribute(Attribute attribute)
  1039. {
  1040. StartNode(attribute);
  1041. attribute.Type.AcceptVisitor(this);
  1042. if (attribute.Arguments.Count != 0 || !attribute.GetChildByRole(Roles.LPar).IsNull) {
  1043. Space(policy.SpaceBeforeMethodCallParentheses);
  1044. WriteCommaSeparatedListInParenthesis(attribute.Arguments, policy.SpaceWithinMethodCallParentheses);
  1045. }
  1046. EndNode(attribute);
  1047. }
  1048. public void VisitAttributeSection(AttributeSection attributeSection)
  1049. {
  1050. StartNode(attributeSection);
  1051. WriteToken(Roles.LBracket);
  1052. if (!string.IsNullOrEmpty(attributeSection.AttributeTarget)) {
  1053. WriteIdentifier(attributeSection.AttributeTargetToken);
  1054. WriteToken(Roles.Colon);
  1055. Space();
  1056. }
  1057. WriteCommaSeparatedList(attributeSection.Attributes);
  1058. WriteToken(Roles.RBracket);
  1059. if (attributeSection.Parent is ParameterDeclaration || attributeSection.Parent is TypeParameterDeclaration) {
  1060. Space();
  1061. } else {
  1062. NewLine();
  1063. }
  1064. EndNode(attributeSection);
  1065. }
  1066. public void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)
  1067. {
  1068. StartNode(delegateDeclaration);
  1069. WriteAttributes(delegateDeclaration.Attributes);
  1070. WriteModifiers(delegateDeclaration.ModifierTokens);
  1071. WriteKeyword(Roles.DelegateKeyword);
  1072. delegateDeclaration.ReturnType.AcceptVisitor(this);
  1073. Space();
  1074. WriteIdentifier(delegateDeclaration.NameToken);
  1075. WriteTypeParameters(delegateDeclaration.TypeParameters);
  1076. Space(policy.SpaceBeforeDelegateDeclarationParentheses);
  1077. WriteCommaSeparatedListInParenthesis(delegateDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
  1078. foreach (Constraint constraint in delegateDeclaration.Constraints) {
  1079. constraint.AcceptVisitor(this);
  1080. }
  1081. Semicolon();
  1082. EndNode(delegateDeclaration);
  1083. }
  1084. public void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
  1085. {
  1086. StartNode(namespaceDeclaration);
  1087. WriteKeyword(Roles.NamespaceKeyword);
  1088. namespaceDeclaration.NamespaceName.AcceptVisitor (this);
  1089. OpenBrace(policy.NamespaceBraceStyle);
  1090. foreach (var member in namespaceDeclaration.Members) {
  1091. member.AcceptVisitor(this);
  1092. MaybeNewLinesAfterUsings(member);
  1093. }
  1094. CloseBrace(policy.NamespaceBraceStyle);
  1095. OptionalSemicolon(namespaceDeclaration.LastChild);
  1096. NewLine();
  1097. EndNode(namespaceDeclaration);
  1098. }
  1099. public void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
  1100. {
  1101. StartNode(typeDeclaration);
  1102. WriteAttributes(typeDeclaration.Attributes);
  1103. WriteModifiers(typeDeclaration.ModifierTokens);
  1104. BraceStyle braceStyle;
  1105. switch (typeDeclaration.ClassType) {
  1106. case ClassType.Enum:
  1107. WriteKeyword(Roles.EnumKeyword);
  1108. braceStyle = policy.EnumBraceStyle;
  1109. break;
  1110. case ClassType.Interface:
  1111. WriteKeyword(Roles.InterfaceKeyword);
  1112. braceStyle = policy.InterfaceBraceStyle;
  1113. break;
  1114. case ClassType.Struct:
  1115. WriteKeyword(Roles.StructKeyword);
  1116. braceStyle = policy.StructBraceStyle;
  1117. break;
  1118. default:
  1119. WriteKeyword(Roles.ClassKeyword);
  1120. braceStyle = policy.ClassBraceStyle;
  1121. break;
  1122. }
  1123. WriteIdentifier(typeDeclaration.NameToken);
  1124. WriteTypeParameters(typeDeclaration.TypeParameters);
  1125. if (typeDeclaration.BaseTypes.Any()) {
  1126. Space();
  1127. WriteToken(Roles.Colon);
  1128. Space();
  1129. WriteCommaSeparatedList(typeDeclaration.BaseTypes);
  1130. }
  1131. foreach (Constraint constraint in typeDeclaration.Constraints) {
  1132. constraint.AcceptVisitor(this);
  1133. }
  1134. OpenBrace(braceStyle);
  1135. if (typeDeclaration.ClassType == ClassType.Enum) {
  1136. bool first = true;
  1137. AstNode last = null;
  1138. foreach (var member in typeDeclaration.Members) {
  1139. if (first) {
  1140. first = false;
  1141. } else {
  1142. Comma(member, noSpaceAfterComma: true);
  1143. NewLine();
  1144. }
  1145. last = member;
  1146. member.AcceptVisitor(this);
  1147. }
  1148. if (last != null)
  1149. OptionalComma(last.NextSibling);
  1150. NewLine();
  1151. } else {
  1152. bool first = true;
  1153. foreach (var member in typeDeclaration.Members) {
  1154. if (!first) {
  1155. for (int i = 0; i < policy.MinimumBlankLinesBetweenMembers; i++)
  1156. NewLine();
  1157. }
  1158. first = false;
  1159. member.AcceptVisitor(this);
  1160. }
  1161. }
  1162. CloseBrace(braceStyle);
  1163. OptionalSemicolon(typeDeclaration.LastChild);
  1164. NewLine();
  1165. EndNode(typeDeclaration);
  1166. }
  1167. public void VisitUsingAliasDeclaration(UsingAliasDeclaration usingAliasDeclaration)
  1168. {
  1169. StartNode(usingAliasDeclaration);
  1170. WriteKeyword(UsingAliasDeclaration.UsingKeywordRole);
  1171. WriteIdentifier(usingAliasDeclaration.GetChildByRole(UsingAliasDeclaration.AliasRole));
  1172. Space(policy.SpaceAroundEqualityOperator);
  1173. WriteToken(Roles.Assign);
  1174. Space(policy.SpaceAroundEqualityOperator);
  1175. usingAliasDeclaration.Import.AcceptVisitor(this);
  1176. Semicolon();
  1177. EndNode(usingAliasDeclaration);
  1178. }
  1179. public void VisitUsingDeclaration(UsingDeclaration usingDeclaration)
  1180. {
  1181. StartNode(usingDeclaration);
  1182. WriteKeyword(UsingDeclaration.UsingKeywordRole);
  1183. usingDeclaration.Import.AcceptVisitor(this);
  1184. Semicolon();
  1185. EndNode(usingDeclaration);
  1186. }
  1187. public void VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration)
  1188. {
  1189. StartNode(externAliasDeclaration);
  1190. WriteKeyword(Roles.ExternKeyword);
  1191. Space();
  1192. WriteKeyword(Roles.AliasKeyword);
  1193. Space();
  1194. WriteIdentifier(externAliasDeclaration.NameToken);
  1195. Semicolon();
  1196. EndNode(externAliasDeclaration);
  1197. }
  1198. #endregion
  1199. #region Statements
  1200. public void VisitBlockStatement(BlockStatement blockStatement)
  1201. {
  1202. StartNode(blockStatement);
  1203. BraceStyle style;
  1204. if (blockStatement.Parent is AnonymousMethodExpression || blockStatement.Parent is LambdaExpression) {
  1205. style = policy.AnonymousMethodBraceStyle;
  1206. } else if (blockStatement.Parent is ConstructorDeclaration) {
  1207. style = policy.ConstructorBraceStyle;
  1208. } else if (blockStatement.Parent is DestructorDeclaration) {
  1209. style = policy.DestructorBraceStyle;
  1210. } else if (blockStatement.Parent is MethodDeclaration) {
  1211. style = policy.MethodBraceStyle;
  1212. } else if (blockStatement.Parent is Accessor) {
  1213. if (blockStatement.Parent.Role == PropertyDeclaration.GetterRole) {
  1214. style = policy.PropertyGetBraceStyle;
  1215. } else if (blockStatement.Parent.Role == PropertyDeclaration.SetterRole) {
  1216. style = policy.PropertySetBraceStyle;
  1217. } else if (blockStatement.Parent.Role == CustomEventDeclaration.AddAccessorRole) {
  1218. style = policy.EventAddBraceStyle;
  1219. } else if (blockStatement.Parent.Role == CustomEventDeclaration.RemoveAccessorRole) {
  1220. style = policy.EventRemoveBraceStyle;
  1221. } else {
  1222. style = policy.StatementBraceStyle;
  1223. }
  1224. } else {
  1225. style = policy.StatementBraceStyle;
  1226. }
  1227. OpenBrace(style);
  1228. foreach (var node in blockStatement.Statements) {
  1229. node.AcceptVisitor(this);
  1230. }
  1231. EndNode(blockStatement);
  1232. CloseBrace(style);
  1233. if (!(blockStatement.Parent is Expression))
  1234. NewLine();
  1235. }
  1236. public void VisitBreakStatement(BreakStatement breakStatement)
  1237. {
  1238. StartNode(breakStatement);
  1239. WriteKeyword("break", BreakStatement.BreakKeywordRole);
  1240. Semicolon();
  1241. EndNode(breakStatement);
  1242. }
  1243. public void VisitCheckedStatement(CheckedStatement checkedStatement)
  1244. {
  1245. StartNode(checkedStatement);
  1246. WriteKeyword(CheckedStatement.CheckedKeywordRole);
  1247. checkedStatement.Body.AcceptVisitor(this);
  1248. EndNode(checkedStatement);
  1249. }
  1250. public void VisitContinueStatement(ContinueStatement continueStatement)
  1251. {
  1252. StartNode(continueStatement);
  1253. WriteKeyword("continue", ContinueStatement.ContinueKeywordRole);
  1254. Semicolon();
  1255. EndNode(continueStatement);
  1256. }
  1257. public void VisitDoWhileStatement(DoWhileStatement doWhileStatement)
  1258. {
  1259. StartNode(doWhileStatement);
  1260. WriteKeyword(DoWhileStatement.DoKeywordRole);
  1261. WriteEmbeddedStatement(doWhileStatement.EmbeddedStatement);
  1262. WriteKeyword(DoWhileStatement.WhileKeywordRole);
  1263. Space(policy.SpaceBeforeWhileParentheses);
  1264. LPar();
  1265. Space(policy.SpacesWithinWhileParentheses);
  1266. doWhileStatement.Condition.AcceptVisitor(this);
  1267. Space(policy.SpacesWithinWhileParentheses);
  1268. RPar();
  1269. Semicolon();
  1270. EndNode(doWhileStatement);
  1271. }
  1272. public void VisitEmptyStatement(EmptyStatement emptyStatement)
  1273. {
  1274. StartNode(emptyStatement);
  1275. Semicolon();
  1276. EndNode(emptyStatement);
  1277. }
  1278. public void VisitExpressionStatement(ExpressionStatement expressionStatement)
  1279. {
  1280. StartNode(expressionStatement);
  1281. expressionStatement.Expression.AcceptVisitor(this);
  1282. Semicolon();
  1283. EndNode(expressionStatement);
  1284. }
  1285. public void VisitFixedStatement(FixedStatement fixedStatement)
  1286. {
  1287. StartNode(fixedStatement);
  1288. WriteKeyword(FixedStatement.FixedKeywordRole);
  1289. Space(policy.SpaceBeforeUsingParentheses);
  1290. LPar();
  1291. Space(policy.SpacesWithinUsingParentheses);
  1292. fixedStatement.Type.AcceptVisitor(this);
  1293. Space();
  1294. WriteCommaSeparatedList(fixedStatement.Variables);
  1295. Space(policy.SpacesWithinUsingParentheses);
  1296. RPar();
  1297. WriteEmbeddedStatement(fixedStatement.EmbeddedStatement);
  1298. EndNode(fixedStatement);
  1299. }
  1300. public void VisitForeachStatement(ForeachStatement foreachStatement)
  1301. {
  1302. StartNode(foreachStatement);
  1303. WriteKeyword(ForeachStatement.ForeachKeywordRole);
  1304. Space(policy.SpaceBeforeForeachParentheses);
  1305. LPar();
  1306. Space(policy.SpacesWithinForeachParentheses);
  1307. foreachStatement.VariableType.AcceptVisitor(this);
  1308. Space();
  1309. WriteIdentifier(foreachStatement.VariableNameToken);
  1310. WriteKeyword(ForeachStatement.InKeywordRole);
  1311. Space();
  1312. foreachStatement.InExpression.AcceptVisitor(this);
  1313. Space(policy.SpacesWithinForeachParentheses);
  1314. RPar();
  1315. WriteEmbeddedStatement(foreachStatement.EmbeddedStatement);
  1316. EndNode(foreachStatement);
  1317. }
  1318. public void VisitForStatement(ForStatement forStatement)
  1319. {
  1320. StartNode(forStatement);
  1321. WriteKeyword(ForStatement.ForKeywordRole);
  1322. Space(policy.SpaceBeforeForParentheses);
  1323. LPar();
  1324. Space(policy.SpacesWithinForParentheses);
  1325. WriteCommaSeparatedList(forStatement.Initializers);
  1326. Space(policy.SpaceBeforeForSemicolon);
  1327. WriteToken(Roles.Semicolon);
  1328. Space(policy.SpaceAfterForSemicolon);
  1329. forStatement.Condition.AcceptVisitor(this);
  1330. Space(policy.SpaceBeforeForSemicolon);
  1331. WriteToken(Roles.Semicolon);
  1332. if (forStatement.Iterators.Any()) {
  1333. Space(policy.SpaceAfterForSemicolon);
  1334. WriteCommaSeparatedList(forStatement.Iterators);
  1335. }
  1336. Space(policy.SpacesWithinForParentheses);
  1337. RPar();
  1338. WriteEmbeddedStatement(forStatement.EmbeddedStatement);
  1339. EndNode(forStatement);
  1340. }
  1341. public void VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement)
  1342. {
  1343. StartNode(gotoCaseStatement);
  1344. WriteKeyword(GotoCaseStatement.GotoKeywordRole);
  1345. WriteKeyword(GotoCaseStatement.CaseKeywordRole);
  1346. Space();
  1347. gotoCaseStatement.LabelExpression.AcceptVisitor(this);
  1348. Semicolon();
  1349. EndNode(gotoCaseStatement);
  1350. }
  1351. public void VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement)
  1352. {
  1353. StartNode(gotoDefaultStatement);
  1354. WriteKeyword(GotoDefaultStatement.GotoKeywordRole);
  1355. WriteKeyword(GotoDefaultStatement.DefaultKeywordRole);
  1356. Semicolon();
  1357. EndNode(gotoDefaultStatement);
  1358. }
  1359. public void VisitGotoStatement(GotoStatement gotoStatement)
  1360. {
  1361. StartNode(gotoStatement);
  1362. WriteKeyword(GotoStatement.GotoKeywordRole);
  1363. WriteIdentifier(gotoStatement.GetChildByRole(Roles.Identifier));
  1364. Semicolon();
  1365. EndNode(gotoStatement);
  1366. }
  1367. public void VisitIfElseStatement(IfElseStatement ifElseStatement)
  1368. {
  1369. StartNode(ifElseStatement);
  1370. WriteKeyword(IfElseStatement.IfKeywordRole);
  1371. Space(policy.SpaceBeforeIfParentheses);
  1372. LPar();
  1373. Space(policy.SpacesWithinIfParentheses);
  1374. ifElseStatement.Condition.AcceptVisitor(this);
  1375. Space(policy.SpacesWithinIfParentheses);
  1376. RPar();
  1377. WriteEmbeddedStatement(ifElseStatement.TrueStatement);
  1378. if (!ifElseStatement.FalseStatement.IsNull) {
  1379. WriteKeyword(IfElseStatement.ElseKeywordRole);
  1380. if (ifElseStatement.FalseStatement is IfElseStatement) {
  1381. // don't put newline between 'else' and 'if'
  1382. ifElseStatement.FalseStatement.AcceptVisitor(this);
  1383. } else {
  1384. WriteEmbeddedStatement(ifElseStatement.FalseStatement);
  1385. }
  1386. }
  1387. EndNode(ifElseStatement);
  1388. }
  1389. public void VisitLabelStatement(LabelStatement labelStatement)
  1390. {
  1391. StartNode(labelStatement);
  1392. WriteIdentifier(labelStatement.GetChildByRole(Roles.Identifier));
  1393. WriteToken(Roles.Colon);
  1394. bool foundLabelledStatement = false;
  1395. for (AstNode tmp = labelStatement.NextSibling; tmp != null; tmp = tmp.NextSibling) {
  1396. if (tmp.Role == labelStatement.Role) {
  1397. foundLabelledStatement = true;
  1398. }
  1399. }
  1400. if (!foundLabelledStatement) {
  1401. // introduce an EmptyStatement so that the output becomes syntactically valid
  1402. WriteToken(Roles.Semicolon);
  1403. }
  1404. NewLine();
  1405. EndNode(labelStatement);
  1406. }
  1407. public void VisitLockStatement(LockStatement lockStatement)
  1408. {
  1409. StartNode(lockStatement);
  1410. WriteKeyword(LockStatement.LockKeywordRole);
  1411. Space(policy.SpaceBeforeLockParentheses);
  1412. LPar();
  1413. Space(policy.SpacesWithinLockParentheses);
  1414. lockStatement.Expression.AcceptVisitor(this);
  1415. Space(policy.SpacesWithinLockParentheses);
  1416. RPar();
  1417. WriteEmbeddedStatement(lockStatement.EmbeddedStatement);
  1418. EndNode(lockStatement);
  1419. }
  1420. public void VisitReturnStatement(ReturnStatement returnStatement)
  1421. {
  1422. StartNode(returnStatement);
  1423. WriteKeyword(ReturnStatement.ReturnKeywordRole);
  1424. if (!returnStatement.Expression.IsNull) {
  1425. Space();
  1426. returnStatement.Expression.AcceptVisitor(this);
  1427. }
  1428. Semicolon();
  1429. EndNode(returnStatement);
  1430. }
  1431. public void VisitSwitchStatement(SwitchStatement switchStatement)
  1432. {
  1433. StartNode(switchStatement);
  1434. WriteKeyword(SwitchStatement.SwitchKeywordRole);
  1435. Space(policy.SpaceBeforeSwitchParentheses);
  1436. LPar();
  1437. Space(policy.SpacesWithinSwitchParentheses);
  1438. switchStatement.Expression.AcceptVisitor(this);
  1439. Space(policy.SpacesWithinSwitchParentheses);
  1440. RPar();
  1441. OpenBrace(policy.StatementBraceStyle);
  1442. if (!policy.IndentSwitchBody) {
  1443. writer.Unindent();
  1444. }
  1445. foreach (var section in switchStatement.SwitchSections) {
  1446. section.AcceptVisitor(this);
  1447. }
  1448. if (!policy.IndentSwitchBody) {
  1449. writer.Indent();
  1450. }
  1451. CloseBrace(policy.StatementBraceStyle);
  1452. NewLine();
  1453. EndNode(switchStatement);
  1454. }
  1455. public void VisitSwitchSection(SwitchSection switchSection)
  1456. {
  1457. StartNode(switchSection);
  1458. bool first = true;
  1459. foreach (var label in switchSection.CaseLabels) {
  1460. if (!first) {
  1461. NewLine();
  1462. }
  1463. label.AcceptVisitor(this);
  1464. first = false;
  1465. }
  1466. bool isBlock = switchSection.Statements.Count == 1 && switchSection.Statements.Single() is BlockStatement;
  1467. if (policy.IndentCaseBody && !isBlock) {
  1468. writer.Indent();
  1469. }
  1470. if (!isBlock)
  1471. NewLine();
  1472. foreach (var statement in switchSection.Statements) {
  1473. statement.AcceptVisitor(this);
  1474. }
  1475. if (policy.IndentCaseBody && !isBlock) {
  1476. writer.Unindent();
  1477. }
  1478. EndNode(switchSection);
  1479. }
  1480. public void VisitCaseLabel(CaseLabel caseLabel)
  1481. {
  1482. StartNode(caseLabel);
  1483. if (caseLabel.Expression.IsNull) {
  1484. WriteKeyword(CaseLabel.DefaultKeywordRole);
  1485. } else {
  1486. WriteKeyword(CaseLabel.CaseKeywordRole);
  1487. Space();
  1488. caseLabel.Expression.AcceptVisitor(this);
  1489. }
  1490. WriteToken(Roles.Colon);
  1491. EndNode(caseLabel);
  1492. }
  1493. public void VisitThrowStatement(ThrowStatement throwStatement)
  1494. {
  1495. StartNode(throwStatement);
  1496. WriteKeyword(ThrowStatement.ThrowKeywordRole);
  1497. if (!throwStatement.Expression.IsNull) {
  1498. Space();
  1499. throwStatement.Expression.AcceptVisitor(this);
  1500. }
  1501. Semicolon();
  1502. EndNode(throwStatement);
  1503. }
  1504. public void VisitTryCatchStatement(TryCatchStatement tryCatchStatement)
  1505. {
  1506. StartNode(tryCatchStatement);
  1507. WriteKeyword(TryCatchStatement.TryKeywordRole);
  1508. tryCatchStatement.TryBlock.AcceptVisitor(this);
  1509. foreach (var catchClause in tryCatchStatement.CatchClauses) {
  1510. catchClause.AcceptVisitor(this);
  1511. }
  1512. if (!tryCatchStatement.FinallyBlock.IsNull) {
  1513. WriteKeyword(TryCatchStatement.FinallyKeywordRole);
  1514. tryCatchStatement.FinallyBlock.AcceptVisitor(this);
  1515. }
  1516. EndNode(tryCatchStatement);
  1517. }
  1518. public void VisitCatchClause(CatchClause catchClause)
  1519. {
  1520. StartNode(catchClause);
  1521. WriteKeyword(CatchClause.CatchKeywordRole);
  1522. if (!catchClause.Type.IsNull) {
  1523. Space(policy.SpaceBeforeCatchParentheses);
  1524. LPar();
  1525. Space(policy.SpacesWithinCatchParentheses);
  1526. catchClause.Type.AcceptVisitor(this);
  1527. if (!string.IsNullOrEmpty(catchClause.VariableName)) {
  1528. Space();
  1529. WriteIdentifier(catchClause.VariableNameToken);
  1530. }
  1531. Space(policy.SpacesWithinCatchParentheses);
  1532. RPar();
  1533. }
  1534. catchClause.Body.AcceptVisitor(this);
  1535. EndNode(catchClause);
  1536. }
  1537. public void VisitUncheckedStatement(UncheckedStatement uncheckedStatement)
  1538. {
  1539. StartNode(uncheckedStatement);
  1540. WriteKeyword(UncheckedStatement.UncheckedKeywordRole);
  1541. uncheckedStatement.Body.AcceptVisitor(this);
  1542. EndNode(uncheckedStatement);
  1543. }
  1544. public void VisitUnsafeStatement(UnsafeStatement unsafeStatement)
  1545. {
  1546. StartNode(unsafeStatement);
  1547. WriteKeyword(UnsafeStatement.UnsafeKeywordRole);
  1548. unsafeStatement.Body.AcceptVisitor(this);
  1549. EndNode(unsafeStatement);
  1550. }
  1551. public void VisitUsingStatement(UsingStatement usingStatement)
  1552. {
  1553. StartNode(usingStatement);
  1554. WriteKeyword(UsingStatement.UsingKeywordRole);
  1555. Space(policy.SpaceBeforeUsingParentheses);
  1556. LPar();
  1557. Space(policy.SpacesWithinUsingParentheses);
  1558. usingStatement.ResourceAcquisition.AcceptVisitor(this);
  1559. Space(policy.SpacesWithinUsingParentheses);
  1560. RPar();
  1561. WriteEmbeddedStatement(usingStatement.EmbeddedStatement);
  1562. EndNode(usingStatement);
  1563. }
  1564. public void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement)
  1565. {
  1566. StartNode(variableDeclarationStatement);
  1567. WriteModifiers(variableDeclarationStatement.GetChildrenByRole(VariableDeclarationStatement.ModifierRole));
  1568. variableDeclarationStatement.Type.AcceptVisitor(this);
  1569. Space();
  1570. WriteCommaSeparatedList(variableDeclarationStatement.Variables);
  1571. Semicolon();
  1572. EndNode(variableDeclarationStatement);
  1573. }
  1574. public void VisitWhileStatement(WhileStatement whileStatement)
  1575. {
  1576. StartNode(whileStatement);
  1577. WriteKeyword(WhileStatement.WhileKeywordRole);
  1578. Space(policy.SpaceBeforeWhileParentheses);
  1579. LPar();
  1580. Space(policy.SpacesWithinWhileParentheses);
  1581. whileStatement.Condition.AcceptVisitor(this);
  1582. Space(policy.SpacesWithinWhileParentheses);
  1583. RPar();
  1584. WriteEmbeddedStatement(whileStatement.EmbeddedStatement);
  1585. EndNode(whileStatement);
  1586. }
  1587. public void VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement)
  1588. {
  1589. StartNode(yieldBreakStatement);
  1590. WriteKeyword(YieldBreakStatement.YieldKeywordRole);
  1591. WriteKeyword(YieldBreakStatement.BreakKeywordRole);
  1592. Semicolon();
  1593. EndNode(yieldBreakStatement);
  1594. }
  1595. public void VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement)
  1596. {
  1597. StartNode(yieldReturnStatement);
  1598. WriteKeyword(YieldReturnStatement.YieldKeywordRole);
  1599. WriteKeyword(YieldReturnStatement.ReturnKeywordRole);
  1600. Space();
  1601. yieldReturnStatement.Expression.AcceptVisitor(this);
  1602. Semicolon();
  1603. EndNode(yieldReturnStatement);
  1604. }
  1605. #endregion
  1606. #region TypeMembers
  1607. public void VisitAccessor(Accessor accessor)
  1608. {
  1609. StartNode(accessor);
  1610. WriteAttributes(accessor.Attributes);
  1611. WriteModifiers(accessor.ModifierTokens);
  1612. if (accessor.Role == PropertyDeclaration.GetterRole) {
  1613. WriteKeyword("get", PropertyDeclaration.GetKeywordRole);
  1614. } else if (accessor.Role == PropertyDeclaration.SetterRole) {
  1615. WriteKeyword("set", PropertyDeclaration.SetKeywordRole);
  1616. } else if (accessor.Role == CustomEventDeclaration.AddAccessorRole) {
  1617. WriteKeyword("add", CustomEventDeclaration.AddKeywordRole);
  1618. } else if (accessor.Role == CustomEventDeclaration.RemoveAccessorRole) {
  1619. WriteKeyword("remove", CustomEventDeclaration.RemoveKeywordRole);
  1620. }
  1621. WriteMethodBody(accessor.Body);
  1622. EndNode(accessor);
  1623. }
  1624. public void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
  1625. {
  1626. StartNode(constructorDeclaration);
  1627. WriteAttributes(constructorDeclaration.Attributes);
  1628. WriteModifiers(constructorDeclaration.ModifierTokens);
  1629. TypeDeclaration type = constructorDeclaration.Parent as TypeDeclaration;
  1630. if (type != null && type.Name != constructorDeclaration.Name)
  1631. WriteIdentifier((Identifier)type.NameToken.Clone());
  1632. else
  1633. WriteIdentifier(constructorDeclaration.NameToken);
  1634. Space(policy.SpaceBeforeConstructorDeclarationParentheses);
  1635. WriteCommaSeparatedListInParenthesis(constructorDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
  1636. if (!constructorDeclaration.Initializer.IsNull) {
  1637. Space();
  1638. constructorDeclaration.Initializer.AcceptVisitor(this);
  1639. }
  1640. WriteMethodBody(constructorDeclaration.Body);
  1641. EndNode(constructorDeclaration);
  1642. }
  1643. public void VisitConstructorInitializer(ConstructorInitializer constructorInitializer)
  1644. {
  1645. StartNode(constructorInitializer);
  1646. WriteToken(Roles.Colon);
  1647. Space();
  1648. if (constructorInitializer.ConstructorInitializerType == ConstructorInitializerType.This) {
  1649. WriteKeyword(ConstructorInitializer.ThisKeywordRole);
  1650. } else {
  1651. WriteKeyword(ConstructorInitializer.BaseKeywordRole);
  1652. }
  1653. Space(policy.SpaceBeforeMethodCallParentheses);
  1654. WriteCommaSeparatedListInParenthesis(constructorInitializer.Arguments, policy.SpaceWithinMethodCallParentheses);
  1655. EndNode(constructorInitializer);
  1656. }
  1657. public void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)
  1658. {
  1659. StartNode(destructorDeclaration);
  1660. WriteAttributes(destructorDeclaration.Attributes);
  1661. WriteModifiers(destructorDeclaration.ModifierTokens);
  1662. WriteToken(DestructorDeclaration.TildeRole);
  1663. TypeDeclaration type = destructorDeclaration.Parent as TypeDeclaration;
  1664. if (type != null && type.Name != destructorDeclaration.Name)
  1665. WriteIdentifier((Identifier)type.NameToken.Clone());
  1666. else
  1667. WriteIdentifier(destructorDeclaration.NameToken);
  1668. Space(policy.SpaceBeforeConstructorDeclarationParentheses);
  1669. LPar();
  1670. RPar();
  1671. WriteMethodBody(destructorDeclaration.Body);
  1672. EndNode(destructorDeclaration);
  1673. }
  1674. public void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration)
  1675. {
  1676. StartNode(enumMemberDeclaration);
  1677. WriteAttributes(enumMemberDeclaration.Attributes);
  1678. WriteModifiers(enumMemberDeclaration.ModifierTokens);
  1679. WriteIdentifier(enumMemberDeclaration.NameToken);
  1680. if (!enumMemberDeclaration.Initializer.IsNull) {
  1681. Space(policy.SpaceAroundAssignment);
  1682. WriteToken(Roles.Assign);
  1683. Space(policy.SpaceAroundAssignment);
  1684. enumMemberDeclaration.Initializer.AcceptVisitor(this);
  1685. }
  1686. EndNode(enumMemberDeclaration);
  1687. }
  1688. public void VisitEventDeclaration(EventDeclaration eventDeclaration)
  1689. {
  1690. StartNode(eventDeclaration);
  1691. WriteAttributes(eventDeclaration.Attributes);
  1692. WriteModifiers(eventDeclaration.ModifierTokens);
  1693. WriteKeyword(EventDeclaration.EventKeywordRole);
  1694. eventDeclaration.ReturnType.AcceptVisitor(this);
  1695. Space();
  1696. WriteCommaSeparatedList(eventDeclaration.Variables);
  1697. Semicolon();
  1698. EndNode(eventDeclaration);
  1699. }
  1700. public void VisitCustomEventDeclaration(CustomEventDeclaration customEventDeclaration)
  1701. {
  1702. StartNode(customEventDeclaration);
  1703. WriteAttributes(customEventDeclaration.Attributes);
  1704. WriteModifiers(customEventDeclaration.ModifierTokens);
  1705. WriteKeyword(CustomEventDeclaration.EventKeywordRole);
  1706. customEventDeclaration.ReturnType.AcceptVisitor(this);
  1707. Space();
  1708. WritePrivateImplementationType(customEventDeclaration.PrivateImplementationType);
  1709. WriteIdentifier(customEventDeclaration.NameToken);
  1710. OpenBrace(policy.EventBraceStyle);
  1711. // output add/remove in their original order
  1712. foreach (AstNode node in customEventDeclaration.Children) {
  1713. if (node.Role == CustomEventDeclaration.AddAccessorRole || node.Role == CustomEventDeclaration.RemoveAccessorRole) {
  1714. node.AcceptVisitor(this);
  1715. }
  1716. }
  1717. CloseBrace(policy.EventBraceStyle);
  1718. NewLine();
  1719. EndNode(customEventDeclaration);
  1720. }
  1721. public void VisitFieldDeclaration(FieldDeclaration fieldDeclaration)
  1722. {
  1723. StartNode(fieldDeclaration);
  1724. WriteAttributes(fieldDeclaration.Attributes);
  1725. WriteModifiers(fieldDeclaration.ModifierTokens);
  1726. fieldDeclaration.ReturnType.AcceptVisitor(this);
  1727. Space();
  1728. WriteCommaSeparatedList(fieldDeclaration.Variables);
  1729. Semicolon();
  1730. EndNode(fieldDeclaration);
  1731. }
  1732. public void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration)
  1733. {
  1734. StartNode(fixedFieldDeclaration);
  1735. WriteAttributes(fixedFieldDeclaration.Attributes);
  1736. WriteModifiers(fixedFieldDeclaration.ModifierTokens);
  1737. WriteKeyword(FixedFieldDeclaration.FixedKeywordRole);
  1738. Space();
  1739. fixedFieldDeclaration.ReturnType.AcceptVisitor(this);
  1740. Space();
  1741. WriteCommaSeparatedList(fixedFieldDeclaration.Variables);
  1742. Semicolon();
  1743. EndNode(fixedFieldDeclaration);
  1744. }
  1745. public void VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer)
  1746. {
  1747. StartNode(fixedVariableInitializer);
  1748. WriteIdentifier(fixedVariableInitializer.NameToken);
  1749. if (!fixedVariableInitializer.CountExpression.IsNull) {
  1750. WriteToken(Roles.LBracket);
  1751. Space(policy.SpacesWithinBrackets);
  1752. fixedVariableInitializer.CountExpression.AcceptVisitor(this);
  1753. Space(policy.SpacesWithinBrackets);
  1754. WriteToken(Roles.RBracket);
  1755. }
  1756. EndNode(fixedVariableInitializer);
  1757. }
  1758. public void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
  1759. {
  1760. StartNode(indexerDeclaration);
  1761. WriteAttributes(indexerDeclaration.Attributes);
  1762. WriteModifiers(indexerDeclaration.ModifierTokens);
  1763. indexerDeclaration.ReturnType.AcceptVisitor(this);
  1764. Space();
  1765. WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType);
  1766. WriteKeyword(IndexerDeclaration.ThisKeywordRole);
  1767. Space(policy.SpaceBeforeMethodDeclarationParentheses);
  1768. WriteCommaSeparatedListInBrackets(indexerDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
  1769. OpenBrace(policy.PropertyBraceStyle);
  1770. // output get/set in their original order
  1771. foreach (AstNode node in indexerDeclaration.Children) {
  1772. if (node.Role == IndexerDeclaration.GetterRole || node.Role == IndexerDeclaration.SetterRole) {
  1773. node.AcceptVisitor(this);
  1774. }
  1775. }
  1776. CloseBrace(policy.PropertyBraceStyle);
  1777. NewLine();
  1778. EndNode(indexerDeclaration);
  1779. }
  1780. public void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
  1781. {
  1782. StartNode(methodDeclaration);
  1783. WriteAttributes(methodDeclaration.Attributes);
  1784. WriteModifiers(methodDeclaration.ModifierTokens);
  1785. methodDeclaration.ReturnType.AcceptVisitor(this);
  1786. Space();
  1787. WritePrivateImplementationType(methodDeclaration.PrivateImplementationType);
  1788. WriteIdentifier(methodDeclaration.NameToken);
  1789. WriteTypeParameters(methodDeclaration.TypeParameters);
  1790. Space(policy.SpaceBeforeMethodDeclarationParentheses);
  1791. WriteCommaSeparatedListInParenthesis(methodDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
  1792. foreach (Constraint constraint in methodDeclaration.Constraints) {
  1793. constraint.AcceptVisitor(this);
  1794. }
  1795. WriteMethodBody(methodDeclaration.Body);
  1796. EndNode(methodDeclaration);
  1797. }
  1798. public void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
  1799. {
  1800. StartNode(operatorDeclaration);
  1801. WriteAttributes(operatorDeclaration.Attributes);
  1802. WriteModifiers(operatorDeclaration.ModifierTokens);
  1803. if (operatorDeclaration.OperatorType == OperatorType.Explicit) {
  1804. WriteKeyword(OperatorDeclaration.ExplicitRole);
  1805. } else if (operatorDeclaration.OperatorType == OperatorType.Implicit) {
  1806. WriteKeyword(OperatorDeclaration.ImplicitRole);
  1807. } else {
  1808. operatorDeclaration.ReturnType.AcceptVisitor(this);
  1809. }
  1810. WriteKeyword(OperatorDeclaration.OperatorKeywordRole);
  1811. Space();
  1812. if (operatorDeclaration.OperatorType == OperatorType.Explicit
  1813. || operatorDeclaration.OperatorType == OperatorType.Implicit) {
  1814. operatorDeclaration.ReturnType.AcceptVisitor(this);
  1815. } else {
  1816. WriteToken(OperatorDeclaration.GetToken(operatorDeclaration.OperatorType), OperatorDeclaration.GetRole(operatorDeclaration.OperatorType));
  1817. }
  1818. Space(policy.SpaceBeforeMethodDeclarationParentheses);
  1819. WriteCommaSeparatedListInParenthesis(operatorDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
  1820. WriteMethodBody(operatorDeclaration.Body);
  1821. EndNode(operatorDeclaration);
  1822. }
  1823. public void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
  1824. {
  1825. StartNode(parameterDeclaration);
  1826. WriteAttributes(parameterDeclaration.Attributes);
  1827. switch (parameterDeclaration.ParameterModifier) {
  1828. case ParameterModifier.Ref:
  1829. WriteKeyword(ParameterDeclaration.RefModifierRole);
  1830. break;
  1831. case ParameterModifier.Out:
  1832. WriteKeyword(ParameterDeclaration.OutModifierRole);
  1833. break;
  1834. case ParameterModifier.Params:
  1835. WriteKeyword(ParameterDeclaration.ParamsModifierRole);
  1836. break;
  1837. case ParameterModifier.This:
  1838. WriteKeyword(ParameterDeclaration.ThisModifierRole);
  1839. break;
  1840. }
  1841. parameterDeclaration.Type.AcceptVisitor(this);
  1842. if (!parameterDeclaration.Type.IsNull && !string.IsNullOrEmpty(parameterDeclaration.Name)) {
  1843. Space();
  1844. }
  1845. if (!string.IsNullOrEmpty(parameterDeclaration.Name)) {
  1846. WriteIdentifier(parameterDeclaration.NameToken);
  1847. }
  1848. if (!parameterDeclaration.DefaultExpression.IsNull) {
  1849. Space(policy.SpaceAroundAssignment);
  1850. WriteToken(Roles.Assign);
  1851. Space(policy.SpaceAroundAssignment);
  1852. parameterDeclaration.DefaultExpression.AcceptVisitor(this);
  1853. }
  1854. EndNode(parameterDeclaration);
  1855. }
  1856. public void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
  1857. {
  1858. StartNode(propertyDeclaration);
  1859. WriteAttributes(propertyDeclaration.Attributes);
  1860. WriteModifiers(propertyDeclaration.ModifierTokens);
  1861. propertyDeclaration.ReturnType.AcceptVisitor(this);
  1862. Space();
  1863. WritePrivateImplementationType(propertyDeclaration.PrivateImplementationType);
  1864. WriteIdentifier(propertyDeclaration.NameToken);
  1865. OpenBrace(policy.PropertyBraceStyle);
  1866. // output get/set in their original order
  1867. foreach (AstNode node in propertyDeclaration.Children) {
  1868. if (node.Role == IndexerDeclaration.GetterRole || node.Role == IndexerDeclaration.SetterRole) {
  1869. node.AcceptVisitor(this);
  1870. }
  1871. }
  1872. CloseBrace(policy.PropertyBraceStyle);
  1873. NewLine();
  1874. EndNode(propertyDeclaration);
  1875. }
  1876. #endregion
  1877. #region Other nodes
  1878. public void VisitVariableInitializer(VariableInitializer variableInitializer)
  1879. {
  1880. StartNode(variableInitializer);
  1881. WriteIdentifier(variableInitializer.NameToken);
  1882. if (!variableInitializer.Initializer.IsNull) {
  1883. Space(policy.SpaceAroundAssignment);
  1884. WriteToken(Roles.Assign);
  1885. Space(policy.SpaceAroundAssignment);
  1886. variableInitializer.Initializer.AcceptVisitor(this);
  1887. }
  1888. EndNode(variableInitializer);
  1889. }
  1890. void MaybeNewLinesAfterUsings(AstNode node)
  1891. {
  1892. var nextSibling = node.NextSibling;
  1893. while (nextSibling is WhitespaceNode || nextSibling is NewLineNode)
  1894. nextSibling = nextSibling.NextSibling;
  1895. if ((node is UsingDeclaration || node is UsingAliasDeclaration) && !(nextSibling is UsingDeclaration || nextSibling is UsingAliasDeclaration)) {
  1896. for (int i = 0; i < policy.MinimumBlankLinesAfterUsings; i++)
  1897. NewLine();
  1898. }
  1899. }
  1900. public void VisitSyntaxTree(SyntaxTree syntaxTree)
  1901. {
  1902. // don't do node tracking as we visit all children directly
  1903. foreach (AstNode node in syntaxTree.Children) {
  1904. node.AcceptVisitor(this);
  1905. MaybeNewLinesAfterUsings(node);
  1906. }
  1907. }
  1908. public void VisitSimpleType(SimpleType simpleType)
  1909. {
  1910. StartNode(simpleType);
  1911. WriteIdentifier(simpleType.IdentifierToken);
  1912. WriteTypeArguments(simpleType.TypeArguments);
  1913. EndNode(simpleType);
  1914. }
  1915. public void VisitMemberType(MemberType memberType)
  1916. {
  1917. StartNode(memberType);
  1918. memberType.Target.AcceptVisitor(this);
  1919. if (memberType.IsDoubleColon) {
  1920. WriteToken(Roles.DoubleColon);
  1921. } else {
  1922. WriteToken(Roles.Dot);
  1923. }
  1924. WriteIdentifier(memberType.MemberNameToken);
  1925. WriteTypeArguments(memberType.TypeArguments);
  1926. EndNode(memberType);
  1927. }
  1928. public void VisitComposedType(ComposedType composedType)
  1929. {
  1930. StartNode(composedType);
  1931. composedType.BaseType.AcceptVisitor(this);
  1932. if (composedType.HasNullableSpecifier) {
  1933. WriteToken(ComposedType.NullableRole);
  1934. }
  1935. for (int i = 0; i < composedType.PointerRank; i++) {
  1936. WriteToken(ComposedType.PointerRole);
  1937. }
  1938. foreach (var node in composedType.ArraySpecifiers) {
  1939. node.AcceptVisitor(this);
  1940. }
  1941. EndNode(composedType);
  1942. }
  1943. public void VisitArraySpecifier(ArraySpecifier arraySpecifier)
  1944. {
  1945. StartNode(arraySpecifier);
  1946. WriteToken(Roles.LBracket);
  1947. foreach (var comma in arraySpecifier.GetChildrenByRole(Roles.Comma)) {
  1948. writer.WriteToken(Roles.Comma, ",");
  1949. }
  1950. WriteToken(Roles.RBracket);
  1951. EndNode(arraySpecifier);
  1952. }
  1953. public void VisitPrimitiveType(PrimitiveType primitiveType)
  1954. {
  1955. StartNode(primitiveType);
  1956. writer.WritePrimitiveType(primitiveType.Keyword);
  1957. EndNode(primitiveType);
  1958. }
  1959. public void VisitComment(Comment comment)
  1960. {
  1961. writer.StartNode(comment);
  1962. writer.WriteComment(comment.CommentType, comment.Content);
  1963. writer.EndNode(comment);
  1964. }
  1965. public void VisitNewLine(NewLineNode newLineNode)
  1966. {
  1967. // formatter.StartNode(newLineNode);
  1968. // formatter.NewLine();
  1969. // formatter.EndNode(newLineNode);
  1970. }
  1971. public void VisitWhitespace(WhitespaceNode whitespaceNode)
  1972. {
  1973. // unused
  1974. }
  1975. public void VisitText(TextNode textNode)
  1976. {
  1977. // unused
  1978. }
  1979. public void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective)
  1980. {
  1981. writer.StartNode(preProcessorDirective);
  1982. writer.WritePreProcessorDirective(preProcessorDirective.Type, preProcessorDirective.Argument);
  1983. writer.EndNode(preProcessorDirective);
  1984. }
  1985. public void VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration)
  1986. {
  1987. StartNode(typeParameterDeclaration);
  1988. WriteAttributes(typeParameterDeclaration.Attributes);
  1989. switch (typeParameterDeclaration.Variance) {
  1990. case VarianceModifier.Invariant:
  1991. break;
  1992. case VarianceModifier.Covariant:
  1993. WriteKeyword(TypeParameterDeclaration.OutVarianceKeywordRole);
  1994. break;
  1995. case VarianceModifier.Contravariant:
  1996. WriteKeyword(TypeParameterDeclaration.InVarianceKeywordRole);
  1997. break;
  1998. default:
  1999. throw new NotSupportedException ("Invalid value for VarianceModifier");
  2000. }
  2001. WriteIdentifier(typeParameterDeclaration.NameToken);
  2002. EndNode(typeParameterDeclaration);
  2003. }
  2004. public void VisitConstraint(Constraint constraint)
  2005. {
  2006. StartNode(constraint);
  2007. Space();
  2008. WriteKeyword(Roles.WhereKeyword);
  2009. constraint.TypeParameter.AcceptVisitor(this);
  2010. Space();
  2011. WriteToken(Roles.Colon);
  2012. Space();
  2013. WriteCommaSeparatedList(constraint.BaseTypes);
  2014. EndNode(constraint);
  2015. }
  2016. public void VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode)
  2017. {
  2018. CSharpModifierToken mod = cSharpTokenNode as CSharpModifierToken;
  2019. if (mod != null) {
  2020. // ITokenWriter assumes that each node processed between a
  2021. // StartNode(parentNode)-EndNode(parentNode)-pair is a child of parentNode.
  2022. WriteKeyword(CSharpModifierToken.GetModifierName(mod.Modifier), cSharpTokenNode.Role);
  2023. } else {
  2024. throw new NotSupportedException ("Should never visit individual tokens");
  2025. }
  2026. }
  2027. public void VisitIdentifier(Identifier identifier)
  2028. {
  2029. // Do not call StartNode and EndNode for Identifier, because they are handled by the ITokenWriter.
  2030. // ITokenWriter assumes that each node processed between a
  2031. // StartNode(parentNode)-EndNode(parentNode)-pair is a child of parentNode.
  2032. WriteIdentifier(identifier);
  2033. }
  2034. void IAstVisitor.VisitNullNode(AstNode nullNode)
  2035. {
  2036. }
  2037. void IAstVisitor.VisitErrorNode(AstNode errorNode)
  2038. {
  2039. StartNode(errorNode);
  2040. EndNode(errorNode);
  2041. }
  2042. #endregion
  2043. #region Pattern Nodes
  2044. public void VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern)
  2045. {
  2046. StartNode(placeholder);
  2047. VisitNodeInPattern(pattern);
  2048. EndNode(placeholder);
  2049. }
  2050. void VisitAnyNode(AnyNode anyNode)
  2051. {
  2052. if (!string.IsNullOrEmpty(anyNode.GroupName)) {
  2053. WriteIdentifier(anyNode.GroupName);
  2054. WriteToken(Roles.Colon);
  2055. }
  2056. }
  2057. void VisitBackreference(Backreference backreference)
  2058. {
  2059. WriteKeyword("backreference");
  2060. LPar();
  2061. WriteIdentifier(backreference.ReferencedGroupName);
  2062. RPar();
  2063. }
  2064. void VisitIdentifierExpressionBackreference(IdentifierExpressionBackreference identifierExpressionBackreference)
  2065. {
  2066. WriteKeyword("identifierBackreference");
  2067. LPar();
  2068. WriteIdentifier(identifierExpressionBackreference.ReferencedGroupName);
  2069. RPar();
  2070. }
  2071. void VisitChoice(Choice choice)
  2072. {
  2073. WriteKeyword("choice");
  2074. Space();
  2075. LPar();
  2076. NewLine();
  2077. writer.Indent();
  2078. foreach (INode alternative in choice) {
  2079. VisitNodeInPattern(alternative);
  2080. if (alternative != choice.Last()) {
  2081. WriteToken(Roles.Comma);
  2082. }
  2083. NewLine();
  2084. }
  2085. writer.Unindent();
  2086. RPar();
  2087. }
  2088. void VisitNamedNode(NamedNode namedNode)
  2089. {
  2090. if (!string.IsNullOrEmpty(namedNode.GroupName)) {
  2091. WriteIdentifier(namedNode.GroupName);
  2092. WriteToken(Roles.Colon);
  2093. }
  2094. VisitNodeInPattern(namedNode.ChildNode);
  2095. }
  2096. void VisitRepeat(Repeat repeat)
  2097. {
  2098. WriteKeyword("repeat");
  2099. LPar();
  2100. if (repeat.MinCount != 0 || repeat.MaxCount != int.MaxValue) {
  2101. WriteIdentifier(repeat.MinCount.ToString());
  2102. WriteToken(Roles.Comma);
  2103. WriteIdentifier(repeat.MaxCount.ToString());
  2104. WriteToken(Roles.Comma);
  2105. }
  2106. VisitNodeInPattern(repeat.ChildNode);
  2107. RPar();
  2108. }
  2109. void VisitOptionalNode(OptionalNode optionalNode)
  2110. {
  2111. WriteKeyword("optional");
  2112. LPar();
  2113. VisitNodeInPattern(optionalNode.ChildNode);
  2114. RPar();
  2115. }
  2116. void VisitNodeInPattern(INode childNode)
  2117. {
  2118. if (childNode is AstNode) {
  2119. ((AstNode)childNode).AcceptVisitor(this);
  2120. } else if (childNode is IdentifierExpressionBackreference) {
  2121. VisitIdentifierExpressionBackreference((IdentifierExpressionBackreference)childNode);
  2122. } else if (childNode is Choice) {
  2123. VisitChoice((Choice)childNode);
  2124. } else if (childNode is AnyNode) {
  2125. VisitAnyNode((AnyNode)childNode);
  2126. } else if (childNode is Backreference) {
  2127. VisitBackreference((Backreference)childNode);
  2128. } else if (childNode is NamedNode) {
  2129. VisitNamedNode((NamedNode)childNode);
  2130. } else if (childNode is OptionalNode) {
  2131. VisitOptionalNode((OptionalNode)childNode);
  2132. } else if (childNode is Repeat) {
  2133. VisitRepeat((Repeat)childNode);
  2134. } else {
  2135. TextWriterTokenWriter.PrintPrimitiveValue(childNode);
  2136. }
  2137. }
  2138. #endregion
  2139. #region Documentation Reference
  2140. public void VisitDocumentationReference(DocumentationReference documentationReference)
  2141. {
  2142. StartNode(documentationReference);
  2143. if (!documentationReference.DeclaringType.IsNull) {
  2144. documentationReference.DeclaringType.AcceptVisitor(this);
  2145. if (documentationReference.SymbolKind != SymbolKind.TypeDefinition) {
  2146. WriteToken(Roles.Dot);
  2147. }
  2148. }
  2149. switch (documentationReference.SymbolKind) {
  2150. case SymbolKind.TypeDefinition:
  2151. // we already printed the DeclaringType
  2152. break;
  2153. case SymbolKind.Indexer:
  2154. WriteKeyword(IndexerDeclaration.ThisKeywordRole);
  2155. break;
  2156. case SymbolKind.Operator:
  2157. var opType = documentationReference.OperatorType;
  2158. if (opType == OperatorType.Explicit) {
  2159. WriteKeyword(OperatorDeclaration.ExplicitRole);
  2160. } else if (opType == OperatorType.Implicit) {
  2161. WriteKeyword(OperatorDeclaration.ImplicitRole);
  2162. }
  2163. WriteKeyword(OperatorDeclaration.OperatorKeywordRole);
  2164. Space();
  2165. if (opType == OperatorType.Explicit || opType == OperatorType.Implicit) {
  2166. documentationReference.ConversionOperatorReturnType.AcceptVisitor(this);
  2167. } else {
  2168. WriteToken(OperatorDeclaration.GetToken(opType), OperatorDeclaration.GetRole(opType));
  2169. }
  2170. break;
  2171. default:
  2172. WriteIdentifier(documentationReference.GetChildByRole(Roles.Identifier));
  2173. break;
  2174. }
  2175. WriteTypeArguments(documentationReference.TypeArguments);
  2176. if (documentationReference.HasParameterList) {
  2177. Space(policy.SpaceBeforeMethodDeclarationParentheses);
  2178. if (documentationReference.SymbolKind == SymbolKind.Indexer) {
  2179. WriteCommaSeparatedListInBrackets(documentationReference.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
  2180. } else {
  2181. WriteCommaSeparatedListInParenthesis(documentationReference.Parameters, policy.SpaceWithinMethodDeclarationParentheses);
  2182. }
  2183. }
  2184. EndNode(documentationReference);
  2185. }
  2186. #endregion
  2187. /// <summary>
  2188. /// Converts special characters to escape sequences within the given string.
  2189. /// </summary>
  2190. public static string ConvertString(string text)
  2191. {
  2192. return TextWriterTokenWriter.ConvertString(text);
  2193. }
  2194. }
  2195. }