Fix empty keys in implicit mappings.
This commit is contained in:
parent
7006620027
commit
e7f29450ca
2 changed files with 43 additions and 2 deletions
|
@ -251,6 +251,15 @@ pub struct Scanner<T> {
|
||||||
token_available: bool,
|
token_available: bool,
|
||||||
/// Whether all characters encountered since the last newline were whitespace.
|
/// Whether all characters encountered since the last newline were whitespace.
|
||||||
leading_whitespace: bool,
|
leading_whitespace: bool,
|
||||||
|
/// Whether we started a flow mapping.
|
||||||
|
///
|
||||||
|
/// This is used to detect implicit flow mapping starts such as:
|
||||||
|
/// ```yaml
|
||||||
|
/// [ : foo ] # { null: "foo" }
|
||||||
|
/// ```
|
||||||
|
flow_mapping_started: bool,
|
||||||
|
/// Whether we currently are in an implicit flow mapping.
|
||||||
|
implicit_flow_mapping: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Iterator<Item = char>> Iterator for Scanner<T> {
|
impl<T: Iterator<Item = char>> Iterator for Scanner<T> {
|
||||||
|
@ -365,6 +374,8 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
tokens_parsed: 0,
|
tokens_parsed: 0,
|
||||||
token_available: false,
|
token_available: false,
|
||||||
leading_whitespace: true,
|
leading_whitespace: true,
|
||||||
|
flow_mapping_started: false,
|
||||||
|
implicit_flow_mapping: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1217,6 +1228,10 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
let start_mark = self.mark;
|
let start_mark = self.mark;
|
||||||
self.skip();
|
self.skip();
|
||||||
|
|
||||||
|
if tok == TokenType::FlowMappingStart {
|
||||||
|
self.flow_mapping_started = true;
|
||||||
|
}
|
||||||
|
|
||||||
self.tokens.push_back(Token(start_mark, tok));
|
self.tokens.push_back(Token(start_mark, tok));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1227,6 +1242,8 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
|
|
||||||
self.disallow_simple_key();
|
self.disallow_simple_key();
|
||||||
|
|
||||||
|
self.end_implicit_mapping(self.mark);
|
||||||
|
|
||||||
let start_mark = self.mark;
|
let start_mark = self.mark;
|
||||||
self.skip();
|
self.skip();
|
||||||
|
|
||||||
|
@ -1239,6 +1256,8 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.remove_simple_key()?;
|
self.remove_simple_key()?;
|
||||||
self.allow_simple_key();
|
self.allow_simple_key();
|
||||||
|
|
||||||
|
self.end_implicit_mapping(self.mark);
|
||||||
|
|
||||||
let start_mark = self.mark;
|
let start_mark = self.mark;
|
||||||
self.skip();
|
self.skip();
|
||||||
|
|
||||||
|
@ -1899,6 +1918,9 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
TokenType::BlockMappingStart,
|
TokenType::BlockMappingStart,
|
||||||
start_mark,
|
start_mark,
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
// The parser, upon receiving a `Key`, will insert a `MappingStart` event.
|
||||||
|
self.flow_mapping_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.remove_simple_key()?;
|
self.remove_simple_key()?;
|
||||||
|
@ -1925,6 +1947,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
fn fetch_value(&mut self) -> ScanResult {
|
fn fetch_value(&mut self) -> ScanResult {
|
||||||
let sk = self.simple_keys.last().unwrap().clone();
|
let sk = self.simple_keys.last().unwrap().clone();
|
||||||
let start_mark = self.mark;
|
let start_mark = self.mark;
|
||||||
|
self.implicit_flow_mapping = self.flow_level > 0 && !self.flow_mapping_started;
|
||||||
|
|
||||||
// Skip over ':'.
|
// Skip over ':'.
|
||||||
self.skip();
|
self.skip();
|
||||||
|
@ -1943,6 +1966,12 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
let tok = Token(sk.mark, TokenType::Key);
|
let tok = Token(sk.mark, TokenType::Key);
|
||||||
let tokens_parsed = self.tokens_parsed;
|
let tokens_parsed = self.tokens_parsed;
|
||||||
self.insert_token(sk.token_number - tokens_parsed, tok);
|
self.insert_token(sk.token_number - tokens_parsed, tok);
|
||||||
|
if self.implicit_flow_mapping {
|
||||||
|
self.insert_token(
|
||||||
|
sk.token_number - tokens_parsed,
|
||||||
|
Token(self.mark, TokenType::FlowMappingStart),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Add the BLOCK-MAPPING-START token if needed.
|
// Add the BLOCK-MAPPING-START token if needed.
|
||||||
self.roll_indent(
|
self.roll_indent(
|
||||||
|
@ -1956,6 +1985,10 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.simple_keys.last_mut().unwrap().possible = false;
|
self.simple_keys.last_mut().unwrap().possible = false;
|
||||||
self.disallow_simple_key();
|
self.disallow_simple_key();
|
||||||
} else {
|
} else {
|
||||||
|
if self.implicit_flow_mapping {
|
||||||
|
self.tokens
|
||||||
|
.push_back(Token(self.mark, TokenType::FlowMappingStart));
|
||||||
|
}
|
||||||
// The ':' indicator follows a complex key.
|
// The ':' indicator follows a complex key.
|
||||||
if self.flow_level == 0 {
|
if self.flow_level == 0 {
|
||||||
if !self.simple_key_allowed {
|
if !self.simple_key_allowed {
|
||||||
|
@ -2096,6 +2129,16 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
fn is_within_block(&self) -> bool {
|
fn is_within_block(&self) -> bool {
|
||||||
!self.indents.is_empty()
|
!self.indents.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If an implicit mapping had started, end it.
|
||||||
|
fn end_implicit_mapping(&mut self, mark: Marker) {
|
||||||
|
if self.implicit_flow_mapping {
|
||||||
|
self.implicit_flow_mapping = false;
|
||||||
|
self.flow_mapping_started = false;
|
||||||
|
self.tokens
|
||||||
|
.push_back(Token(mark, TokenType::FlowMappingEnd));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Behavior to adopt regarding treating tabs as whitespace.
|
/// Behavior to adopt regarding treating tabs as whitespace.
|
||||||
|
|
|
@ -297,8 +297,6 @@ fn expected_events(expected_tree: &str) -> Vec<String> {
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
static EXPECTED_FAILURES: &[&str] = &[
|
static EXPECTED_FAILURES: &[&str] = &[
|
||||||
// Empty key in flow mappings
|
|
||||||
"CFD4",
|
|
||||||
// Document with no nodes and document end
|
// Document with no nodes and document end
|
||||||
"HWV9",
|
"HWV9",
|
||||||
"QT73",
|
"QT73",
|
||||||
|
|
Loading…
Reference in a new issue