| import { Pair } from '../nodes/Pair.js'; | |
| import { YAMLMap } from '../nodes/YAMLMap.js'; | |
| import { resolveProps } from './resolve-props.js'; | |
| import { containsNewline } from './util-contains-newline.js'; | |
| import { flowIndentCheck } from './util-flow-indent-check.js'; | |
| import { mapIncludes } from './util-map-includes.js'; | |
| const startColMsg = 'All mapping items must start at the same column'; | |
| function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError, tag) { | |
| const NodeClass = tag?.nodeClass ?? YAMLMap; | |
| const map = new NodeClass(ctx.schema); | |
| if (ctx.atRoot) | |
| ctx.atRoot = false; | |
| let offset = bm.offset; | |
| let commentEnd = null; | |
| for (const collItem of bm.items) { | |
| const { start, key, sep, value } = collItem; | |
| // key properties | |
| const keyProps = resolveProps(start, { | |
| indicator: 'explicit-key-ind', | |
| next: key ?? sep?.[0], | |
| offset, | |
| onError, | |
| parentIndent: bm.indent, | |
| startOnNewline: true | |
| }); | |
| const implicitKey = !keyProps.found; | |
| if (implicitKey) { | |
| if (key) { | |
| if (key.type === 'block-seq') | |
| onError(offset, 'BLOCK_AS_IMPLICIT_KEY', 'A block sequence may not be used as an implicit map key'); | |
| else if ('indent' in key && key.indent !== bm.indent) | |
| onError(offset, 'BAD_INDENT', startColMsg); | |
| } | |
| if (!keyProps.anchor && !keyProps.tag && !sep) { | |
| commentEnd = keyProps.end; | |
| if (keyProps.comment) { | |
| if (map.comment) | |
| map.comment += '\n' + keyProps.comment; | |
| else | |
| map.comment = keyProps.comment; | |
| } | |
| continue; | |
| } | |
| if (keyProps.newlineAfterProp || containsNewline(key)) { | |
| onError(key ?? start[start.length - 1], 'MULTILINE_IMPLICIT_KEY', 'Implicit keys need to be on a single line'); | |
| } | |
| } | |
| else if (keyProps.found?.indent !== bm.indent) { | |
| onError(offset, 'BAD_INDENT', startColMsg); | |
| } | |
| // key value | |
| ctx.atKey = true; | |
| const keyStart = keyProps.end; | |
| const keyNode = key | |
| ? composeNode(ctx, key, keyProps, onError) | |
| : composeEmptyNode(ctx, keyStart, start, null, keyProps, onError); | |
| if (ctx.schema.compat) | |
| flowIndentCheck(bm.indent, key, onError); | |
| ctx.atKey = false; | |
| if (mapIncludes(ctx, map.items, keyNode)) | |
| onError(keyStart, 'DUPLICATE_KEY', 'Map keys must be unique'); | |
| // value properties | |
| const valueProps = resolveProps(sep ?? [], { | |
| indicator: 'map-value-ind', | |
| next: value, | |
| offset: keyNode.range[2], | |
| onError, | |
| parentIndent: bm.indent, | |
| startOnNewline: !key || key.type === 'block-scalar' | |
| }); | |
| offset = valueProps.end; | |
| if (valueProps.found) { | |
| if (implicitKey) { | |
| if (value?.type === 'block-map' && !valueProps.hasNewline) | |
| onError(offset, 'BLOCK_AS_IMPLICIT_KEY', 'Nested mappings are not allowed in compact mappings'); | |
| if (ctx.options.strict && | |
| keyProps.start < valueProps.found.offset - 1024) | |
| onError(keyNode.range, 'KEY_OVER_1024_CHARS', 'The : indicator must be at most 1024 chars after the start of an implicit block mapping key'); | |
| } | |
| // value value | |
| const valueNode = value | |
| ? composeNode(ctx, value, valueProps, onError) | |
| : composeEmptyNode(ctx, offset, sep, null, valueProps, onError); | |
| if (ctx.schema.compat) | |
| flowIndentCheck(bm.indent, value, onError); | |
| offset = valueNode.range[2]; | |
| const pair = new Pair(keyNode, valueNode); | |
| if (ctx.options.keepSourceTokens) | |
| pair.srcToken = collItem; | |
| map.items.push(pair); | |
| } | |
| else { | |
| // key with no value | |
| if (implicitKey) | |
| onError(keyNode.range, 'MISSING_CHAR', 'Implicit map keys need to be followed by map values'); | |
| if (valueProps.comment) { | |
| if (keyNode.comment) | |
| keyNode.comment += '\n' + valueProps.comment; | |
| else | |
| keyNode.comment = valueProps.comment; | |
| } | |
| const pair = new Pair(keyNode); | |
| if (ctx.options.keepSourceTokens) | |
| pair.srcToken = collItem; | |
| map.items.push(pair); | |
| } | |
| } | |
| if (commentEnd && commentEnd < offset) | |
| onError(commentEnd, 'IMPOSSIBLE', 'Map comment with trailing content'); | |
| map.range = [bm.offset, offset, commentEnd ?? offset]; | |
| return map; | |
| } | |
| export { resolveBlockMap }; | |
Xet Storage Details
- Size:
- 4.92 kB
- Xet hash:
- a9595746cdeae664d29d8913e5cda9d9434c14cde95744e2c46868b1a4c71677
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.