| File: Formatters\FormatterUtilities.cs | Web Access |
| Project: 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.Collections.Immutable; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Text; using Microsoft.Extensions.Logging; namespace Microsoft.CodeAnalysis.Tools.Formatters { internal static class FormatterUtilities { internal static bool IsRazorDocument(TextDocument document) => document.FilePath is string filePath && (filePath.EndsWith(".razor", StringComparison.OrdinalIgnoreCase) || filePath.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase)); internal static AnalyzerConfigOptions? GetAnalyzerConfigOptionsForAdditionalDocument(TextDocument document) { if (document.FilePath is not string filePath) { return null; } var additionalText = document.Project.AnalyzerOptions.AdditionalFiles.FirstOrDefault( file => string.Equals(file.Path, filePath, StringComparison.Ordinal)); return additionalText is null ? null : document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(additionalText); } public static ImmutableArray<FileChange> GetFileChanges( TextDocument document, SourceText originalText, SourceText formattedText, string formatterName, string formatWarningDescription, FormatOptions formatOptions, ILogger logger) { var fileChanges = ImmutableArray.CreateBuilder<FileChange>(); var changes = formattedText.GetTextChanges(originalText); for (var index = 0; index < changes.Count; index++) { var change = changes[index]; var changeMessage = changes.Count > 1 || change.NewText?.Length != formattedText.Length ? BuildChangeMessage(change) : string.Empty; var changePosition = originalText.Lines.GetLinePosition(change.Span.Start); var fileChange = new FileChange(changePosition, formatterName, $"{formatWarningDescription}{changeMessage}"); fileChanges.Add(fileChange); if (!formatOptions.SaveFormattedFiles || formatOptions.LogLevel == LogLevel.Debug) { logger.LogFormattingIssue(document, formatterName, fileChange, formatOptions.ChangesAreErrors); } } return fileChanges.ToImmutable(); } private static string BuildChangeMessage(TextChange change) { var isDelete = string.IsNullOrEmpty(change.NewText); var isAdd = change.Span.Length == 0; if (isDelete && isAdd) { return string.Empty; } // Escape characters in the text changes so that it can be more easily read. var textChange = change.NewText?.Replace(" ", "\\s").Replace("\t", "\\t").Replace("\n", "\\n").Replace("\r", "\\r"); var message = isDelete ? string.Format(Resources.Delete_0_characters, change.Span.Length) : isAdd ? string.Format(Resources.Insert_0, textChange) : string.Format(Resources.Replace_0_characters_with_1, change.Span.Length, textChange); return $" {message}"; } } }