Skip to content

Converter: preserve choice type slicing (open/closed rules, all variants) - #19

Merged
ryukzak merged 2 commits into
mainfrom
test/choice-type-slicing
Jul 22, 2026
Merged

Converter: preserve choice type slicing (open/closed rules, all variants)#19
ryukzak merged 2 commits into
mainfrom
test/choice-type-slicing

Conversation

@ryukzak

@ryukzak ryukzak commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Type slicing on choice elements ($this type discriminator) — the pattern KBV Basis and US Core use on onset[x]/value[x] — was mangled by the converter:

  • a slicing root without an explicit type list was dropped entirely, losing slicing.rules (open/closed) and the discriminator
  • each slice re-expanded into its own parent element, so the last slice overwrote choices (e.g. KBV Condition.onset[x] with slices Period/Range/dateTime/Age came out as choices: ["onsetAge"])
  • variant elements got self-referential slicing.slices nodes with empty match: {} (type discriminators are skipped by buildMatchForSlice)

Fix: collapseChoiceTypeSlicing() rewrites such slicing into the plain choice representation before stack processing — the sliced element becomes the choice declaration (accumulated choices + preserved slicing metadata), each slice becomes a regular typed variant element (choiceOf set), and slice children are re-parented under their variant.

Before (KBV Condition.onset[x], open slicing with 4 type slices):

"onset": {
  "choices": ["onsetAge"],
  "slicing": { "slices": { "onsetAge": { "match": {}, "schema": { "choices": ["onsetAge"] } } } }
}

After:

"onset": {
  "choices": ["onsetPeriod", "onsetRange", "onsetDateTime", "onsetAge"],
  "slicing": { "discriminator": [{ "type": "type", "path": "$this" }], "rules": "open" }
}
  • First commit adds the regression tests (red on main), second commit makes them green.
  • Verified downstream against atomic-ehr/codegen main (make all fully green with this build linked): generated KBV profiles lose their false validateExcluded checks for open choice variants, previously-lost us-core-smokingstatus value[x] slice bindings materialize, and genuinely restricted profiles keep their exclusions.
  • Non-type slicing (pattern/value discriminators), extensions, and unsliced choices are untouched; slicing with any other discriminator shape keeps the existing behavior.

ryukzak added 2 commits July 22, 2026 12:08
Type slicing on choice elements ($this type discriminator) was mangled:
a slicing root without an explicit type list was dropped entirely (losing
slicing.rules and the discriminator), each slice overwrote the parent's
choices (only the last variant survived), and variants got self-referential
slices with empty matches.

Collapse such slicing into the plain choice representation before stack
processing: the sliced element becomes the choice declaration with
accumulated choices and the slicing metadata, each slice becomes a regular
typed variant element, and slice children are re-parented under their
variant.
@ryukzak
ryukzak merged commit bda8dd4 into main Jul 22, 2026
11 checks passed
@ryukzak
ryukzak deleted the test/choice-type-slicing branch July 22, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant