< Summary

Information
Class: NexusLabs.Needlr.Generators.DiagnosticDescriptors
Assembly: NexusLabs.Needlr.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/DiagnosticDescriptors.cs
Line coverage
100%
Covered lines: 198
Uncovered lines: 0
Coverable lines: 198
Total lines: 345
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/DiagnosticDescriptors.cs

#LineLine coverage
 1using Microsoft.CodeAnalysis;
 2
 3namespace NexusLabs.Needlr.Generators;
 4
 5/// <summary>
 6/// Contains diagnostic descriptors for the Needlr source generator.
 7/// </summary>
 8internal static class DiagnosticDescriptors
 9{
 10    private const string Category = "NexusLabs.Needlr.Generators";
 11    private const string HelpLinkBase = "https://github.com/nexus-labs/needlr/blob/main/docs/analyzers/";
 12
 13    /// <summary>
 14    /// NDLRGEN001: Internal type in referenced assembly cannot be registered.
 15    /// </summary>
 16    /// <remarks>
 17    /// This error is emitted when a type in a referenced assembly:
 18    /// - Matches the namespace filter
 19    /// - Would be registerable (injectable or plugin) if it were accessible
 20    /// - Is internal (not public) and thus inaccessible from the generated code
 21    ///
 22    /// To fix this error, add [GenerateTypeRegistry] to the referenced assembly
 23    /// so that it generates its own type registry that can access its internal types.
 24    /// </remarks>
 125    public static readonly DiagnosticDescriptor InaccessibleInternalType = new(
 126        id: "NDLRGEN001",
 127        title: "Internal type in referenced assembly cannot be registered",
 128        messageFormat: "Type '{0}' in assembly '{1}' is internal and cannot be registered. Add [GenerateTypeRegistry] at
 129        category: Category,
 130        defaultSeverity: DiagnosticSeverity.Error,
 131        isEnabledByDefault: true,
 132        description: "Internal types in referenced assemblies cannot be accessed by the generated code. To include inter
 133        helpLinkUri: HelpLinkBase + "NDLRGEN001.md");
 34
 35    /// <summary>
 36    /// NDLRGEN002: Referenced assembly has internal plugin types but no [GenerateTypeRegistry] attribute.
 37    /// </summary>
 38    /// <remarks>
 39    /// This error is emitted when a referenced assembly:
 40    /// - Contains internal types that implement plugin interfaces (e.g., IServiceCollectionPlugin)
 41    /// - Does not have a [GenerateTypeRegistry] attribute
 42    ///
 43    /// Without the attribute, the internal plugin types will not be registered and will
 44    /// silently fail to load at runtime.
 45    /// </remarks>
 146    public static readonly DiagnosticDescriptor MissingGenerateTypeRegistryAttribute = new(
 147        id: "NDLRGEN002",
 148        title: "Referenced assembly has internal plugin types but no type registry",
 149        messageFormat: "Assembly '{0}' contains internal plugin type '{1}' but has no [GenerateTypeRegistry] attribute. 
 150        category: Category,
 151        defaultSeverity: DiagnosticSeverity.Error,
 152        isEnabledByDefault: true,
 153        description: "Referenced assemblies with internal plugin types must have a [GenerateTypeRegistry] attribute to g
 154        helpLinkUri: HelpLinkBase + "NDLRGEN002.md");
 55
 56    /// <summary>
 57    /// NDLRGEN003: [GenerateFactory] on type with all injectable parameters is unnecessary.
 58    /// </summary>
 159    public static readonly DiagnosticDescriptor FactoryAllParamsInjectable = new(
 160        id: "NDLRGEN003",
 161        title: "[GenerateFactory] unnecessary - all parameters are injectable",
 162        messageFormat: "Type '{0}' has [GenerateFactory] but all constructor parameters are injectable. Consider removin
 163        category: Category,
 164        defaultSeverity: DiagnosticSeverity.Warning,
 165        isEnabledByDefault: true,
 166        description: "The [GenerateFactory] attribute generates a factory for types with mixed injectable and runtime pa
 167        helpLinkUri: HelpLinkBase + "NDLRGEN003.md");
 68
 69    /// <summary>
 70    /// NDLRGEN004: [GenerateFactory] on type with no injectable parameters provides low value.
 71    /// </summary>
 172    public static readonly DiagnosticDescriptor FactoryNoInjectableParams = new(
 173        id: "NDLRGEN004",
 174        title: "[GenerateFactory] has low value - no injectable parameters",
 175        messageFormat: "Type '{0}' has [GenerateFactory] but no constructor parameters are injectable. The factory provi
 176        category: Category,
 177        defaultSeverity: DiagnosticSeverity.Warning,
 178        isEnabledByDefault: true,
 179        description: "The [GenerateFactory] attribute is most useful when a type has a mix of injectable and runtime par
 180        helpLinkUri: HelpLinkBase + "NDLRGEN004.md");
 81
 82    /// <summary>
 83    /// NDLRGEN005: [GenerateFactory&lt;T&gt;] type argument must be an interface implemented by the class.
 84    /// </summary>
 185    public static readonly DiagnosticDescriptor FactoryTypeArgNotImplemented = new(
 186        id: "NDLRGEN005",
 187        title: "[GenerateFactory<T>] type argument not implemented",
 188        messageFormat: "Type '{0}' has [GenerateFactory<{1}>] but does not implement '{1}'. The type argument must be an
 189        category: Category,
 190        defaultSeverity: DiagnosticSeverity.Error,
 191        isEnabledByDefault: true,
 192        description: "When using [GenerateFactory<T>], T must be an interface that the decorated class implements. The f
 193        helpLinkUri: HelpLinkBase + "NDLRGEN005.md");
 94
 95    /// <summary>
 96    /// NDLRGEN006: [OpenDecoratorFor] type argument must be an open generic interface.
 97    /// </summary>
 198    public static readonly DiagnosticDescriptor OpenDecoratorTypeNotOpenGeneric = new(
 199        id: "NDLRGEN006",
 1100        title: "[OpenDecoratorFor] type must be an open generic interface",
 1101        messageFormat: "Type argument '{0}' in [OpenDecoratorFor] is not an open generic interface: {1}",
 1102        category: Category,
 1103        defaultSeverity: DiagnosticSeverity.Error,
 1104        isEnabledByDefault: true,
 1105        description: "The [OpenDecoratorFor] attribute requires an open generic interface type. Use typeof(IInterface<>)
 1106        helpLinkUri: HelpLinkBase + "NDLRGEN006.md");
 107
 108    /// <summary>
 109    /// NDLRGEN007: [OpenDecoratorFor] decorator class must be an open generic with matching arity.
 110    /// </summary>
 1111    public static readonly DiagnosticDescriptor OpenDecoratorClassNotOpenGeneric = new(
 1112        id: "NDLRGEN007",
 1113        title: "[OpenDecoratorFor] decorator must be an open generic class",
 1114        messageFormat: "Class '{0}' with [OpenDecoratorFor({1})] must be an open generic class with {2} type parameter(s
 1115        category: Category,
 1116        defaultSeverity: DiagnosticSeverity.Error,
 1117        isEnabledByDefault: true,
 1118        description: "When using [OpenDecoratorFor(typeof(IInterface<>))], the decorated class must also be an open gene
 1119        helpLinkUri: HelpLinkBase + "NDLRGEN007.md");
 120
 121    /// <summary>
 122    /// NDLRGEN008: [OpenDecoratorFor] decorator class must implement the open generic interface.
 123    /// </summary>
 1124    public static readonly DiagnosticDescriptor OpenDecoratorNotImplementingInterface = new(
 1125        id: "NDLRGEN008",
 1126        title: "[OpenDecoratorFor] decorator must implement the interface",
 1127        messageFormat: "Class '{0}' has [OpenDecoratorFor({1})] but does not implement '{1}'. The decorator must impleme
 1128        category: Category,
 1129        defaultSeverity: DiagnosticSeverity.Error,
 1130        isEnabledByDefault: true,
 1131        description: "A decorator must implement the same interface as the services it wraps. Ensure the class implement
 1132        helpLinkUri: HelpLinkBase + "NDLRGEN008.md");
 133
 134    // ============================================================================
 135    // Options Validation Analyzers (NDLRGEN014-021)
 136    // ============================================================================
 137
 138    /// <summary>
 139    /// NDLRGEN014: Validator type must implement IOptionsValidator&lt;T&gt; or have a valid Validate method.
 140    /// </summary>
 1141    public static readonly DiagnosticDescriptor ValidatorTypeMissingInterface = new(
 1142        id: "NDLRGEN014",
 1143        title: "Validator type has no validation method",
 1144        messageFormat: "Validator type '{0}' must have a Validate method. Implement IOptionsValidator<{1}> or add a 'Val
 1145        category: Category,
 1146        defaultSeverity: DiagnosticSeverity.Error,
 1147        isEnabledByDefault: true,
 1148        description: "When using Validator property on [Options], the specified type must have a valid validation method
 1149        helpLinkUri: HelpLinkBase + "NDLRGEN014.md");
 150
 151    /// <summary>
 152    /// NDLRGEN015: Validator's generic type parameter doesn't match the options type.
 153    /// </summary>
 1154    public static readonly DiagnosticDescriptor ValidatorTypeMismatch = new(
 1155        id: "NDLRGEN015",
 1156        title: "Validator type mismatch",
 1157        messageFormat: "Validator '{0}' validates '{1}' but is applied to options type '{2}'. The validator must be for 
 1158        category: Category,
 1159        defaultSeverity: DiagnosticSeverity.Error,
 1160        isEnabledByDefault: true,
 1161        description: "The Validator specified in [Options(Validator = ...)] must validate the same type as the options c
 1162        helpLinkUri: HelpLinkBase + "NDLRGEN015.md");
 163
 164    /// <summary>
 165    /// NDLRGEN016: ValidateMethod specified but method not found on target type.
 166    /// </summary>
 1167    public static readonly DiagnosticDescriptor ValidateMethodNotFound = new(
 1168        id: "NDLRGEN016",
 1169        title: "Validation method not found",
 1170        messageFormat: "Method '{0}' not found on type '{1}'. Ensure the method exists and has the correct signature.",
 1171        category: Category,
 1172        defaultSeverity: DiagnosticSeverity.Error,
 1173        isEnabledByDefault: true,
 1174        description: "The ValidateMethod specified in [Options] must exist on the options type (or Validator type if spe
 1175        helpLinkUri: HelpLinkBase + "NDLRGEN016.md");
 176
 177    /// <summary>
 178    /// NDLRGEN017: Validation method has incorrect signature.
 179    /// </summary>
 1180    public static readonly DiagnosticDescriptor ValidateMethodWrongSignature = new(
 1181        id: "NDLRGEN017",
 1182        title: "Validation method has wrong signature",
 1183        messageFormat: "Method '{0}' on type '{1}' has wrong signature, expected {2}",
 1184        category: Category,
 1185        defaultSeverity: DiagnosticSeverity.Error,
 1186        isEnabledByDefault: true,
 1187        description: "Validation methods must return IEnumerable<ValidationError> or IEnumerable<string>. Instance metho
 1188        helpLinkUri: HelpLinkBase + "NDLRGEN017.md");
 189
 190    /// <summary>
 191    /// NDLRGEN018: Validator specified but ValidateOnStart is false.
 192    /// </summary>
 1193    public static readonly DiagnosticDescriptor ValidatorWontRun = new(
 1194        id: "NDLRGEN018",
 1195        title: "Validator won't run",
 1196        messageFormat: "Validator '{0}' will not run because ValidateOnStart is false. Set ValidateOnStart = true to ena
 1197        category: Category,
 1198        defaultSeverity: DiagnosticSeverity.Warning,
 1199        isEnabledByDefault: true,
 1200        description: "When Validator is specified but ValidateOnStart is not enabled, the validator will never be invoke
 1201        helpLinkUri: HelpLinkBase + "NDLRGEN018.md");
 202
 203    /// <summary>
 204    /// NDLRGEN019: ValidateMethod specified but ValidateOnStart is false.
 205    /// </summary>
 1206    public static readonly DiagnosticDescriptor ValidateMethodWontRun = new(
 1207        id: "NDLRGEN019",
 1208        title: "Validation method won't run",
 1209        messageFormat: "ValidateMethod '{0}' will not run because ValidateOnStart is false. Set ValidateOnStart = true t
 1210        category: Category,
 1211        defaultSeverity: DiagnosticSeverity.Warning,
 1212        isEnabledByDefault: true,
 1213        description: "When ValidateMethod is specified but ValidateOnStart is not enabled, the validation method will ne
 1214        helpLinkUri: HelpLinkBase + "NDLRGEN019.md");
 215
 216    // ============================================================================
 217    // AOT Compatibility Analyzers (NDLRGEN020+)
 218    // ============================================================================
 219
 220    /// <summary>
 221    /// NDLRGEN020: [Options] attribute is not compatible with AOT/trimming.
 222    /// </summary>
 223    /// <remarks>
 224    /// The [Options] feature generates calls to Configure&lt;T&gt;() and BindConfiguration()
 225    /// which use reflection for configuration binding. These APIs are not AOT-compatible.
 226    /// </remarks>
 1227    public static readonly DiagnosticDescriptor OptionsNotAotCompatible = new(
 1228        id: "NDLRGEN020",
 1229        title: "[Options] is not compatible with AOT",
 1230        messageFormat: "Type '{0}' has [Options] attribute but is in an AOT-enabled project. The [Options] feature uses 
 1231        category: Category,
 1232        defaultSeverity: DiagnosticSeverity.Error,
 1233        isEnabledByDefault: true,
 1234        description: "The [Options] attribute generates code that calls Configure<T>() and BindConfiguration() which use
 1235        helpLinkUri: HelpLinkBase + "NDLRGEN020.md");
 236
 237    /// <summary>
 238    /// NDLRGEN021: Positional record with [Options] must be declared partial.
 239    /// </summary>
 240    /// <remarks>
 241    /// Positional records lack parameterless constructors, which are required for
 242    /// configuration binding. When the record is partial, the generator can emit
 243    /// a parameterless constructor. Non-partial records cannot be extended.
 244    /// </remarks>
 1245    public static readonly DiagnosticDescriptor PositionalRecordMustBePartial = new(
 1246        id: "NDLRGEN021",
 1247        title: "Positional record must be partial for [Options]",
 1248        messageFormat: "Positional record '{0}' has [Options] but is not declared partial. Add the 'partial' modifier to
 1249        category: Category,
 1250        defaultSeverity: DiagnosticSeverity.Warning,
 1251        isEnabledByDefault: true,
 1252        description: "Positional records (records with primary constructor parameters) lack parameterless constructors, 
 1253        helpLinkUri: HelpLinkBase + "NDLRGEN021.md");
 254
 255    /// <summary>
 256    /// NDLRGEN022: Disposable service may be captured by a longer-lived service.
 257    /// </summary>
 258    /// <remarks>
 259    /// This error is emitted when a longer-lived service (e.g., Singleton) has a constructor
 260    /// dependency on a shorter-lived service (e.g., Scoped, Transient) that implements
 261    /// IDisposable or IAsyncDisposable. This is a "captive dependency" anti-pattern where
 262    /// the disposable may be disposed while the consuming service still holds a reference.
 263    ///
 264    /// Unlike NDLRCOR012 which only detects explicit lifetime attributes, this diagnostic
 265    /// uses inferred lifetimes from Needlr's convention-based discovery, catching more issues.
 266    /// </remarks>
 1267    public static readonly DiagnosticDescriptor DisposableCaptiveDependency = new(
 1268        id: "NDLRGEN022",
 1269        title: "Disposable captive dependency detected",
 1270        messageFormat: "'{0}' ({1}) depends on '{2}' ({3}) which implements IDisposable. The disposable may be disposed 
 1271        category: Category,
 1272        defaultSeverity: DiagnosticSeverity.Error,
 1273        isEnabledByDefault: true,
 1274        description: "A longer-lived service captures a shorter-lived disposable dependency. When the shorter-lived scop
 1275        helpLinkUri: HelpLinkBase + "NDLRGEN022.md");
 276
 277    /// <summary>
 278    /// NDLRGEN030: DataAnnotation attribute cannot be source-generated.
 279    /// </summary>
 1280    public static readonly DiagnosticDescriptor UnsupportedDataAnnotation = new(
 1281        id: "NDLRGEN030",
 1282        title: "DataAnnotation attribute cannot be source-generated",
 1283        messageFormat: "DataAnnotation '{0}' on '{1}.{2}' cannot be source-generated. In AOT mode, this validation will 
 1284        category: Category,
 1285        defaultSeverity: DiagnosticSeverity.Warning,
 1286        isEnabledByDefault: true,
 1287        description: "This DataAnnotation validation attribute cannot be source-generated because it requires runtime re
 1288        helpLinkUri: HelpLinkBase + "NDLRGEN030.md");
 289
 290    // ============================================================================
 291    // Provider Analyzers (NDLRGEN031-034)
 292    // ============================================================================
 293
 294    /// <summary>
 295    /// NDLRGEN031: [Provider] on class requires `partial` modifier.
 296    /// </summary>
 1297    public static readonly DiagnosticDescriptor ProviderClassNotPartial = new(
 1298        id: "NDLRGEN031",
 1299        title: "[Provider] on class requires partial modifier",
 1300        messageFormat: "Class '{0}' has [Provider] attribute but is not declared partial. Add the 'partial' modifier to 
 1301        category: Category,
 1302        defaultSeverity: DiagnosticSeverity.Error,
 1303        isEnabledByDefault: true,
 1304        description: "When applying [Provider] to a class (shorthand mode), the class must be declared partial so the ge
 1305        helpLinkUri: HelpLinkBase + "NDLRGEN031.md");
 306
 307    /// <summary>
 308    /// NDLRGEN032: [Provider] interface must only contain get-only properties.
 309    /// </summary>
 1310    public static readonly DiagnosticDescriptor ProviderInterfaceInvalidMember = new(
 1311        id: "NDLRGEN032",
 1312        title: "[Provider] interface has invalid member",
 1313        messageFormat: "Interface '{0}' has [Provider] attribute but contains {1}. Provider interfaces must only contain
 1314        category: Category,
 1315        defaultSeverity: DiagnosticSeverity.Error,
 1316        isEnabledByDefault: true,
 1317        description: "Provider interfaces should only contain get-only properties that represent the services to be prov
 1318        helpLinkUri: HelpLinkBase + "NDLRGEN032.md");
 319
 320    /// <summary>
 321    /// NDLRGEN033: Provider property type is a concrete class, consider using an interface.
 322    /// </summary>
 1323    public static readonly DiagnosticDescriptor ProviderPropertyConcreteType = new(
 1324        id: "NDLRGEN033",
 1325        title: "Provider property uses concrete type",
 1326        messageFormat: "Provider property '{0}.{1}' has type '{2}' which is a concrete class. Consider using an interfac
 1327        category: Category,
 1328        defaultSeverity: DiagnosticSeverity.Warning,
 1329        isEnabledByDefault: true,
 1330        description: "Provider properties represent services resolved from the DI container. Using interface types inste
 1331        helpLinkUri: HelpLinkBase + "NDLRGEN033.md");
 332
 333    /// <summary>
 334    /// NDLRGEN034: Circular provider dependency detected.
 335    /// </summary>
 1336    public static readonly DiagnosticDescriptor ProviderCircularDependency = new(
 1337        id: "NDLRGEN034",
 1338        title: "Circular provider dependency detected",
 1339        messageFormat: "Provider '{0}' has a circular dependency: {1}",
 1340        category: Category,
 1341        defaultSeverity: DiagnosticSeverity.Error,
 1342        isEnabledByDefault: true,
 1343        description: "A circular dependency was detected in the provider dependency graph. Provider A references Provide
 1344        helpLinkUri: HelpLinkBase + "NDLRGEN034.md");
 345}

Methods/Properties

.cctor()