feat(generator): SEM004 diagnostic — flag dimensions.json units missing from units.json#77
Merged
matt-edmondson merged 1 commit intovectorsfrom May 10, 2026
Merged
Conversation
…ts.json
Without this diagnostic, BuildToBaseExpression silently falls back to
identity conversion when an availableUnits entry doesn't match any
unit declared in units.json. That's wrong for any non-base unit — a
typo like "Metre" instead of "Meter", or a unit that hasn't been
added to units.json yet, would compile clean and emit a From{Unit}
factory whose body just passes the value through unchanged.
SEM004 walks every dimension's availableUnits, dedups by
(dimension, unitName), and warns with the unit name plus the
offending dimension so the typo is easy to find. Verified with a
deliberate "Metre" injection: produces the expected diagnostic and
identifies Length as the owner. Reverted to clean metadata; current
build is silent.
Side-effect: the silent identity fallback in BuildToBaseExpression
is preserved so the build still succeeds; SEM004 is the surfacing
mechanism. If we want hard failure on unknown units in CI, treat
warnings as errors at the project level (TreatWarningsAsErrors).
CLAUDE.md generator-diagnostics list updated.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Summary
Adds a fourth generator diagnostic:
SEM004warns whendimensions.json'savailableUnitsreferences a unit name that doesn't appear inunits.json.Why
Currently
BuildToBaseExpressionsilently falls back to identity conversion when a unit is missing fromunits.json. That's wrong for any non-base unit — a typo ("Metre"for"Meter","Hektopascal"for"Hectopascal") or an unmigrated unit produces a clean build with aFrom{Unit}factory whose body just passes the value through with no scaling. Verified by deliberately injecting"Metre"into Length'savailableUnits:Reverted to clean metadata before commit; current build is silent (zero
SEM00xwarnings).Implementation
UnknownUnitReferencedescriptor (idSEM004, warning).ReportUnknownUnitReferenceshelper called once afterBuildUnitMap. Walks every dimension'savailableUnits, dedups by(dimension, unitName)so a typo on a unit shared by many dimensions reports once per offending dimension, and skips reporting entirely whenunitMapis empty (units.jsonnot loaded — avoids drowning the log if metadata loading misfires).BuildToBaseExpressionpreserved —SEM004is the surfacing mechanism, not a behaviour change. Projects can promote warnings to errors viaTreatWarningsAsErrorsif they want hard failure on unknown units.Updates
AnalyzerReleases.Unshipped.md— adds theSEM004row.CLAUDE.md— addsSEM004to the generator-diagnostics list under "Working with the source generator".Test plan
dotnet build Semantics.SourceGeneratorsclean.dotnet build Semantics.Quantitiesclean — noSEM00xwarnings on current metadata."Meter" → "Metre"indimensions.jsonproduces the expectedSEM004against Length; revert restores silence.https://claude.ai/code/session_01Tj63Rddvs9frqLUgsjNEP5
Generated by Claude Code