Skip to content

Commit

Permalink
Fix ToString for all nodes involving trivias and comments (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
xoofx committed Apr 13, 2020
1 parent 57c05da commit b5c4ef0
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 51 deletions.
51 changes: 35 additions & 16 deletions src/Tomlyn.Tests/SyntaxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
35 changes: 14 additions & 21 deletions src/Tomlyn/Syntax/SyntaxNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<SyntaxNode>();
stack.Push(this);
WriteTo(stack, writer);
WriteToInternal(writer);
}

private static void WriteTo(Stack<SyntaxNode> 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<SyntaxTrivia> trivias, TextWriter writer)
Expand Down
47 changes: 33 additions & 14 deletions src/Tomlyn/Syntax/SyntaxNodeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -56,15 +57,25 @@ public static void Add(this SyntaxList<KeyValueSyntax> 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<T>(this T node) where T : SyntaxNode
{
return AddLeadingTrivia(node, SyntaxFactory.Whitespace());
}

public static T AddTrailingWhitespace<T>(this T node) where T : SyntaxNode
{
return AddTrailingTrivia(node, SyntaxFactory.Whitespace());
}

public static T AddLeadingTrivia<T>(this T node, SyntaxTrivia trivia) where T : SyntaxNode
{
if (node == null) throw new ArgumentNullException(nameof(node));
var trivias = node.LeadingTrivia;
Expand All @@ -73,11 +84,11 @@ public static T AddLeadingWhitespace<T>(this T node) where T : SyntaxNode
trivias = new List<SyntaxTrivia>();
node.LeadingTrivia = trivias;
}
trivias.Add(SyntaxFactory.Whitespace());
trivias.Add(trivia);
return node;
}

public static T AddTrailingWhitespace<T>(this T node) where T : SyntaxNode
public static T AddTrailingTrivia<T>(this T node, SyntaxTrivia trivia) where T : SyntaxNode
{
if (node == null) throw new ArgumentNullException(nameof(node));
var trivias = node.TrailingTrivia;
Expand All @@ -86,20 +97,28 @@ public static T AddTrailingWhitespace<T>(this T node) where T : SyntaxNode
trivias = new List<SyntaxTrivia>();
node.TrailingTrivia = trivias;
}
trivias.Add(SyntaxFactory.Whitespace());
trivias.Add(trivia);
return node;
}

public static T AddComment<T>(this T node, string comment) where T : SyntaxNode
public static T AddLeadingComment<T>(this T node, string comment) where T : SyntaxNode
{
var trivias = node.TrailingTrivia;
if (trivias == null)
{
trivias = new List<SyntaxTrivia>();
node.TrailingTrivia = trivias;
}
trivias.Add(SyntaxFactory.Comment(comment));
return node;
return AddLeadingTrivia(node, SyntaxFactory.Comment(comment));
}

public static T AddTrailingComment<T>(this T node, string comment) where T : SyntaxNode
{
return AddTrailingTrivia(node, SyntaxFactory.Comment(comment));
}

public static T AddLeadingTriviaNewLine<T>(this T node) where T : SyntaxNode
{
return AddLeadingTrivia(node, SyntaxFactory.NewLineTrivia());
}

public static T AddTrailingTriviaNewLine<T>(this T node) where T : SyntaxNode
{
return AddTrailingTrivia(node, SyntaxFactory.NewLineTrivia());
}
}
}

0 comments on commit b5c4ef0

Please sign in to comment.