Skip to content

Commit

Permalink
Fix the range of empty scalars (#231)
Browse files Browse the repository at this point in the history
  • Loading branch information
eemeli committed Feb 20, 2021
1 parent 374e113 commit ed3bce7
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/compose/compose-doc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function composeDoc(

doc.contents = value
? composeNode(doc, value, props, onError)
: composeEmptyNode(doc, offset + props.length, props, onError)
: composeEmptyNode(doc, offset + props.length, start, null, props, onError)

const re = resolveEnd(end, doc.contents.range[1], false, onError)
if (re.comment) doc.comment = re.comment
Expand Down
10 changes: 9 additions & 1 deletion src/compose/compose-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { FlowScalar, Token } from '../parse/tokens.js'
import { composeCollection } from './compose-collection.js'
import { composeScalar } from './compose-scalar.js'
import { resolveEnd } from './resolve-end.js'
import { emptyScalarPosition } from './util-empty-scalar-position.js'

export interface Props {
spaceBefore: boolean
Expand Down Expand Up @@ -52,10 +53,17 @@ export function composeNode(
export function composeEmptyNode(
doc: Document.Parsed,
offset: number,
before: Token[] | undefined,
pos: number | null,
{ spaceBefore, comment, anchor, tagName }: Props,
onError: (offset: number, message: string, warning?: boolean) => void
) {
const token: FlowScalar = { type: 'scalar', offset, indent: -1, source: '' }
const token: FlowScalar = {
type: 'scalar',
offset: emptyScalarPosition(offset, before, pos),
indent: -1,
source: ''
}
const node = composeScalar(doc, token, anchor, tagName, onError)
if (spaceBefore) node.spaceBefore = true
if (comment) node.comment = comment
Expand Down
4 changes: 2 additions & 2 deletions src/compose/resolve-block-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function resolveBlockMap(
const keyStart = offset
const keyNode = key
? composeNode(doc, key, keyProps, onError)
: composeEmptyNode(doc, offset, keyProps, onError)
: composeEmptyNode(doc, offset, start, null, keyProps, onError)
offset = keyNode.range[1]

// value properties
Expand Down Expand Up @@ -88,7 +88,7 @@ export function resolveBlockMap(
// value value
const valueNode = value
? composeNode(doc, value, valueProps, onError)
: composeEmptyNode(doc, offset, valueProps, onError)
: composeEmptyNode(doc, offset, sep, null, valueProps, onError)
offset = valueNode.range[1]
const pair = new Pair(keyNode, valueNode)
map.items.push(doc.schema.merge ? resolveMergePair(pair, onError) : pair)
Expand Down
4 changes: 2 additions & 2 deletions src/compose/resolve-block-seq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function resolveBlockSeq(
const seq = new YAMLSeq(doc.schema)
seq.type = Type.SEQ
if (anchor) doc.anchors.setAnchor(seq, anchor)
loop: for (const { start, value } of items) {
for (const { start, value } of items) {
const props = resolveProps(
doc,
start,
Expand All @@ -40,7 +40,7 @@ export function resolveBlockSeq(
}
const node = value
? composeNode(doc, value, props, onError)
: composeEmptyNode(doc, offset, props, onError)
: composeEmptyNode(doc, offset, start, null, props, onError)
offset = node.range[1]
seq.items.push(node)
}
Expand Down
14 changes: 8 additions & 6 deletions src/compose/resolve-flow-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ export function resolveFlowCollection(
return props
}

function addItem() {
function addItem(pos: number) {
if (value) {
if (hasComment) value.comment = comment
} else {
value = composeEmptyNode(doc, offset, getProps(), onError)
value = composeEmptyNode(doc, offset, fc.items, pos, getProps(), onError)
}
if (isMap || atExplicitKey) {
const pair = key ? new Pair(key, value) : new Pair(value)
Expand All @@ -69,7 +69,8 @@ export function resolveFlowCollection(
}
}

for (const token of fc.items) {
for (let i = 0; i < fc.items.length; ++i) {
const token = fc.items[i]
let isSourceToken = true
switch (token.type) {
case 'space':
Expand Down Expand Up @@ -162,7 +163,7 @@ export function resolveFlowCollection(
key = value
value = null
} else {
key = composeEmptyNode(doc, offset, getProps(), onError)
key = composeEmptyNode(doc, offset, fc.items, i, getProps(), onError)
}
if (hasComment) {
key.comment = comment
Expand All @@ -175,7 +176,7 @@ export function resolveFlowCollection(
break
}
case 'comma':
if (key || value || anchor || tagName || atExplicitKey) addItem()
if (key || value || anchor || tagName || atExplicitKey) addItem(i)
else
onError(offset, `Unexpected , in flow ${isMap ? 'map' : 'sequence'}`)
key = null
Expand Down Expand Up @@ -206,7 +207,8 @@ export function resolveFlowCollection(
}
if (isSourceToken) offset += (token as SourceToken).source.length
}
if (key || value || anchor || tagName || atExplicitKey) addItem()
if (key || value || anchor || tagName || atExplicitKey)
addItem(fc.items.length)

const expectedEnd = isMap ? '}' : ']'
const [ce, ...ee] = fc.end
Expand Down
31 changes: 31 additions & 0 deletions src/compose/util-empty-scalar-position.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Token } from '../parse/tokens.js'

export function emptyScalarPosition(
offset: number,
before: Token[] | undefined,
pos: number | null
) {
if (before) {
if (pos === null) pos = before.length
for (let i = pos - 1; i >= 0; --i) {
let st = before[i]
switch (st.type) {
case 'space':
case 'comment':
case 'newline':
offset -= st.source.length
continue
}

// Technically, an empty scalar is immediately after the last non-empty
// node, but it's more useful to place it after any whitespace.
st = before[++i]
while (st?.type === 'space') {
offset += st.source.length
st = before[++i]
}
break
}
}
return offset
}
4 changes: 2 additions & 2 deletions tests/doc/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,10 +456,10 @@ test('comment between key & : in flow collection (eemeli/yaml#149)', () => {
)
})

test('empty node should respect setOrigRanges()', () => {
test('empty node position', () => {
const doc = YAML.parseDocument('\r\na: # 123\r\n')
const empty = doc.contents.items[0].value
expect(empty.range).toEqual([12, 12])
expect(empty.range).toEqual([5, 5])
})

test('parse an empty string as null', () => {
Expand Down

0 comments on commit ed3bce7

Please sign in to comment.