Skip to content

Fixing bug with xml comments always using the line break for the syst… #1662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,5 @@ dotnet_diagnostic.IDE0301.severity = warning
dotnet_diagnostic.IDE0305.severity = none
dotnet_diagnostic.IDE0330.severity = warning
dotnet_diagnostic.IDE1006.severity = warning

dotnet_diagnostic.SYSLIB1045.severity = warning
7 changes: 4 additions & 3 deletions Src/CSharpier.Cli/EditorConfig/EditorConfigFileParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@

namespace CSharpier.Cli.EditorConfig;

internal static class EditorConfigFileParser
internal static partial class EditorConfigFileParser
{
// According to https://spec.editorconfig.org/#file-format
// "Comment: starts with a ; or a #."
private static readonly Regex CommentRegex = new("^[;#].*$");
[GeneratedRegex("^[;#].*$")]
private static partial Regex CommentRegex();

private static readonly IniParserConfiguration Configuration = new()
{
CommentRegex = CommentRegex,
CommentRegex = CommentRegex(),
AllowDuplicateKeys = true,
AllowDuplicateSections = true,
OverrideDuplicateKeys = true,
Expand Down
12 changes: 7 additions & 5 deletions Src/CSharpier.Cli/EditorConfig/GlobMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ internal class GlobMatcherOptions
/// A simple glob matcher implementation, if you want a proper one please use a full fletched one from nuget.
/// </summary>
[SuppressMessage("Style", "IDE0011:Add braces")]
internal class GlobMatcher
internal partial class GlobMatcher
{
private readonly GlobMatcherOptions myOptions;
private readonly List<PatternCase> mySet;
Expand Down Expand Up @@ -822,9 +822,11 @@ private static bool ParseNegate(GlobMatcherOptions options, ref string pattern)
return negate;
}

private static readonly Regex ourHasBraces = new Regex(@"\{.*\}");
[GeneratedRegex(@"\{.*\}")]
private static partial Regex ourHasBraces();

private static readonly Regex ourNumericSet = new Regex(@"^\{(-?[0-9]+)\.\.(-?[0-9]+)\}");
[GeneratedRegex(@"^\{(-?[0-9]+)\.\.(-?[0-9]+)\}")]
private static partial Regex ourNumericSet();

// Brace expansion:
// a{b,c}d -> abd acd
Expand All @@ -839,7 +841,7 @@ private static bool ParseNegate(GlobMatcherOptions options, ref string pattern)
///<summary>Expands all brace ranges in a pattern, returning a sequence containing every possible combination.</summary>
private static IList<string> BraceExpand(string pattern, GlobMatcherOptions options)
{
if (options.NoBrace || !ourHasBraces.IsMatch(pattern))
if (options.NoBrace || !ourHasBraces().IsMatch(pattern))
{
// shortcut. no need to expand.
return [pattern];
Expand Down Expand Up @@ -908,7 +910,7 @@ private static IList<string> BraceExpand(string pattern, GlobMatcherOptions opti
// If the set only has a single member, then'll put the {} back

// first, handle numeric sets, since they're easier
var numset = ourNumericSet.Match(pattern);
var numset = ourNumericSet().Match(pattern);
if (numset.Success)
{
// console.error("numset", numset[1], numset[2])
Expand Down
20 changes: 18 additions & 2 deletions Src/CSharpier.Core/Xml/XNodePrinters/Node.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
using System.Text.RegularExpressions;
using System.Xml.Linq;
using CSharpier.Core.DocTypes;
using CSharpier.Core.Utilities;

namespace CSharpier.Core.Xml.XNodePrinters;

internal static class Node
internal static
#if !NETSTANDARD2_0
partial
#endif
class Node
{
#if NETSTANDARD2_0
private static readonly Regex NewlineRegex = new(@"\r\n|\n|\r", RegexOptions.Compiled);
#else
[GeneratedRegex(@"\r\n|\n|\r", RegexOptions.Compiled)]
private static partial Regex NewlineRegex();
#endif

internal static Doc Print(XNode xNode, XmlPrintingContext context)
{
if (xNode is XDocument xDocument)
Expand Down Expand Up @@ -57,7 +69,11 @@ internal static Doc Print(XNode xNode, XmlPrintingContext context)

if (xNode is XComment or XProcessingInstruction)
{
return xNode.ToString();
return NewlineRegex
#if !NETSTANDARD2_0
()
#endif
.Replace(xNode.ToString(), context.Options.LineEnding);
}

throw new Exception("Need to handle + " + xNode.GetType());
Expand Down
23 changes: 23 additions & 0 deletions Src/CSharpier.Tests/CommandLineFormatterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,29 @@ public void Should_Support_Config_Path_With_Editor_Config()
context.GetFileContent(fileName).Should().Be("var myVariable =\n someLongValue;\n");
}

[TestCase("\r\n")]
[TestCase("\n")]
public void Format_XML_With_Multiline_Comment_Uses_Consistent_Line_Breaks(string lineBreak)
{
var context = new TestContext();
var content = new StringBuilder();
#pragma warning disable CA1305
// avoiding raw strings because this needs to use specific line breaks
content.Append($"<Root>{lineBreak}");
content.Append($" <Element />{lineBreak}");
content.Append($" <!--{lineBreak}");
content.Append($" SomeText{lineBreak}");
content.Append($" -->{lineBreak}");
content.Append($"</Root>{lineBreak}");
#pragma warning restore CA1305

context.WhenAFileExists("Xml.xml", content.ToString());

Format(context);

context.GetFileContent("Xml.xml").Should().Be(content.ToString());
}

private static FormatResult Format(
TestContext context,
bool skipWrite = false,
Expand Down