|
| 1 | +# schemagen |
| 2 | + |
| 3 | +Generates [`unified/extractor/swift_node_types.yml`][schema], the schema that |
| 4 | +describes the shape of the trees produced by `swift_syntax_rs::parse_to_json`. |
| 5 | +The extractor seeds every parse with it, so rule matching never refers to a |
| 6 | +node kind or field that swift-syntax can produce but the schema does not know. |
| 7 | + |
| 8 | +Run it through the script, which stages the sources described below: |
| 9 | + |
| 10 | +```console |
| 11 | +$ unified/scripts/regenerate-node-types.sh |
| 12 | +``` |
| 13 | + |
| 14 | +Do this after changing the pinned swift-syntax version, and read the resulting |
| 15 | +diff: a new or renamed node kind usually means the mapping in |
| 16 | +[`swift.rs`][mapping] needs attention too. |
| 17 | + |
| 18 | +This requires the local Swift toolchain pinned by |
| 19 | +[`.swift-version`](../.swift-version). |
| 20 | + |
| 21 | +## Why the sources are copied in |
| 22 | + |
| 23 | +The schema is derived from `SyntaxSupport`, the module that describes |
| 24 | +swift-syntax's own syntax tree. This is the same description swift-syntax |
| 25 | +generates itself from, and is therefore authoritative in a way that observing |
| 26 | +parser output never would be. The runtime `SwiftSyntax` module is not a |
| 27 | +substitute: its `SyntaxNodeStructure` exposes layout as key paths, without the |
| 28 | +field names, optionality, and base-kind relationships this schema records. |
| 29 | + |
| 30 | +`SyntaxSupport` is awkward to depend on, though. It is a target of |
| 31 | +`CodeGeneration`, a package inside the swift-syntax repository that is |
| 32 | +separate from swift-syntax itself, and it is not one of that package's |
| 33 | +products. SwiftPM can only depend on products, and Bazel's swift-syntax module |
| 34 | +does not export the `CodeGeneration` sources, so neither build system can |
| 35 | +reach it directly. |
| 36 | + |
| 37 | +The regeneration script therefore resolves this package's swift-syntax |
| 38 | +dependency and copies its `CodeGeneration/Sources/SyntaxSupport` sources into |
| 39 | +`Sources/SyntaxSupport`, where this package builds them as its own. That |
| 40 | +directory is git-ignored and refreshed on every run, so it always matches |
| 41 | +schemagen's pin rather than drifting as a stale vendored copy would. |
| 42 | + |
| 43 | +Schemagen has its own exact swift-syntax pin in `Package.swift`. Keep it |
| 44 | +synchronized with the SwiftPM parser pin in `../swift/Package.swift` and the |
| 45 | +Bazel pin in the repository's `MODULE.bazel`. The build systems resolve these |
| 46 | +independently, so regeneration does not itself guarantee that all three pins |
| 47 | +match. |
| 48 | + |
| 49 | +## What is filtered out |
| 50 | + |
| 51 | +The schema describes the JSON the extractor's adapter receives, not |
| 52 | +swift-syntax's tree verbatim, so `main.swift` mirrors what |
| 53 | +[`adapter.rs`][adapter] does: |
| 54 | + |
| 55 | +- Abstract base kinds become `supertypes:` entries rather than node kinds. |
| 56 | +- Collection nodes are dropped, and a collection-typed child is recorded as |
| 57 | + its element kinds, because the adapter elides collections into JSON arrays. |
| 58 | +- `unexpectedBeforeX`, `unexpectedBetweenXAndY`, and `unexpectedAfterX` |
| 59 | + error-recovery children are dropped; no rule matches them. This filters on |
| 60 | + the child name: `unexpectedCodeDecl` is a real node kind and is retained. |
| 61 | +- Token-typed children become the synthetic `_token` kind. Only the varying |
| 62 | + token kinds whose `TokenSpec` is `.other` and has no fixed text are emitted |
| 63 | + as kinds of their own. These are derived from `Token.allCases` and should match |
| 64 | + `VARYING_TOKEN_KINDS` in `adapter.rs`. Fixed tokens are anonymous and keyed |
| 65 | + by their text, so no rule can name them. |
| 66 | + |
| 67 | +Setting `EMIT_SUPERTYPES=0` omits the `supertypes:` section, which can be useful |
| 68 | +when diffing two versions for kind and field changes alone. |
| 69 | + |
| 70 | +[schema]: ../../extractor/swift_node_types.yml |
| 71 | +[mapping]: ../../extractor/src/languages/swift/swift.rs |
| 72 | +[adapter]: ../../extractor/src/languages/swift/adapter.rs |
0 commit comments