From b5c4ef018ef65193c2e6a7ccc73e067042a0b047 Mon Sep 17 00:00:00 2001 From: Alexandre Mutel Date: Mon, 13 Apr 2020 21:05:53 +0200 Subject: [PATCH] Fix ToString for all nodes involving trivias and comments (#7) --- src/Tomlyn.Tests/SyntaxTests.cs | 51 ++++++++++++++++------- src/Tomlyn/Syntax/SyntaxNode.cs | 35 +++++++--------- src/Tomlyn/Syntax/SyntaxNodeExtensions.cs | 47 ++++++++++++++------- 3 files changed, 82 insertions(+), 51 deletions(-) diff --git a/src/Tomlyn.Tests/SyntaxTests.cs b/src/Tomlyn.Tests/SyntaxTests.cs index 710a96d..47e6ecb 100644 --- a/src/Tomlyn.Tests/SyntaxTests.cs +++ b/src/Tomlyn.Tests/SyntaxTests.cs @@ -2,6 +2,7 @@ // Licensed under the BSD-Clause 2 license. // See license.txt file in the project root for full license information. using System; +using System.Collections.Generic; using NUnit.Framework; using Tomlyn.Model; using Tomlyn.Syntax; @@ -13,32 +14,50 @@ public class SyntaxTests [Test] public void TestDocument() { + var table = new TableSyntax("test") + { + Items = + { + {"a", 1}, + {"b", true}, + {"c", "Check"}, + {"d", "ToEscape\nWithAnotherChar\t"}, + {"e", 12.5}, + {"f", new int[] {1, 2, 3, 4}}, + {"g", new string[] {"0", "1", "2"}}, + {"key with space", 2} + } + }; + var doc = new DocumentSyntax() { Tables = { - new TableSyntax("test") - { - Items = - { - {"a", 1}, - {"b", true }, - {"c", "Check"}, - {"d", "ToEscape\nWithAnotherChar\t" }, - {"e", 12.5 }, - {"f", new int[] {1,2,3,4} }, - {"g", new string[] {"0", "1", "2"} }, - {"key with space", 2} - } - } + table } }; + table.AddLeadingComment("This is a comment"); + table.AddLeadingTriviaNewLine(); + + var firstElement = table.Items.GetChildren(0); + firstElement.AddTrailingComment("This is an item comment"); + + var secondElement = table.Items.GetChildren(2); + secondElement.AddLeadingTriviaNewLine(); + secondElement.AddLeadingComment("This is a comment in a middle of a table"); + secondElement.AddLeadingTriviaNewLine(); + secondElement.AddLeadingTriviaNewLine(); + var docStr = doc.ToString(); - var expected = @"[test] -a = 1 + var expected = @"# This is a comment +[test] +a = 1 # This is an item comment b = true + +# This is a comment in a middle of a table + c = ""Check"" d = ""ToEscape\nWithAnotherChar\t"" e = 12.5 diff --git a/src/Tomlyn/Syntax/SyntaxNode.cs b/src/Tomlyn/Syntax/SyntaxNode.cs index c20b2a1..6566f5c 100644 --- a/src/Tomlyn/Syntax/SyntaxNode.cs +++ b/src/Tomlyn/Syntax/SyntaxNode.cs @@ -72,34 +72,27 @@ public override string ToString() public void WriteTo(TextWriter writer) { if (writer == null) throw new ArgumentNullException(nameof(writer)); - var stack = new Stack(); - stack.Push(this); - WriteTo(stack, writer); + WriteToInternal(writer); } - private static void WriteTo(Stack stack, TextWriter writer) + private void WriteToInternal(TextWriter writer) { - while (stack.Count > 0) + WriteTriviaTo(LeadingTrivia, writer); + if (this is SyntaxToken token) { - var node = stack.Pop(); - - WriteTriviaTo(node.LeadingTrivia, writer); - if (node is SyntaxToken token) - { - writer.Write(token.TokenKind.ToText() ?? token.Text); - } - else + writer.Write(token.TokenKind.ToText() ?? token.Text); + } + else + { + int count = ChildrenCount; + for (int i = 0; i < count; i++) { - int count = node.ChildrenCount; - for (int i = count - 1; i >= 0; i--) - { - var child = node.GetChildren(i); - if (child == null) continue; - stack.Push(child); - } + var child = GetChildren(i); + if (child == null) continue; + child.WriteToInternal(writer); } - WriteTriviaTo(node.TrailingTrivia, writer); } + WriteTriviaTo(TrailingTrivia, writer); } private static void WriteTriviaTo(List trivias, TextWriter writer) diff --git a/src/Tomlyn/Syntax/SyntaxNodeExtensions.cs b/src/Tomlyn/Syntax/SyntaxNodeExtensions.cs index 5fa9dc6..dccfcfd 100644 --- a/src/Tomlyn/Syntax/SyntaxNodeExtensions.cs +++ b/src/Tomlyn/Syntax/SyntaxNodeExtensions.cs @@ -3,6 +3,7 @@ // See license.txt file in the project root for full license information. using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; namespace Tomlyn.Syntax { @@ -56,15 +57,25 @@ public static void Add(this SyntaxList list, string name, DateTi list.Add(new KeyValueSyntax(name, value)); } - public static KeyValueSyntax AddComment(this KeyValueSyntax keyValue, string comment) + public static KeyValueSyntax AddTrailingComment(this KeyValueSyntax keyValue, string comment) { if (keyValue == null) throw new ArgumentNullException(nameof(keyValue)); if (keyValue.Value == null) throw new InvalidOperationException("The Value must not be null on the KeyValueSyntax"); - keyValue.Value.AddTrailingWhitespace().AddComment(comment); + keyValue.Value.AddTrailingWhitespace().AddTrailingComment(comment); return keyValue; } public static T AddLeadingWhitespace(this T node) where T : SyntaxNode + { + return AddLeadingTrivia(node, SyntaxFactory.Whitespace()); + } + + public static T AddTrailingWhitespace(this T node) where T : SyntaxNode + { + return AddTrailingTrivia(node, SyntaxFactory.Whitespace()); + } + + public static T AddLeadingTrivia(this T node, SyntaxTrivia trivia) where T : SyntaxNode { if (node == null) throw new ArgumentNullException(nameof(node)); var trivias = node.LeadingTrivia; @@ -73,11 +84,11 @@ public static T AddLeadingWhitespace(this T node) where T : SyntaxNode trivias = new List(); node.LeadingTrivia = trivias; } - trivias.Add(SyntaxFactory.Whitespace()); + trivias.Add(trivia); return node; } - public static T AddTrailingWhitespace(this T node) where T : SyntaxNode + public static T AddTrailingTrivia(this T node, SyntaxTrivia trivia) where T : SyntaxNode { if (node == null) throw new ArgumentNullException(nameof(node)); var trivias = node.TrailingTrivia; @@ -86,20 +97,28 @@ public static T AddTrailingWhitespace(this T node) where T : SyntaxNode trivias = new List(); node.TrailingTrivia = trivias; } - trivias.Add(SyntaxFactory.Whitespace()); + trivias.Add(trivia); return node; } - public static T AddComment(this T node, string comment) where T : SyntaxNode + public static T AddLeadingComment(this T node, string comment) where T : SyntaxNode { - var trivias = node.TrailingTrivia; - if (trivias == null) - { - trivias = new List(); - node.TrailingTrivia = trivias; - } - trivias.Add(SyntaxFactory.Comment(comment)); - return node; + return AddLeadingTrivia(node, SyntaxFactory.Comment(comment)); + } + + public static T AddTrailingComment(this T node, string comment) where T : SyntaxNode + { + return AddTrailingTrivia(node, SyntaxFactory.Comment(comment)); + } + + public static T AddLeadingTriviaNewLine(this T node) where T : SyntaxNode + { + return AddLeadingTrivia(node, SyntaxFactory.NewLineTrivia()); + } + + public static T AddTrailingTriviaNewLine(this T node) where T : SyntaxNode + { + return AddTrailingTrivia(node, SyntaxFactory.NewLineTrivia()); } } }