|
| 1 | +/** |
| 2 | + * The classification data `scripts/fact-inventory.ts` gates against: |
| 3 | + * every `src/ast.ts` property, sorted into FACTS (a printer under |
| 4 | + * `src/print/` reads it to choose an output SHAPE) or EXEMPT (a |
| 5 | + * discriminant, position bookkeeping, structural containment, |
| 6 | + * verbatim content, an unread record, a type-level sentinel, or a |
| 7 | + * container whose own arm's fields are classified separately). The |
| 8 | + * criterion, the verification method, and the surprises it turned up |
| 9 | + * are stated in `scripts/fact-inventory.ts`'s own module doc — this |
| 10 | + * file is the two maps alone, split out so that file stays under the |
| 11 | + * `max-lines` ceiling. |
| 12 | + * |
| 13 | + * Reasons are kept SHORT here on purpose (most owe their length to a |
| 14 | + * long key, not a long reason): the narrative for each recorded fact |
| 15 | + * — where the reparse-ledger fits, which test already exercises it — |
| 16 | + * lives in `scripts/fact-inventory-ledger.json`, which is what a |
| 17 | + * reader chasing "why is this a fact" should open next. |
| 18 | + */ |
| 19 | + |
| 20 | +/** Selects which printer function runs; carries no spelling of its own. */ |
| 21 | +const TYPE_DISCRIMINANT = |
| 22 | + "type discriminant, not a print-shape choice of its own"; |
| 23 | +/** The printer's byte output never reads this. */ |
| 24 | +const POSITION = "position bookkeeping, not read by the printer"; |
| 25 | +/** Walked by Prettier's path.map or the printer's own recursive print. */ |
| 26 | +const STRUCTURAL = "structural containment, not a shape choice of its own"; |
| 27 | +/** Copied into the output unconditionally; no branch on its own value. */ |
| 28 | +const CONTENT = "verbatim leaf content, copied unconditionally"; |
| 29 | +/** Constructed at parse time; no `src/print/*.ts` reference found. */ |
| 30 | +const UNREAD = "recorded but unread under src/print (verified by grep)"; |
| 31 | +/** `?: undefined`; never holds a runtime value. */ |
| 32 | +const SENTINEL = "type-level sentinel, never holds a value"; |
| 33 | +/** A record/union pointer whose own arms are classified separately. */ |
| 34 | +const CONTAINER = "container; its arm's fields are classified separately"; |
| 35 | + |
| 36 | +/** |
| 37 | + * Fields read under `src/print/` to choose between output shapes — |
| 38 | + * the recorded facts themselves. See `scripts/fact-inventory.ts` for |
| 39 | + * the criterion and `scripts/fact-inventory-ledger.json` for the |
| 40 | + * per-fact narrative. |
| 41 | + */ |
| 42 | +export const FACTS: ReadonlyMap<string, string> = new Map([ |
| 43 | + ["DocumentNode.byteOrderMark", "printer.ts replays it"], |
| 44 | + ["ParagraphNode.firstWordEndsItsLine", "block-start-hazard.ts's question"], |
| 45 | + ["BoldNode.constrained", "mark width choice"], |
| 46 | + ["ItalicNode.constrained", "mark width choice"], |
| 47 | + ["MonospaceNode.constrained", "mark width choice"], |
| 48 | + ["HighlightNode.constrained", "mark width choice"], |
| 49 | + ["CurvedQuoteNode.quote", "entity-pair choice"], |
| 50 | + ["LinkNode.text", "3-state bracket spelling"], |
| 51 | + ["InlineAnchorNode.form", "bracket-width choice"], |
| 52 | + ["InlineAnchorNode.reftext", "verbatim-replay framing"], |
| 53 | + ["HeadingNode.level", "only record of marker count"], |
| 54 | + ["DocumentHeaderNode.underline", "compat-mode spelling"], |
| 55 | + ["DiscreteHeadingNode.level", "marker-count fact"], |
| 56 | + ["CommentNode.commentType", "// vs //// choice"], |
| 57 | + ["AttributeEntryNode.unset", "collapses two spellings"], |
| 58 | + ["ListNode.variant", "callout marker path choice"], |
| 59 | + ["ListNode.marker", "printedGap's gap-fold key"], |
| 60 | + ["LeafDelimitedBlockNode.variant", "delimiter char lookup"], |
| 61 | + ["LeafDelimitedBlockNode.form", "framing-strategy choice"], |
| 62 | + ["FencedCodeBlockNode.variant", "delimiter char lookup"], |
| 63 | + ["FencedCodeBlockNode.form", "framing-strategy choice"], |
| 64 | + ["MasqueradedBlockNode.variant", "style-attribute label"], |
| 65 | + ["MasqueradedBlockNode.form", "framing-strategy choice"], |
| 66 | + ["IndentedLiteralBlockNode.variant", "delimiter char lookup"], |
| 67 | + ["IndentedLiteralBlockNode.form", "framing-strategy choice"], |
| 68 | + ["ParagraphFormBlockNode.variant", "style-attribute label"], |
| 69 | + ["ParagraphFormBlockNode.form", "framing-strategy choice"], |
| 70 | + ["LeafDelimitedBlockNode.annotatedBy", "invariant (xi)"], |
| 71 | + ["FencedCodeBlockNode.annotatedBy", "invariant (xi)"], |
| 72 | + ["FencedCodeBlockNode.language", "[source,lang] emission"], |
| 73 | + ["MasqueradedBlockNode.annotatedBy", "invariant (xi)"], |
| 74 | + ["MasqueradedBlockNode.sourceDelimiter", "invariant (xiii)"], |
| 75 | + ["IndentedLiteralBlockNode.annotatedBy", "invariant (xi)"], |
| 76 | + ["ParagraphFormBlockNode.annotatedBy", "invariant (xi)"], |
| 77 | + ["OpenParentBlockNode.openDelimiter", "tilde spelling, issue #64"], |
| 78 | + ["CompoundParentBlockNode.variant", "only record of the delimiter"], |
| 79 | + ["AdmonitionNode.form", "label vs delimited-wrapper"], |
| 80 | + ["ItemBody.trailingContinuation", "issue #181's landed lemma"], |
| 81 | + ["ItemBody.detachedTail", "detachedTail print arm"], |
| 82 | + ["ItemBody.activeTail", "blank-line count after list"], |
| 83 | + ["ItemBody.everyTextLineIndented", "reflow-guard input"], |
| 84 | + ["ListItemNode.markerSpelling", "printed marker bytes"], |
| 85 | + ["ListItemNode.markerIndent", "structure, not decoration"], |
| 86 | + ["ListItemNode.checkbox", "checklist marker bytes"], |
| 87 | + ["ListItemNode.calloutNumber", "callout marker bytes"], |
| 88 | + ["ItemBlock.gap", "the brief's own gap example"], |
| 89 | + ["DescriptionTermNode.line", "keeps three spellings apart"], |
| 90 | + ["DescriptionListItemNode.printing", "own doc: never re-derived"], |
| 91 | + ["TermEntry.gap", "gap alphabet, for a term"], |
| 92 | + ["TableNode.open", "psv/csv/dsv family choice"], |
| 93 | + ["TableNode.columns", "gates ragged-row decline"], |
| 94 | + ["TableNode.leadingRuns", "gates interior-content check"], |
| 95 | + ["TableNode.annotatedBy", "not covered by invariant (xi)"], |
| 96 | + ["TableNode.attrlistUnread", "declines layout normalization"], |
| 97 | + ["TableClose#0.kind", "gates the closing line"], |
| 98 | + ["TableClose#1.kind", "same fact, other arm"], |
| 99 | + ["TableCutting.format", "table-layout.ts's isNotPsv"], |
| 100 | + ["TableCutting.separator", "table-layout.ts's isNotPsv"], |
| 101 | + ["TableColumnSpec.style", "suppresses ws normalization"], |
| 102 | + ["TableCellNode.columnIndex", "own doc: recorded, not derived"], |
| 103 | + ["TableCellOpening#0.kind", "separator vs lineStart choice"], |
| 104 | + ["TableCellOpening#1.kind", "same fact, other arms"], |
| 105 | + ["TableTextRun.kind", "content/comment/blank choice"], |
| 106 | + ["TableTextRun.image", "table-partition bytes, (xv)"], |
| 107 | + ["TableCellSpec.style", "opening.parsed.style read"], |
| 108 | + ["TableCellRepeat#0.kind", "none/span/duplicate choice"], |
| 109 | + ["TableCellRepeat#1.kind", "same fact, other arms"], |
| 110 | + ["TableCellRepeat#1.colspan", "span calculation input"], |
| 111 | + ["TableCellRepeat#1.rowspan", "rowVisits reservation"], |
| 112 | + ["TableCellRepeat#2.kind", "same fact, other arms"], |
| 113 | + ["TableCellRepeat#2.count", "span calculation input"], |
| 114 | +]); |
| 115 | + |
| 116 | +/** |
| 117 | + * Fields that are NOT recorded facts, each with a reason (shared |
| 118 | + * constants above for the common buckets, a short bespoke string for |
| 119 | + * the rest). |
| 120 | + */ |
| 121 | +export const EXEMPT: ReadonlyMap<string, string> = new Map([ |
| 122 | + ["Location.offset", POSITION], |
| 123 | + ["Location.line", POSITION], |
| 124 | + ["Location.column", POSITION], |
| 125 | + ["Node.type", TYPE_DISCRIMINANT], |
| 126 | + ["Node.position", POSITION], |
| 127 | + ["DocumentNode.type", TYPE_DISCRIMINANT], |
| 128 | + ["DocumentNode.children", STRUCTURAL], |
| 129 | + ["ParagraphNode.type", TYPE_DISCRIMINANT], |
| 130 | + ["ParagraphNode.children", STRUCTURAL], |
| 131 | + ["TextNode.type", TYPE_DISCRIMINANT], |
| 132 | + ["TextNode.value", CONTENT], |
| 133 | + ["BoldNode.type", TYPE_DISCRIMINANT], |
| 134 | + ["BoldNode.role", CONTENT], |
| 135 | + ["BoldNode.children", STRUCTURAL], |
| 136 | + ["ItalicNode.type", TYPE_DISCRIMINANT], |
| 137 | + ["ItalicNode.role", CONTENT], |
| 138 | + ["ItalicNode.children", STRUCTURAL], |
| 139 | + ["MonospaceNode.type", TYPE_DISCRIMINANT], |
| 140 | + ["MonospaceNode.role", CONTENT], |
| 141 | + ["MonospaceNode.children", STRUCTURAL], |
| 142 | + ["HighlightNode.type", TYPE_DISCRIMINANT], |
| 143 | + ["HighlightNode.role", CONTENT], |
| 144 | + ["HighlightNode.children", STRUCTURAL], |
| 145 | + ["CurvedQuoteNode.type", TYPE_DISCRIMINANT], |
| 146 | + ["CurvedQuoteNode.children", STRUCTURAL], |
| 147 | + ["SuperscriptNode.type", TYPE_DISCRIMINANT], |
| 148 | + ["SuperscriptNode.children", STRUCTURAL], |
| 149 | + ["SubscriptNode.type", TYPE_DISCRIMINANT], |
| 150 | + ["SubscriptNode.children", STRUCTURAL], |
| 151 | + ["CharacterReferenceNode.type", TYPE_DISCRIMINANT], |
| 152 | + ["CharacterReferenceNode.value", CONTENT], |
| 153 | + ["EscapedMarkNode.type", TYPE_DISCRIMINANT], |
| 154 | + ["EscapedMarkNode.value", CONTENT], |
| 155 | + ["AttributeReferenceNode.type", TYPE_DISCRIMINANT], |
| 156 | + ["AttributeReferenceNode.name", CONTENT], |
| 157 | + ["LinkNode.type", TYPE_DISCRIMINANT], |
| 158 | + ["LinkNode.form", "own doc: unread"], |
| 159 | + ["LinkNode.target", CONTENT], |
| 160 | + ["XrefNode.type", TYPE_DISCRIMINANT], |
| 161 | + ["XrefNode.form", 'fixed "shorthand"'], |
| 162 | + ["XrefNode.target", CONTENT], |
| 163 | + ["XrefNode.text", "ordinary optional content"], |
| 164 | + ["InlineAnchorNode.type", TYPE_DISCRIMINANT], |
| 165 | + ["InlineAnchorNode.id", CONTENT], |
| 166 | + ["InlineMacroNode.type", TYPE_DISCRIMINANT], |
| 167 | + ["InlineMacroNode.name", CONTENT], |
| 168 | + ["InlineMacroNode.target", CONTENT], |
| 169 | + ["InlineMacroNode.attrlist", CONTENT], |
| 170 | + ["HardLineBreakNode.type", TYPE_DISCRIMINANT], |
| 171 | + ["RawLineNode.type", TYPE_DISCRIMINANT], |
| 172 | + ["RawLineNode.value", CONTENT], |
| 173 | + ["PassthroughNode.type", TYPE_DISCRIMINANT], |
| 174 | + ["PassthroughNode.value", CONTENT], |
| 175 | + ["HeadingNode.type", TYPE_DISCRIMINANT], |
| 176 | + ["HeadingNode.title", CONTENT], |
| 177 | + ["AuthorLineNode.type", TYPE_DISCRIMINANT], |
| 178 | + ["AuthorLineNode.value", CONTENT], |
| 179 | + ["RevisionLineNode.type", TYPE_DISCRIMINANT], |
| 180 | + ["RevisionLineNode.value", CONTENT], |
| 181 | + ["DocumentHeaderNode.type", TYPE_DISCRIMINANT], |
| 182 | + ["DocumentHeaderNode.title", CONTENT], |
| 183 | + ["DocumentHeaderNode.lines", STRUCTURAL], |
| 184 | + ["DiscreteHeadingNode.type", TYPE_DISCRIMINANT], |
| 185 | + ["DiscreteHeadingNode.title", CONTENT], |
| 186 | + ["CommentNode.type", TYPE_DISCRIMINANT], |
| 187 | + ["CommentNode.value", CONTENT], |
| 188 | + ["AttributeEntryNode.type", TYPE_DISCRIMINANT], |
| 189 | + ["AttributeEntryNode.name", CONTENT], |
| 190 | + ["AttributeEntryNode.value", CONTENT], |
| 191 | + ["ListNode.type", TYPE_DISCRIMINANT], |
| 192 | + ["ListNode.children", STRUCTURAL], |
| 193 | + ["LeafDelimitedBlockNode.type", TYPE_DISCRIMINANT], |
| 194 | + ["LeafDelimitedBlockNode.content", CONTENT], |
| 195 | + ["FencedCodeBlockNode.type", TYPE_DISCRIMINANT], |
| 196 | + ["FencedCodeBlockNode.content", CONTENT], |
| 197 | + ["MasqueradedBlockNode.type", TYPE_DISCRIMINANT], |
| 198 | + ["MasqueradedBlockNode.content", CONTENT], |
| 199 | + ["IndentedLiteralBlockNode.type", TYPE_DISCRIMINANT], |
| 200 | + ["IndentedLiteralBlockNode.content", CONTENT], |
| 201 | + ["ParagraphFormBlockNode.type", TYPE_DISCRIMINANT], |
| 202 | + ["ParagraphFormBlockNode.content", CONTENT], |
| 203 | + ["LeafDelimitedBlockNode.sourceDelimiter", SENTINEL], |
| 204 | + ["LeafDelimitedBlockNode.fenced", SENTINEL], |
| 205 | + ["LeafDelimitedBlockNode.language", SENTINEL], |
| 206 | + ["FencedCodeBlockNode.sourceDelimiter", SENTINEL], |
| 207 | + ["FencedCodeBlockNode.fenced", "fixed literal true"], |
| 208 | + ["MasqueradedBlockNode.fenced", SENTINEL], |
| 209 | + ["MasqueradedBlockNode.language", SENTINEL], |
| 210 | + ["IndentedLiteralBlockNode.sourceDelimiter", SENTINEL], |
| 211 | + ["IndentedLiteralBlockNode.fenced", SENTINEL], |
| 212 | + ["IndentedLiteralBlockNode.language", SENTINEL], |
| 213 | + ["ParagraphFormBlockNode.sourceDelimiter", SENTINEL], |
| 214 | + ["ParagraphFormBlockNode.fenced", SENTINEL], |
| 215 | + ["ParagraphFormBlockNode.language", SENTINEL], |
| 216 | + ["OpenParentBlockNode.type", TYPE_DISCRIMINANT], |
| 217 | + ["OpenParentBlockNode.variant", 'fixed "open"'], |
| 218 | + ["OpenParentBlockNode.children", STRUCTURAL], |
| 219 | + ["CompoundParentBlockNode.type", TYPE_DISCRIMINANT], |
| 220 | + ["CompoundParentBlockNode.openDelimiter", SENTINEL], |
| 221 | + ["CompoundParentBlockNode.children", STRUCTURAL], |
| 222 | + ["AdmonitionNode.type", TYPE_DISCRIMINANT], |
| 223 | + ["AdmonitionNode.variant", "label text, case only"], |
| 224 | + ["AdmonitionNode.text", STRUCTURAL], |
| 225 | + ["AdmonitionNode.children", STRUCTURAL], |
| 226 | + ["ThematicBreakNode.type", TYPE_DISCRIMINANT], |
| 227 | + ["BlockMacroNode.type", TYPE_DISCRIMINANT], |
| 228 | + ["BlockMacroNode.name", CONTENT], |
| 229 | + ["BlockMacroNode.target", CONTENT], |
| 230 | + ["BlockMacroNode.attrlist", CONTENT], |
| 231 | + ["FrontMatterNode.type", TYPE_DISCRIMINANT], |
| 232 | + ["FrontMatterNode.content", CONTENT], |
| 233 | + ["PreprocessorDirectiveNode.type", TYPE_DISCRIMINANT], |
| 234 | + ["PreprocessorDirectiveNode.value", CONTENT], |
| 235 | + ["PageBreakNode.type", TYPE_DISCRIMINANT], |
| 236 | + ["ItemBody.text", STRUCTURAL], |
| 237 | + ["ItemBody.blocks", STRUCTURAL], |
| 238 | + ["ListItemNode.type", TYPE_DISCRIMINANT], |
| 239 | + ["ItemBlock.block", STRUCTURAL], |
| 240 | + ["DescriptionListNode.type", TYPE_DISCRIMINANT], |
| 241 | + ["DescriptionListNode.delimiter", "grouping key, not bytes"], |
| 242 | + ["DescriptionListNode.children", STRUCTURAL], |
| 243 | + ["DescriptionTermNode.type", TYPE_DISCRIMINANT], |
| 244 | + ["DescriptionTermNode.children", STRUCTURAL], |
| 245 | + ["DescriptionListItemNode.type", TYPE_DISCRIMINANT], |
| 246 | + ["DescriptionListItemNode.terms", STRUCTURAL], |
| 247 | + ["DescriptionListItemNode.textLines", "replay bytes; printing is the fact"], |
| 248 | + ["TermEntry.term", STRUCTURAL], |
| 249 | + ["TermGapComment.comment", CONTENT], |
| 250 | + ["BlockAttributeListNode.type", TYPE_DISCRIMINANT], |
| 251 | + ["BlockAttributeListNode.value", CONTENT], |
| 252 | + ["BlockTitleNode.type", TYPE_DISCRIMINANT], |
| 253 | + ["BlockTitleNode.title", CONTENT], |
| 254 | + ["BlockAnchorNode.type", TYPE_DISCRIMINANT], |
| 255 | + ["BlockAnchorNode.id", CONTENT], |
| 256 | + ["BlockAnchorNode.reftext", "ordinary optional content"], |
| 257 | + ["TableNode.type", TYPE_DISCRIMINANT], |
| 258 | + ["TableNode.children", STRUCTURAL], |
| 259 | + ["TableNode.close", CONTAINER], |
| 260 | + ["TableNode.cutting", CONTAINER], |
| 261 | + ["TableNode.header", "own doc: derived predicate"], |
| 262 | + ["TableNode.footer", UNREAD], |
| 263 | + ["TableClose#0.image", UNREAD], |
| 264 | + ["TableColumnSpec.halign", UNREAD], |
| 265 | + ["TableColumnSpec.valign", UNREAD], |
| 266 | + ["TableRowNode.type", TYPE_DISCRIMINANT], |
| 267 | + ["TableRowNode.children", STRUCTURAL], |
| 268 | + ["TableCellNode.type", TYPE_DISCRIMINANT], |
| 269 | + ["TableCellNode.opening", CONTAINER], |
| 270 | + ["TableCellNode.runs", CONTAINER], |
| 271 | + ["TableCellNode.repeat", CONTAINER], |
| 272 | + ["TableCellOpening#0.parsed", CONTAINER], |
| 273 | + ["TableCellOpening#0.spec", "concatenated unconditionally into cellImage"], |
| 274 | + [ |
| 275 | + "TableCellOpening#0.separator", |
| 276 | + "concatenated unconditionally into cellImage", |
| 277 | + ], |
| 278 | + ["TableCellOpening#0.offset", POSITION], |
| 279 | + ["TableCellOpening#1.offset", POSITION], |
| 280 | + ["TableTextRun.offset", POSITION], |
| 281 | + ["TableCellSpec.repeat", UNREAD], |
| 282 | + ["TableCellSpec.halign", UNREAD], |
| 283 | + ["TableCellSpec.valign", UNREAD], |
| 284 | +]); |
0 commit comments