Skip to content

Commit 8b0a3a4

Browse files
committed
fix: Set correct node-end position for block collections with comments (#413)
1 parent acb5f47 commit 8b0a3a4

File tree

3 files changed

+48
-7
lines changed

3 files changed

+48
-7
lines changed

src/compose/resolve-block-map.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export function resolveBlockMap(
2121

2222
if (ctx.atRoot) ctx.atRoot = false
2323
let offset = bm.offset
24+
let commentEnd: number | null = null
2425
for (const collItem of bm.items) {
2526
const { start, key, sep, value } = collItem
2627

@@ -45,7 +46,7 @@ export function resolveBlockMap(
4546
onError(offset, 'BAD_INDENT', startColMsg)
4647
}
4748
if (!keyProps.anchor && !keyProps.tag && !sep) {
48-
// TODO: assert being at last item?
49+
commentEnd = keyProps.end
4950
if (keyProps.comment) {
5051
if (map.comment) map.comment += '\n' + keyProps.comment
5152
else map.comment = keyProps.comment
@@ -128,6 +129,8 @@ export function resolveBlockMap(
128129
}
129130
}
130131

131-
map.range = [bm.offset, offset, offset]
132+
if (commentEnd && commentEnd < offset)
133+
onError(commentEnd, 'IMPOSSIBLE', 'Map comment with trailing content')
134+
map.range = [bm.offset, offset, commentEnd ?? offset]
132135
return map as YAMLMap.Parsed
133136
}

src/compose/resolve-block-seq.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export function resolveBlockSeq(
1515

1616
if (ctx.atRoot) ctx.atRoot = false
1717
let offset = bs.offset
18+
let commentEnd: number | null = null
1819
for (const { start, value } of bs.items) {
1920
const props = resolveProps(start, {
2021
indicator: 'seq-item-ind',
@@ -23,30 +24,29 @@ export function resolveBlockSeq(
2324
onError,
2425
startOnNewline: true
2526
})
26-
offset = props.end
2727
if (!props.found) {
2828
if (props.anchor || props.tag || value) {
2929
if (value && value.type === 'block-seq')
3030
onError(
31-
offset,
31+
props.end,
3232
'BAD_INDENT',
3333
'All sequence items must start at the same column'
3434
)
3535
else
3636
onError(offset, 'MISSING_CHAR', 'Sequence item without - indicator')
3737
} else {
38-
// TODO: assert being at last item?
38+
commentEnd = props.end
3939
if (props.comment) seq.comment = props.comment
4040
continue
4141
}
4242
}
4343
const node = value
4444
? composeNode(ctx, value, props, onError)
45-
: composeEmptyNode(ctx, offset, start, null, props, onError)
45+
: composeEmptyNode(ctx, props.end, start, null, props, onError)
4646
if (ctx.schema.compat) flowIndentCheck(bs.indent, value, onError)
4747
offset = node.range[2]
4848
seq.items.push(node)
4949
}
50-
seq.range = [bs.offset, offset, offset]
50+
seq.range = [bs.offset, offset, commentEnd ?? offset]
5151
return seq as YAMLSeq.Parsed
5252
}

tests/doc/errors.js

+38
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,44 @@ describe('block collections', () => {
140140
`)
141141
expect(doc.errors).toMatchObject([])
142142
})
143+
144+
test('key after long comment on block map (eemeli/yaml#413)', () => {
145+
const doc = YAML.parseDocument(source`
146+
one:
147+
sub: a
148+
# large block of text, large block of text, large block of text, large block of text, large block of text,
149+
# large block of text, large block of text, large block of text, large block of text, large block of text,
150+
# large block of text, large block of text, large block of text, large block of text, large block of text,
151+
# large block of text, large block of text, large block of text, large block of text, large block of text,
152+
# large block of text, large block of text, large block of text, large block of text, large block of text,
153+
# large block of text, large block of text, large block of text, large block of text, large block of text,
154+
# large block of text, large block of text, large block of text, large block of text, large block of text,
155+
# large block of text, large block of text, large block of text, large block of text, large block of text,
156+
# large block of text, large block of text, large block of text, large block of text, large block of text,
157+
# large block of text, large block of text, large block of text, large block of text, large block of text,
158+
two: b
159+
`)
160+
expect(doc.errors).toMatchObject([])
161+
})
162+
163+
test('key after long comment on block seq (eemeli/yaml#413)', () => {
164+
const doc = YAML.parseDocument(source`
165+
one:
166+
- a
167+
# large block of text, large block of text, large block of text, large block of text, large block of text,
168+
# large block of text, large block of text, large block of text, large block of text, large block of text,
169+
# large block of text, large block of text, large block of text, large block of text, large block of text,
170+
# large block of text, large block of text, large block of text, large block of text, large block of text,
171+
# large block of text, large block of text, large block of text, large block of text, large block of text,
172+
# large block of text, large block of text, large block of text, large block of text, large block of text,
173+
# large block of text, large block of text, large block of text, large block of text, large block of text,
174+
# large block of text, large block of text, large block of text, large block of text, large block of text,
175+
# large block of text, large block of text, large block of text, large block of text, large block of text,
176+
# large block of text, large block of text, large block of text, large block of text, large block of text,
177+
two: b
178+
`)
179+
expect(doc.errors).toMatchObject([])
180+
})
143181
})
144182

145183
describe('flow collections', () => {

0 commit comments

Comments
 (0)