fix(parsing): end a tagged zero-indent sequence at a sibling key
A block sequence value carrying an inline property (`sequence: !!seq` then `- entry` at the key's column) is a zero-indent sequence: its entries sit at the mapping key's own indentation, so a following sibling key ends it. The untagged form was already parsed as a zero-indent sequence that stops at a sibling mapping key, but the property-bearing form fell through to the generic node path, which parsed the sequence without that terminator and read the sibling key as a mixed sequence-and-mapping entry. The zero-indent sequence is now handled before the generic path, carrying any property to the sequence. Fixes yaml-test-suite 57H4; raises parse-level conformance to 313/333 (94.0%) and value-level to 206/206 (100.0%), with the should-error rate unchanged.
This commit is contained in:
parent
4dcedbd6aa
commit
5ea6fa668b
@ -84,6 +84,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
|
||||
- A block sequence value carrying an inline property (`sequence: !!seq` then `- entry` at the key's
|
||||
column) is now correctly terminated by a sibling mapping key. Such a zero-indent sequence has its
|
||||
entries at the mapping key's own indentation, so a following key ends it. The untagged form already
|
||||
stopped at the sibling key, but the property-bearing form was routed through the generic node path,
|
||||
which read the sibling key as a mixed sequence-and-mapping entry and rejected the document. The
|
||||
zero-indent sequence is now handled before that path, with or without a property. Fixes
|
||||
yaml-test-suite 57H4; raises parse-level conformance to 313/333 (94.0%) and value-level to 206/206
|
||||
(100.0%), with the should-error rate unchanged.
|
||||
|
||||
- Node properties that span their own indented lines above a further-indented node now attach to
|
||||
that node (`key: &anchor` then ` !!map` then ` a: b`). An inline anchor with a tag on the next
|
||||
indented line, above a mapping indented deeper still, left the node introduced by another indent
|
||||
|
||||
@ -43,15 +43,20 @@ extension PureYAML.Parsing.TokenEventParser {
|
||||
if properties != .none, cursor.current?.kind.isMappingKey == true {
|
||||
return try emitEmptyNodeOrThrow(properties: properties)
|
||||
}
|
||||
if properties != .none || hasNodeOnSameLine(after: valueIndicator) {
|
||||
return try parseNode(properties: properties)
|
||||
}
|
||||
if cursor.current?.kind.isBlockEntry == true {
|
||||
// A block sequence value whose entries return to the mapping key's own indentation is a
|
||||
// zero-indent sequence, which a sibling mapping key terminates. This holds whether or not
|
||||
// the value carries properties (`seq: !!seq` then `- a`), so it is handled before the
|
||||
// generic property-bearing node below, which would not stop at the sibling key and would
|
||||
// misread it as a mixed collection.
|
||||
return try parseBlockSequence(
|
||||
properties: properties,
|
||||
allowMappingKeyTerminator: true,
|
||||
)
|
||||
}
|
||||
if properties != .none || hasNodeOnSameLine(after: valueIndicator) {
|
||||
return try parseNode(properties: properties)
|
||||
}
|
||||
|
||||
return try emitNullMappingValue(at: valueIndicator.endMark)
|
||||
}
|
||||
|
||||
27
Tests/TaggedZeroIndentSequenceTests.swift
Normal file
27
Tests/TaggedZeroIndentSequenceTests.swift
Normal file
@ -0,0 +1,27 @@
|
||||
@testable import PureYAML
|
||||
import Testing
|
||||
|
||||
@Suite("A tagged zero-indent block sequence is terminated by a sibling mapping key")
|
||||
struct TaggedZeroIndentSequenceTests {
|
||||
/// yaml-test-suite 57H4: a block sequence value carrying an inline tag (`sequence: !!seq` then
|
||||
/// `- entry` at the key's column) is a zero-indent sequence whose entries sit at the mapping
|
||||
/// key's indentation. A following sibling key (`mapping:`) ends the sequence rather than mixing
|
||||
/// into it, the same as an untagged zero-indent sequence.
|
||||
@Test("A tagged zero-indent sequence ends at the next sibling key")
|
||||
func test_taggedZeroIndentSequence() throws {
|
||||
let root = try requireMapping(PureYAML.parse(
|
||||
"sequence: !!seq\n- entry\n- !!seq\n - nested\nmapping: !!map\n foo: bar\n",
|
||||
))
|
||||
#expect(root?["sequence"] == .sequence([.string("entry"), .sequence([.string("nested")])]))
|
||||
let mapping = try requireMapping(#require(root?["mapping"]))
|
||||
#expect(mapping?["foo"] == .string("bar"))
|
||||
}
|
||||
|
||||
/// The untagged zero-indent sequence followed by a sibling key keeps working unchanged.
|
||||
@Test("An untagged zero-indent sequence still ends at the next sibling key")
|
||||
func test_untaggedZeroIndentSequence() throws {
|
||||
let root = try requireMapping(PureYAML.parse("seq:\n- a\n- b\nother: x\n"))
|
||||
#expect(root?["seq"] == .sequence([.string("a"), .string("b")]))
|
||||
#expect(root?["other"] == .string("x"))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user