| File: Formatters\EndOfLineFormatter.cs | Web Access |
| Project: src\sdk\src\Dotnet.Format\dotnet-format\dotnet-format.csproj (dotnet-format) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; using Microsoft.Extensions.Logging; namespace Microsoft.CodeAnalysis.Tools.Formatters { internal sealed class EndOfLineFormatter : DocumentFormatter { protected override string FormatWarningDescription => Resources.Fix_end_of_line_marker; public override string Name => "ENDOFLINE"; public override FixCategory Category => FixCategory.Whitespace; internal override Task<SourceText> FormatFileAsync( Document document, SourceText sourceText, OptionSet optionSet, AnalyzerConfigOptions analyzerConfigOptions, FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken) { return Task.Run(() => { if (!TryGetEndOfLine(analyzerConfigOptions, out var endOfLine)) { return sourceText; } var newSourceText = sourceText; var changes = new List<TextChange>(); for (var lineIndex = 0; lineIndex < newSourceText.Lines.Count; lineIndex++) { var line = newSourceText.Lines[lineIndex]; var lineEndingSpan = new TextSpan(line.End, line.EndIncludingLineBreak - line.End); // Check for end of file if (lineEndingSpan.IsEmpty) { break; } var lineEnding = newSourceText.ToString(lineEndingSpan); if (lineEnding == endOfLine) { continue; } changes.Add(new TextChange(lineEndingSpan, endOfLine)); } newSourceText = newSourceText.WithChanges(changes); return newSourceText; }); } public static bool TryGetEndOfLine(AnalyzerConfigOptions analyzerConfigOptions, [NotNullWhen(true)] out string? endOfLine) { if (analyzerConfigOptions != null && analyzerConfigOptions.TryGetValue("end_of_line", out var endOfLineOption)) { endOfLine = GetEndOfLine(endOfLineOption); return true; } endOfLine = null; return false; } private static string GetEndOfLine(string endOfLineOption) { return endOfLineOption switch { "lf" => "\n", "cr" => "\r", "crlf" => "\r\n", _ => Environment.NewLine, }; } internal static string GetEndOfLineOption(string newLine) { return newLine switch { "\n" => "lf", "\r" => "cr", "\r\n" => "crlf", _ => GetEndOfLineOption(Environment.NewLine), }; } } }