dssl / native /spec /10-resolved-document.md
EHS-Studio's picture
Claude Sonnet 5.5
v0.16.3: native DSSL spec, and the seven bugs writing it found
9da4a9b
|
Raw History Blame Contribute Delete
4.41 kB
# 10. The resolved document
The resolver turns one source file into a *resolved document*. This chapter defines its exact
shape and how two implementations are compared. This is what makes Level 2 testable without a
browser.
## 10.1 Inputs
- **DOC-1.** The resolver takes: the source text, the file name, the token registry (4.5) and
the motion registry (7.3). The registry defaults are the built-in tokens and no motions.
## 10.2 The document
```
{
errors: [ { file, line, message, hint? } ], // parser errors, then resolver errors
warnings: [ { file, line, message, hint? } ],
rules: [ Rule ],
shadowRules: [ Rule ],
raws: [ { css, file, line, order } ],
fontLinks: [ { url, line, file } ],
motionNames: [ name ], // motions defined in this file, in source order
motionFrames: { name: { essential, frames: [ { offset, props } ] } },
mediaQueries: [ query ], // distinct, in first-use order
tokens: { key: value }, // the final token map
registryRule: Rule
}
Rule = { id, sel, media, signals, containers, layer, order, decls, file, line, pseudo, states }
decl = { prop, value, line, via?, fromGradient? }
```
- **DOC-2.** `rules` holds the ordinary rules and the token rules from `tokens` blocks, in the
order they were emitted. `shadowRules` holds pseudo-element rules (5.8). `raws` holds `raw`
and `fonts` font-face blocks in emission order. The registry rule is not in `rules`.
- **DOC-3.** `mediaQueries` lists every distinct entry of `media` found in `rules` and
`shadowRules`, in the order first seen, rules first.
- **DOC-4.** `tokens` is the final map of 4.3 (every key, with the last definition in source
order). Keys are compared as a set; the canonical form sorts them.
- **DOC-5.** A declaration may carry `via` (the semantic property that produced a `display`
value) and `fromGradient` (true for the `background-image` from `gradient:`). Both are part
of the record.
- **DOC-6.** `states` is a set of state words. It is written as a sorted array.
- **DOC-7.** `ok` is not stored. It is `errors.length == 0`.
## 10.3 Canonical form
To compare two documents they are written as JSON in this form.
- **DOC-8.** Object keys are sorted by code point. Arrays keep their order, except `states`
and the `tokens` object, which are sorted.
- **DOC-9.** Numbers are written as the shortest decimal that reads back to the same
double, with no exponent for values between 1e-6 and 1e21, and no `-0`. Infinity is the
string `"Infinity"` (an `iterations` of `infinite`).
- **DOC-10.** A field that is `undefined` is omitted. A field that is `null` is `null`.
- **DOC-11.** Strings are compared as UTF-8 text.
- **DOC-12.** Two implementations are equal on a source when their canonical JSON is
byte-identical, after removing lint warnings from implementations that declared `lint: false`
(DIA-12).
## 10.4 The corpus
The comparison needs inputs. The corpus is a folder of `.dssl` files:
- every stylesheet the site ships (`public/styles/*.dssl`),
- every fenced `dssl` block from the guide, the readme and this spec,
- the fixtures of the existing test suites,
- one file per diagnostic message, written to trigger it.
For each input, `scripts/native-dump.mjs` writes the canonical JSON of the reference engine's
output to `native/expected/`. The Rust test `native/tests/differential.rs` resolves the same
input and compares.
- **DOC-13.** The expected files are generated. They are committed so that a change in the
reference engine shows up in review as a change in expected output, and so the Rust tests run
without Node.
- **DOC-14.** A divergence (chapter 12) is excluded from the comparison by listing the input in
`native/corpus/EXCLUDED.md` with the divergence id. An excluded input is still run, and its
diff is printed, so a fix is noticed.
- **DOC-15.** Once the harness exists, `native/PARITY.md` lists, per chapter, how many corpus
inputs pass, fail and are excluded. It is generated by the test run and not written by hand.
## 10.5 What the document does not contain
- The syntax tree (Level 1 compares it separately, 2.9).
- Behaviors (they are expanded during the walk and do not appear in the output).
- Anything about a particular element. Matching is stage 3 and needs a document.