using Microsoft.CodeAnalysis; namespace Vellum.Generator { /// /// Save mistakes Vellum.Generator finds at build time. /// public static class VellumDiagnostics { private const string Category = "Vellum"; public static readonly DiagnosticDescriptor UnusableConverter = new DiagnosticDescriptor( "VEL0001", "A save converter must be public with a public parameterless constructor", "'{0}' converts a {1}, but saving can only create it if it's public with a public parameterless " + "constructor", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor DuplicateConverter = new DiagnosticDescriptor( "VEL0002", "Two save converters convert the same type", "'{0}' converts a {1}, but so does another converter, and saving can't choose between them", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor BuiltInConverter = new DiagnosticDescriptor( "VEL0003", "A save converter can't replace a built-in type", "'{0}' converts a {1}, which Vellum already saves itself", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor UnsaveableType = new DiagnosticDescriptor( "VEL0004", "A saved value's type can't be saved", "'{0}' is saved, but a {1}{2} can't be saved. Mark it [Saveable], or write a SaveConverter<{1}> for it.", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor UnsupportedSaveable = new DiagnosticDescriptor( "VEL0005", "A [Saveable] type must be a public, partial struct or class", "'{0}' is [Saveable]{1}, so it must be a public, partial struct, or class deriving from object or " + "another [Saveable] class, and any type it's nested in must be a partial class or struct", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor PublicLoader = new DiagnosticDescriptor( "VEL0006", "A [Saveable] type's SaveReader constructor must be private, or protected if it can be derived", "'{0}' loads through this constructor, which must be private so nothing else constructs a half-loaded " + "instance with it, or protected on a class others can derive from, since they load through it", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor UnmatchableConverter = new DiagnosticDescriptor( "VEL0007", "A generic save converter's type can't be matched", "'{0}' converts a {1}, but {2}. A generic converter must convert a generic type " + "made from its own type parameters, each used exactly once, or a type parameter whose only constraint " + "is a base class or interface made from its other type parameters, each used exactly once", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor ReservedKey = new DiagnosticDescriptor( "VEL0008", "A saved member can't be named for a key Vellum uses for itself", "'{0}' is saved under a key that Vellum uses to tell a subtype's saved value from others", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor HiddenKey = new DiagnosticDescriptor( "VEL0009", "A saved member's key can't repeat one saved by a base class", "'{0}' is saved under the same key as a member of {1}, which would be saved over", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor UnsavedSubtype = new DiagnosticDescriptor( "VEL0010", "A subtype of a type with a save converter needs one too", "'{0}' derives from {1}, which a converter saves, but nothing saves '{0}', so a {0} in a {1} " + "would fail to save", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor InterfaceConverter = new DiagnosticDescriptor( "VEL0011", "A save converter can't convert an interface", "'{0}' converts {1}, an interface, but a value is saved by the converter of its own type. " + "Mark the interface [Saveable] to hold any type that implements it.", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor MarkOutsideAConverter = new DiagnosticDescriptor( "VEL0012", "[Saveable] on a type parameter must mark a save converter's", "'{0}' of '{1}' is marked [Saveable], but only a type parameter of a SaveConverter can be", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor MarkedFamilySubject = new DiagnosticDescriptor( "VEL0013", "[Saveable] can't mark the type parameter a converter family stands for every type of", "'{0}' of '{1}' is marked [Saveable], but it stands for every type the converter saves, so it has " + "nothing to require", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor AmbiguousInterfaceFamilies = new DiagnosticDescriptor( "VEL0014", "A type can't be in two interface families neither of which extends the other's", "'{0}' implements {1}, which are each the interface of a converter family, and neither interface extends " + "the other, so saving can't choose a converter for it", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor RepeatedFamilyInterface = new DiagnosticDescriptor( "VEL0015", "A type can't implement an interface family's generic interface more than once", "'{0}' implements {1} with different type arguments, so the converter family for it can't tell which to " + "take its type parameters from", Category, DiagnosticSeverity.Error, isEnabledByDefault: true); public static readonly DiagnosticDescriptor UnregisterableSaveMethod = new DiagnosticDescriptor( "VEL0016", "A method that saves its type parameters can't be registered", "'{0}' saves a type built from its type parameters, but that type {1}, so calls to it aren't checked", Category, DiagnosticSeverity.Warning, isEnabledByDefault: true); } }