Skip to content

Extract a reusable generator diagnostics helper #185

Closed

Description

@matt-edmondson

Problem

Every generator in this repo hand-rolls the same diagnostic plumbing. QuantitiesGenerator declares four DiagnosticDescriptor fields (SEM001–SEM004) and LogarithmicScalesGenerator a fifth (SEM005), each with its own private Report helper:

private static readonly DiagnosticDescriptor InvalidScaleDefinition = new(
    id: "SEM005",
    title: "logarithmic.json scale definition is invalid",
    messageFormat: "logarithmic.json validation issue: {0}",
    category: Emit.DiagnosticCategory,
    defaultSeverity: DiagnosticSeverity.Warning,
    isEnabledByDefault: true);

private static void Report(SourceProductionContext context, string message) =>
    context.ReportDiagnostic(Diagnostic.Create(InvalidScaleDefinition, Location.None, message));

Nothing about that shape is Semantics-specific. Three problems come with it:

  1. The boilerplate is copied per generator, and the IDs are allocated by hand — the next generator author has to grep for the highest SEM0xx in use.
  2. GeneratorBase does not follow the scheme. It reports JSON parse failures as CONV001 in category "SourceGenerator" — a leftover from when it served only ConversionsGenerator, and inconsistent with everything derived from it.
  3. AnalyzerReleases.Shipped.md / AnalyzerReleases.Unshipped.md are maintained by hand. With EnforceExtendedAnalyzerRules=true, RS2008 fires when a descriptor is not tracked there, so this is a real recurring cost and an easy thing to forget.

Proposal

Extract into the shared toolkit:

  • A DiagnosticFactory / descriptor-registry type parameterized by prefix (SEM, CONV, whatever the consumer uses) and category, so a generator declares descriptors declaratively and reporting is one call.
  • Convenience overloads for the recurring shapes: "metadata validation issue", "unknown reference in metadata", "referenced file not found" — the three that account for all five descriptors here.
  • Optional Location support. Everything here reports Location.None, so a typo in dimensions.json gives no file or line. Since the metadata arrives as an AdditionalText the generator can map an offset to a Location, which would make these diagnostics genuinely navigable. Worth doing as part of the extraction rather than after.
  • A check (test or build step) that every declared descriptor is present in AnalyzerReleases.*.md, so RS2008 is caught before it fires.

Acceptance criteria

  • All SEM00x descriptors are declared through the shared helper; no generator declares a raw DiagnosticDescriptor.
  • GeneratorBase's JSON-failure diagnostic uses the consumer-configured prefix and category — CONV001 / "SourceGenerator" is gone.
  • Existing diagnostic IDs and message formats are unchanged (they are documented in CLAUDE.md and docs/physics-generator.md).
  • Analyzer-release tracking is verified automatically.

Context

Part of #181. Closely related to #182 — the base generator's diagnostics are the worst offender.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions