diff --git a/.github/workflows/verify-generated.yml b/.github/workflows/verify-generated.yml index cbb411b0..1aa4ffd5 100644 --- a/.github/workflows/verify-generated.yml +++ b/.github/workflows/verify-generated.yml @@ -26,9 +26,11 @@ concurrency: jobs: verify-generated: name: Generated files up to date - # windows-latest so git's autocrlf matches the committed CRLF line endings and the - # diff doesn't flag end-of-line differences. - runs-on: windows-latest + # Runs on Linux: the generators pin their line terminator to LF, matching + # `* text=auto eol=lf` in .gitattributes, so the diff no longer depends on the runner's + # autocrlf. (This was windows-latest while the generators emitted CRLF and git normalised + # the difference away on commit.) + runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout diff --git a/CLAUDE.md b/CLAUDE.md index 25fb6734..2ac9e38d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -41,7 +41,7 @@ The opt-in lives in `.sonarlint/sonar-local.props` (analyzer package) and `.sona | `Semantics.Music` | Immutable musical value types (`Pitch`, `Interval`, `Scale`, `Chord`, `Key`, `Duration`, `TimeSignature`) plus an analysis aggregate layer (`Progression`, `Section`, `Arrangement`, `Form`) computing roman numerals, cadences, key inference, chromatic identification, and named forms. Targets `net8.0`–`net10.0` + `netstandard2.0`/`netstandard2.1`. | | `Semantics.Color` | Physically-grounded color types. Canonical linear-RGB `Color` hub plus color-space satellites (`Srgb`, `Hsl`, `Hsv`, `Oklab`, `Oklch`); every type converts to and from every other, routed through the nearest shared hub (`Srgb` within the sRGB family, `Oklab` within the perceptual family, linear `Color` across families) so no conversion takes a redundant gamma round-trip. Also WCAG accessibility tooling, HSL/perceptual adjustment operations (lighten/saturate/hue/invert), and `NamedColors`. Targets `net8.0`–`net10.0` + `netstandard2.0`/`netstandard2.1`. | | `Semantics.Quantities` | Hand-written runtime types (`PhysicalQuantity`, `IVector0`..`IVector4`, `UnitSystem`) plus generator output under `Generated/`. | -| `Semantics.SourceGenerators` | Roslyn incremental generators that emit quantity types, units, conversions, magnitudes, physical constants, and storage-type helpers from metadata. `CodeGen/` holds the parts that are not specific to physics — the metadata-driven generator base, metadata loading, the diagnostic catalogue — and is being extracted into a shared toolkit (#181). | +| `Semantics.SourceGenerators` | Roslyn incremental generators that emit quantity types, units, conversions, magnitudes, physical constants, and storage-type helpers from metadata. The C# syntax templates now come from `ktsu.CodeBlocker.Templates`; `CodeGen/` holds what is left that is not specific to physics — the metadata-driven generator base, metadata loading, the diagnostic catalogue — and is being extracted into a shared toolkit (#181). | | `Semantics.Quantities.{Double,Float,Decimal}` | Props-only satellite packages. Each ships a `buildTransitive` props file (generated by `scripts/Generate-AliasProps.ps1`) that injects global-using aliases binding every quantity to one storage type, so consumers write `Mass` instead of `Mass`. | | `Semantics.Test` | MSTest project covering all of the above. | @@ -122,7 +122,7 @@ All values are stored in SI base units, so operators read `.Value` directly. Sup // Copyright (c) 2023-2026 ktsu-dev contributors ``` -The text comes from `COPYRIGHT.md`; ktsu.Sdk syncs `.editorconfig`'s `file_header_template` from that file on every build, and `IDE0073` enforces it. If `COPYRIGHT.md` changes, update `GeneratorBase.WriteHeaderTo` to match — generator output is committed source, so a drift there shows up as a diff rather than a build error (`.g.cs` is exempt from `IDE0073`). `SourceGeneratorTests` asserts the emitted header, so the drift fails a test instead. +The text comes from `COPYRIGHT.md`; ktsu.Sdk syncs `.editorconfig`'s `file_header_template` from that file on every build, and `IDE0073` enforces it. Generated files are written with LF line endings, pinned in `CreateCodeBlocker` to match `* text=auto eol=lf` in `.gitattributes`. If `COPYRIGHT.md` changes, update `GeneratorBase.WriteHeaderTo` to match — generator output is committed source, so a drift there shows up as a diff rather than a build error (`.g.cs` is exempt from `IDE0073`). `SourceGeneratorTests` asserts the emitted header, so the drift fails a test instead. Generator-emitted files additionally carry `// `. @@ -169,6 +169,8 @@ var converted = sourceString.As(); ### Working with the source generator - A generator declares the metadata files it reads via `MetadataFileNames` and derives from `SemanticsGenerator` (one file) or `SemanticsMultiFileGenerator` (several). Neither needs to override `Initialize`. +- Emitted C# is described with the template model from `ktsu.CodeBlocker.Templates` — `SourceFileTemplate`, `ClassTemplate`, `FieldTemplate`, `MethodTemplate` and friends. The model owns punctuation, spacing, member ordering and indentation, so a `BodyFactory` writes only the body: `=> Create(value);` for an expression body, or a braced block. Do **not** prefix it with a space; the model supplies the separator. +- A type's declaration keyword comes from `ClassTemplate.Kind` (`TypeKind.Class`, `TypeKind.Record`, …), not from `Keywords`, which carries only modifiers. Collection properties are read-only, so use collection-initializer syntax (`Keywords = { "public" }`) rather than assignment, or the `WithComments`/`WithInterfaces` helpers when you already hold a sequence. - Edit `Semantics.SourceGenerators/Metadata/dimensions.json` to add a dimension, vector form, semantic overload, or relationship. - Rebuild `Semantics.SourceGenerators` and the consuming `Semantics.Quantities` project; emitted files appear in `Semantics.Quantities/Generated/Semantics.SourceGenerators//`. - Treat generator output as committed source. Diff it before commit so accidental regressions are visible. diff --git a/Directory.Packages.props b/Directory.Packages.props index c15c7ba3..6e8776c1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -14,7 +14,7 @@ - +