using System; using Microsoft.CodeAnalysis; namespace Ariadne.Generator { /// /// Describes a diagnostic as plain data, which an incremental generator step can compare between runs. A /// Diagnostic can't be compared that way, since its location holds a syntax tree that each edit replaces. /// public sealed class DiagnosticData : IEquatable { public readonly DiagnosticDescriptor Descriptor; /// /// Holds the message with its arguments already filled in. /// public readonly string Message; public readonly SourcePlace Place; public DiagnosticData(DiagnosticDescriptor descriptor, string message, SourcePlace place) { Descriptor = descriptor; Message = message; Place = place; } /// /// Returns at , with filled /// into its message. /// public static DiagnosticData Create(DiagnosticDescriptor descriptor, SourcePlace place, params object[] arguments) { return new DiagnosticData(descriptor, Diagnostic.Create(descriptor, Location.None, arguments).GetMessage(), place); } /// /// Returns as data. /// public static DiagnosticData Of(Diagnostic diagnostic) { return new DiagnosticData(diagnostic.Descriptor, diagnostic.GetMessage(), SourcePlace.Of(diagnostic.Location)); } /// /// Returns the diagnostic at its place in . /// public Diagnostic ToDiagnostic(Compilation compilation) { // An error has no warning level, and a warning is at the first. int warningLevel = 1; if (Descriptor.DefaultSeverity == DiagnosticSeverity.Error) { warningLevel = 0; } return Diagnostic.Create(Descriptor.Id, Descriptor.Category, Message, Descriptor.DefaultSeverity, Descriptor.DefaultSeverity, Descriptor.IsEnabledByDefault, warningLevel, Descriptor.Title, Descriptor.Description, Descriptor.HelpLinkUri, Place.LocationIn(compilation)); } public bool Equals(DiagnosticData other) { return other != null && Descriptor.Id == other.Descriptor.Id && Message == other.Message && Place.Equals(other.Place); } public override bool Equals(object obj) { return Equals(obj as DiagnosticData); } public override int GetHashCode() { return Descriptor.Id.GetHashCode() * 31 + Message.GetHashCode(); } } }