@import {Doc} from "../builders/index.js";
(doc, cb)
| 28 | */ |
| 29 | |
| 30 | function mapDoc(doc, cb) { |
| 31 | // Avoid creating `Map` |
| 32 | if (typeof doc === "string") { |
| 33 | return cb(doc); |
| 34 | } |
| 35 | |
| 36 | // Within a doc tree, the same subtrees can be found multiple times. |
| 37 | // E.g., often this happens in conditional groups. |
| 38 | // As an optimization (those subtrees can be huge) and to maintain the |
| 39 | // reference structure of the tree, the mapping results are cached in |
| 40 | // a map and reused. |
| 41 | const mapped = new Map(); |
| 42 | |
| 43 | return rec(doc); |
| 44 | |
| 45 | function rec(doc) { |
| 46 | return getOrInsertComputed(mapped, doc, process); |
| 47 | } |
| 48 | |
| 49 | function process(doc) { |
| 50 | switch (getDocType(doc)) { |
| 51 | case DOC_TYPE_ARRAY: |
| 52 | return cb(doc.map(rec)); |
| 53 | |
| 54 | case DOC_TYPE_FILL: |
| 55 | return cb({ ...doc, parts: doc.parts.map(rec) }); |
| 56 | |
| 57 | case DOC_TYPE_IF_BREAK: |
| 58 | return cb({ |
| 59 | ...doc, |
| 60 | breakContents: rec(doc.breakContents), |
| 61 | flatContents: rec(doc.flatContents), |
| 62 | }); |
| 63 | |
| 64 | case DOC_TYPE_GROUP: { |
| 65 | let { expandedStates, contents } = doc; |
| 66 | if (expandedStates) { |
| 67 | expandedStates = expandedStates.map(rec); |
| 68 | contents = expandedStates[0]; |
| 69 | } else { |
| 70 | contents = rec(contents); |
| 71 | } |
| 72 | return cb({ ...doc, contents, expandedStates }); |
| 73 | } |
| 74 | |
| 75 | case DOC_TYPE_ALIGN: |
| 76 | case DOC_TYPE_INDENT: |
| 77 | case DOC_TYPE_INDENT_IF_BREAK: |
| 78 | case DOC_TYPE_LABEL: |
| 79 | case DOC_TYPE_LINE_SUFFIX: |
| 80 | return cb({ ...doc, contents: rec(doc.contents) }); |
| 81 | |
| 82 | case DOC_TYPE_STRING: |
| 83 | case DOC_TYPE_CURSOR: |
| 84 | case DOC_TYPE_TRIM: |
| 85 | case DOC_TYPE_LINE_SUFFIX_BOUNDARY: |
| 86 | case DOC_TYPE_LINE: |
| 87 | case DOC_TYPE_BREAK_PARENT: |
no test coverage detected
searching dependent graphs…