diff --git a/.editorconfig b/.editorconfig index 0de1fdae8..c94f2d35f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -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 diff --git a/Src/CSharpier.Cli/EditorConfig/EditorConfigFileParser.cs b/Src/CSharpier.Cli/EditorConfig/EditorConfigFileParser.cs index 21dd9d6e0..4a3faab3b 100644 --- a/Src/CSharpier.Cli/EditorConfig/EditorConfigFileParser.cs +++ b/Src/CSharpier.Cli/EditorConfig/EditorConfigFileParser.cs @@ -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, diff --git a/Src/CSharpier.Cli/EditorConfig/GlobMatcher.cs b/Src/CSharpier.Cli/EditorConfig/GlobMatcher.cs index 04d0b29a2..755091934 100644 --- a/Src/CSharpier.Cli/EditorConfig/GlobMatcher.cs +++ b/Src/CSharpier.Cli/EditorConfig/GlobMatcher.cs @@ -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. /// [SuppressMessage("Style", "IDE0011:Add braces")] -internal class GlobMatcher +internal partial class GlobMatcher { private readonly GlobMatcherOptions myOptions; private readonly List mySet; @@ -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 @@ -839,7 +841,7 @@ private static bool ParseNegate(GlobMatcherOptions options, ref string pattern) ///Expands all brace ranges in a pattern, returning a sequence containing every possible combination. private static IList BraceExpand(string pattern, GlobMatcherOptions options) { - if (options.NoBrace || !ourHasBraces.IsMatch(pattern)) + if (options.NoBrace || !ourHasBraces().IsMatch(pattern)) { // shortcut. no need to expand. return [pattern]; @@ -908,7 +910,7 @@ private static IList 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]) diff --git a/Src/CSharpier.Core/Xml/XNodePrinters/Node.cs b/Src/CSharpier.Core/Xml/XNodePrinters/Node.cs index fa9f374f0..bcb64eede 100644 --- a/Src/CSharpier.Core/Xml/XNodePrinters/Node.cs +++ b/Src/CSharpier.Core/Xml/XNodePrinters/Node.cs @@ -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) @@ -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()); diff --git a/Src/CSharpier.Tests/CommandLineFormatterTests.cs b/Src/CSharpier.Tests/CommandLineFormatterTests.cs index 74093a6c8..932128ab1 100644 --- a/Src/CSharpier.Tests/CommandLineFormatterTests.cs +++ b/Src/CSharpier.Tests/CommandLineFormatterTests.cs @@ -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($"{lineBreak}"); + content.Append($" {lineBreak}"); + content.Append($" {lineBreak}"); + content.Append($"{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,