Skip to content

Commit

Permalink
Implement original new line separator preserving
Browse files Browse the repository at this point in the history
  • Loading branch information
FrediKats committed Mar 28, 2024
1 parent e451bf3 commit bbcad64
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Sources/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<PropertyGroup>
<RepositoryUrl>https://github.com/kysect/DotnetProjectSystem</RepositoryUrl>
<PackageProjectUrl>https://github.com/kysect/DotnetProjectSystem</PackageProjectUrl>
<Version>0.1.15</Version>
<Version>0.1.16</Version>
</PropertyGroup>

<!-- Code configuration -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,24 @@ public void Format_FileWithComment_ExpectNoChanges()
Validate(input, input);
}

[Fact]
public void Format_FileWithEmptyLine_ExpectNoChanges()
{
var input = """
<Project>
<PropertyGroup>
<IncludeSymbols>true</IncludeSymbols>
</PropertyGroup>

<PropertyGroup>
<IncludeSymbols>true</IncludeSymbols>
</PropertyGroup>
</Project>
""";

Validate(input, input);
}

private void Validate(string input, string expected)
{
XmlDocumentSyntax document = Parser.ParseText(input);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ private XmlNodeSyntax UpdateElement(XmlDocumentSyntax documentSyntax, IXmlElemen
currentElement.ThrowIfNull();

int depth = CalculateDepth(documentSyntax, oldNode);
int originalNewLineCount = CalculateOriginalNewLineCount(currentElement);
currentElement = FormatAttributes(currentElement);
currentElement = AddLeadingTrivia(depth, currentElement);
currentElement = AddLeadingTrivia(originalNewLineCount, depth, currentElement);

return currentElement.AsSyntaxElement.AsNode;
}
Expand All @@ -56,6 +57,19 @@ private int CalculateDepth(XmlDocumentSyntax _, IXmlElement currentElement)
return depth;
}

private int CalculateOriginalNewLineCount(IXmlElement currentElement)
{
int newLineCount = currentElement
.AsSyntaxElement
.AsNode
.GetLeadingTrivia()
.ToFullString()
.Split(new[] { Environment.NewLine }, StringSplitOptions.None)
.Length - 1;

return newLineCount;
}

private IXmlElement FormatAttributes(IXmlElement currentElement)
{
IXmlElementSyntax currentElementSyntax = currentElement.AsSyntaxElement;
Expand Down Expand Up @@ -94,20 +108,20 @@ private IXmlElement FormatAttributes(IXmlElement currentElement)
return currentElementSyntax.AsElement;
}

private IXmlElement AddLeadingTrivia(int depth, IXmlElement modified)
private IXmlElement AddLeadingTrivia(int originalNewLineCount, int depth, IXmlElement modified)
{
if (modified is XmlEmptyElementSyntax xmlEmptyElementSyntax)
return AddLeadingTrivia(depth, xmlEmptyElementSyntax);
return AddLeadingTrivia(originalNewLineCount, depth, xmlEmptyElementSyntax);

if (modified is XmlElementSyntax xmlElementSyntax)
return AddLeadingTrivia(depth, xmlElementSyntax);
return AddLeadingTrivia(originalNewLineCount, depth, xmlElementSyntax);

throw SwitchDefaultExceptions.OnUnexpectedType(modified);
}

private IXmlElement AddLeadingTrivia(int depth, XmlEmptyElementSyntax xmlEmptyElementSyntax)
private IXmlElement AddLeadingTrivia(int originalNewLineCount, int depth, XmlEmptyElementSyntax xmlEmptyElementSyntax)
{
string trivia = GetTrivia(depth);
string trivia = GetTrivia(originalNewLineCount, depth);

xmlEmptyElementSyntax = xmlEmptyElementSyntax.ReplaceNode(
xmlEmptyElementSyntax.LessThanToken,
Expand All @@ -116,34 +130,39 @@ private IXmlElement AddLeadingTrivia(int depth, XmlEmptyElementSyntax xmlEmptyEl
return xmlEmptyElementSyntax;
}

private IXmlElement AddLeadingTrivia(int depth, XmlElementSyntax xmlElementSyntax)
private IXmlElement AddLeadingTrivia(int originalNewLineCount, int depth, XmlElementSyntax xmlElementSyntax)
{
string trivia = GetTrivia(depth);
string openNodeTrivia = GetTrivia(originalNewLineCount, depth);
string closeNodeTrivia = GetTrivia(1, depth);

// TODO: remove this hack for first node
bool needTriviaForStartTag = depth != 0;
if (needTriviaForStartTag)
{
xmlElementSyntax = xmlElementSyntax.ReplaceNode(
xmlElementSyntax.StartTag,
xmlElementSyntax.StartTag.WithLeadingTrivia(SyntaxFactory.WhitespaceTrivia(trivia)));
xmlElementSyntax.StartTag.WithLeadingTrivia(SyntaxFactory.WhitespaceTrivia(openNodeTrivia)));
}

bool needTriviaForEndTag = xmlElementSyntax.Elements.Any();
if (needTriviaForEndTag)
{
xmlElementSyntax = xmlElementSyntax.ReplaceNode(
xmlElementSyntax.EndTag,
xmlElementSyntax.EndTag.WithLeadingTrivia(SyntaxFactory.WhitespaceTrivia(trivia)));
xmlElementSyntax.EndTag.WithLeadingTrivia(SyntaxFactory.WhitespaceTrivia(closeNodeTrivia)));

}

return xmlElementSyntax;
}

private string GetTrivia(int depth)
private string GetTrivia(int originalNewLineCount, int depth)
{
var sb = new StringBuilder(Environment.NewLine);
var sb = new StringBuilder();

int newLineCount = Math.Max(originalNewLineCount, 1);
for (int i = 0; i < newLineCount; i++)
sb = sb.AppendLine();

for (int i = 0; i < depth; i++)
sb = sb.Append(DefaultIndention);
Expand Down

0 comments on commit bbcad64

Please sign in to comment.