| function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) { | |
| let spaceBefore = false; | |
| let atNewline = startOnNewline; | |
| let hasSpace = startOnNewline; | |
| let comment = ''; | |
| let commentSep = ''; | |
| let hasNewline = false; | |
| let reqSpace = false; | |
| let tab = null; | |
| let anchor = null; | |
| let tag = null; | |
| let newlineAfterProp = null; | |
| let comma = null; | |
| let found = null; | |
| let start = null; | |
| for (const token of tokens) { | |
| if (reqSpace) { | |
| if (token.type !== 'space' && | |
| token.type !== 'newline' && | |
| token.type !== 'comma') | |
| onError(token.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space'); | |
| reqSpace = false; | |
| } | |
| if (tab) { | |
| if (atNewline && token.type !== 'comment' && token.type !== 'newline') { | |
| onError(tab, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation'); | |
| } | |
| tab = null; | |
| } | |
| switch (token.type) { | |
| case 'space': | |
| // At the doc level, tabs at line start may be parsed | |
| // as leading white space rather than indentation. | |
| // In a flow collection, only the parser handles indent. | |
| if (!flow && | |
| (indicator !== 'doc-start' || next?.type !== 'flow-collection') && | |
| token.source.includes('\t')) { | |
| tab = token; | |
| } | |
| hasSpace = true; | |
| break; | |
| case 'comment': { | |
| if (!hasSpace) | |
| onError(token, 'MISSING_CHAR', 'Comments must be separated from other tokens by white space characters'); | |
| const cb = token.source.substring(1) || ' '; | |
| if (!comment) | |
| comment = cb; | |
| else | |
| comment += commentSep + cb; | |
| commentSep = ''; | |
| atNewline = false; | |
| break; | |
| } | |
| case 'newline': | |
| if (atNewline) { | |
| if (comment) | |
| comment += token.source; | |
| else if (!found || indicator !== 'seq-item-ind') | |
| spaceBefore = true; | |
| } | |
| else | |
| commentSep += token.source; | |
| atNewline = true; | |
| hasNewline = true; | |
| if (anchor || tag) | |
| newlineAfterProp = token; | |
| hasSpace = true; | |
| break; | |
| case 'anchor': | |
| if (anchor) | |
| onError(token, 'MULTIPLE_ANCHORS', 'A node can have at most one anchor'); | |
| if (token.source.endsWith(':')) | |
| onError(token.offset + token.source.length - 1, 'BAD_ALIAS', 'Anchor ending in : is ambiguous', true); | |
| anchor = token; | |
| start ?? (start = token.offset); | |
| atNewline = false; | |
| hasSpace = false; | |
| reqSpace = true; | |
| break; | |
| case 'tag': { | |
| if (tag) | |
| onError(token, 'MULTIPLE_TAGS', 'A node can have at most one tag'); | |
| tag = token; | |
| start ?? (start = token.offset); | |
| atNewline = false; | |
| hasSpace = false; | |
| reqSpace = true; | |
| break; | |
| } | |
| case indicator: | |
| // Could here handle preceding comments differently | |
| if (anchor || tag) | |
| onError(token, 'BAD_PROP_ORDER', `Anchors and tags must be after the ${token.source} indicator`); | |
| if (found) | |
| onError(token, 'UNEXPECTED_TOKEN', `Unexpected ${token.source} in ${flow ?? 'collection'}`); | |
| found = token; | |
| atNewline = | |
| indicator === 'seq-item-ind' || indicator === 'explicit-key-ind'; | |
| hasSpace = false; | |
| break; | |
| case 'comma': | |
| if (flow) { | |
| if (comma) | |
| onError(token, 'UNEXPECTED_TOKEN', `Unexpected , in ${flow}`); | |
| comma = token; | |
| atNewline = false; | |
| hasSpace = false; | |
| break; | |
| } | |
| // else fallthrough | |
| default: | |
| onError(token, 'UNEXPECTED_TOKEN', `Unexpected ${token.type} token`); | |
| atNewline = false; | |
| hasSpace = false; | |
| } | |
| } | |
| const last = tokens[tokens.length - 1]; | |
| const end = last ? last.offset + last.source.length : offset; | |
| if (reqSpace && | |
| next && | |
| next.type !== 'space' && | |
| next.type !== 'newline' && | |
| next.type !== 'comma' && | |
| (next.type !== 'scalar' || next.source !== '')) { | |
| onError(next.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space'); | |
| } | |
| if (tab && | |
| ((atNewline && tab.indent <= parentIndent) || | |
| next?.type === 'block-map' || | |
| next?.type === 'block-seq')) | |
| onError(tab, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation'); | |
| return { | |
| comma, | |
| found, | |
| spaceBefore, | |
| comment, | |
| hasNewline, | |
| anchor, | |
| tag, | |
| newlineAfterProp, | |
| end, | |
| start: start ?? end | |
| }; | |
| } | |
| export { resolveProps }; | |
Xet Storage Details
- Size:
- 5.55 kB
- Xet hash:
- aaa34899d9e11894682b045d9bfe265c827267b60d3c16110ffc51fe55348a58
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.