fix handling of empty sequence items

When a line contains only a dash it cannot safely be assumed that
it contains a nested list or an embedded mapping. If the next line
starts with a dash at the same indentation, the current line's item
is to be treated as `null`.
This commit is contained in:
Christian Flothmann 2014-08-29 13:30:22 +02:00
parent c730fc6f77
commit fc85435915
2 changed files with 41 additions and 4 deletions

View File

@ -93,7 +93,7 @@ class Parser
$c = $this->getRealCurrentLineNb() + 1; $c = $this->getRealCurrentLineNb() + 1;
$parser = new Parser($c); $parser = new Parser($c);
$parser->refs =& $this->refs; $parser->refs =& $this->refs;
$data[] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport); $data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport);
} else { } else {
if (isset($values['leadspaces']) if (isset($values['leadspaces'])
&& ' ' == $values['leadspaces'] && ' ' == $values['leadspaces']
@ -281,15 +281,20 @@ class Parser
/** /**
* Returns the next embed block of YAML. * Returns the next embed block of YAML.
* *
* @param int $indentation The indent level at which the block is to be read, or null for default * @param int $indentation The indent level at which the block is to be read, or null for default
* @param bool $inSequence True if the enclosing data structure is a sequence
* *
* @return string A YAML string * @return string A YAML string
* *
* @throws ParseException When indentation problem are detected * @throws ParseException When indentation problem are detected
*/ */
private function getNextEmbedBlock($indentation = null) private function getNextEmbedBlock($indentation = null, $inSequence = false)
{ {
$this->moveToNextLine(); $oldLineIndentation = $this->getCurrentLineIndentation();
if (!$this->moveToNextLine()) {
return;
}
if (null === $indentation) { if (null === $indentation) {
$newIndent = $this->getCurrentLineIndentation(); $newIndent = $this->getCurrentLineIndentation();
@ -305,6 +310,14 @@ class Parser
$data = array(substr($this->currentLine, $newIndent)); $data = array(substr($this->currentLine, $newIndent));
if ($inSequence && $oldLineIndentation === $newIndent && '-' === $data[0][0]) {
// the previous line contained a dash but no item content, this line is a sequence item with the same indentation
// and therefore no nested list or mapping
$this->moveToPreviousLine();
return;
}
$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem($this->currentLine); $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem($this->currentLine);
// Comments must not be removed inside a string block (ie. after a line ending with "|") // Comments must not be removed inside a string block (ie. after a line ending with "|")

View File

@ -11,6 +11,30 @@ yaml: |
php: | php: |
array('apple', 'banana', 'carrot') array('apple', 'banana', 'carrot')
--- ---
test: Sequence With Item Being Null In The Middle
brief: |
You can specify a list in YAML by placing each
member of the list on a new line with an opening
dash. These lists are called sequences.
yaml: |
- apple
-
- carrot
php: |
array('apple', null, 'carrot')
---
test: Sequence With Last Item Being Null
brief: |
You can specify a list in YAML by placing each
member of the list on a new line with an opening
dash. These lists are called sequences.
yaml: |
- apple
- banana
-
php: |
array('apple', 'banana', null)
---
test: Nested Sequences test: Nested Sequences
brief: | brief: |
You can include a sequence within another You can include a sequence within another