| File: Diagnostic\DiagnosticFormatter.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Globalization; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis { /// <summary> /// Formats <see cref="Diagnostic"/> messages. /// </summary> public class DiagnosticFormatter { /// <summary> /// Formats the <see cref="Diagnostic"/> message using the optional <see cref="IFormatProvider"/>. /// </summary> /// <param name="diagnostic">The diagnostic.</param> /// <param name="formatter">The formatter; or null to use the default formatter.</param> /// <returns>The formatted message.</returns> public virtual string Format(Diagnostic diagnostic, IFormatProvider? formatter = null) { if (diagnostic == null) { throw new ArgumentNullException(nameof(diagnostic)); } var culture = formatter as CultureInfo; switch (diagnostic.Location.Kind) { case LocationKind.SourceFile: case LocationKind.XmlFile: case LocationKind.ExternalFile: var span = diagnostic.Location.GetLineSpan(); var mappedSpan = diagnostic.Location.GetMappedLineSpan(); if (!span.IsValid || !mappedSpan.IsValid) { goto default; } string? path, basePath; if (mappedSpan.HasMappedPath) { path = mappedSpan.Path; basePath = span.Path; } else { path = span.Path; basePath = null; } return string.Format(formatter, "{0}{1}: {2}: {3}{4}", FormatSourcePath(path, basePath, formatter), FormatSourceSpan(mappedSpan.Span, formatter), GetMessagePrefix(diagnostic), diagnostic.GetMessage(culture), FormatHelpLinkUri(diagnostic)); default: return string.Format(formatter, "{0}: {1}{2}", GetMessagePrefix(diagnostic), diagnostic.GetMessage(culture), FormatHelpLinkUri(diagnostic)); } } internal virtual string FormatSourcePath(string path, string? basePath, IFormatProvider? formatter) { // ignore base path return path; } internal virtual string FormatSourceSpan(LinePositionSpan span, IFormatProvider? formatter) { return string.Format("({0},{1})", span.Start.Line + 1, span.Start.Character + 1); } internal string GetMessagePrefix(Diagnostic diagnostic) { string prefix; switch (diagnostic.Severity) { case DiagnosticSeverity.Hidden: prefix = "hidden"; break; case DiagnosticSeverity.Info: prefix = "info"; break; case DiagnosticSeverity.Warning: prefix = "warning"; break; case DiagnosticSeverity.Error: prefix = "error"; break; default: throw ExceptionUtilities.UnexpectedValue(diagnostic.Severity); } return string.Format("{0} {1}", prefix, diagnostic.Id); } private string FormatHelpLinkUri(Diagnostic diagnostic) { var uri = diagnostic.Descriptor.HelpLinkUri; if (string.IsNullOrEmpty(uri) || HasDefaultHelpLinkUri(diagnostic)) { return string.Empty; } return $" ({uri})"; } internal virtual bool HasDefaultHelpLinkUri(Diagnostic diagnostic) => true; internal static readonly DiagnosticFormatter Instance = new DiagnosticFormatter(); } }