diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index a6e39007dfe0f..773837c995588 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -537,7 +537,27 @@ private function getNextEmbedBlock($indentation = null, $inSequence = false) } if (null === $indentation) { - $newIndent = $this->getCurrentLineIndentation(); + $newIndent = null; + $movements = 0; + + do { + $EOF = false; + + // comment-like lines do not influence the indentation depth + if ($this->isCurrentLineComment()) { + $EOF = !$this->moveToNextLine(); + + if (!$EOF) { + ++$movements; + } + } else { + $newIndent = $this->getCurrentLineIndentation(); + } + } while (!$EOF && null === $newIndent); + + for ($i = 0; $i < $movements; ++$i) { + $this->moveToPreviousLine(); + } $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem(); @@ -551,6 +571,8 @@ private function getNextEmbedBlock($indentation = null, $inSequence = false) $data = array(); if ($this->getCurrentLineIndentation() >= $newIndent) { $data[] = substr($this->currentLine, $newIndent); + } elseif ($this->isCurrentLineComment()) { + $data[] = $this->currentLine; } else { $this->moveToPreviousLine(); @@ -866,11 +888,15 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0) private function isNextLineIndented() { $currentIndentation = $this->getCurrentLineIndentation(); - $EOF = !$this->moveToNextLine(); + $movements = 0; - while (!$EOF && $this->isCurrentLineEmpty()) { + do { $EOF = !$this->moveToNextLine(); - } + + if (!$EOF) { + ++$movements; + } + } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment())); if ($EOF) { return false; @@ -878,7 +904,9 @@ private function isNextLineIndented() $ret = $this->getCurrentLineIndentation() > $currentIndentation; - $this->moveToPreviousLine(); + for ($i = 0; $i < $movements; ++$i) { + $this->moveToPreviousLine(); + } return $ret; } @@ -967,19 +995,25 @@ private function cleanup($value) private function isNextLineUnIndentedCollection() { $currentIndentation = $this->getCurrentLineIndentation(); - $notEOF = $this->moveToNextLine(); + $movements = 0; - while ($notEOF && $this->isCurrentLineEmpty()) { - $notEOF = $this->moveToNextLine(); - } + do { + $EOF = !$this->moveToNextLine(); + + if (!$EOF) { + ++$movements; + } + } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment())); - if (false === $notEOF) { + if ($EOF) { return false; } $ret = $this->getCurrentLineIndentation() === $currentIndentation && $this->isStringUnIndentedCollectionItem(); - $this->moveToPreviousLine(); + for ($i = 0; $i < $movements; ++$i) { + $this->moveToPreviousLine(); + } return $ret; } diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 1d35ecc1bd819..73a482b9399c7 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -2013,6 +2013,68 @@ public function testEvalRefException() EOE; $this->parser->parse($yaml); } + + /** + * @dataProvider indentedMappingData + */ + public function testParseIndentedMappings($yaml, $expected) + { + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function indentedMappingData() + { + $tests = array(); + + $yaml = << array( + array( + 'bar' => 'foobar', + 'baz' => 'foobaz', + ), + ), + ); + $tests['comment line is first line in indented block'] = array($yaml, $expected); + + $yaml = << array( + array( + 'bar' => array( + 'baz' => array(1, 2, 3), + ), + ), + ), + ); + $tests['mapping value on new line starting with a comment line'] = array($yaml, $expected); + + $yaml = << array( + array( + 'bar' => 'foobar', + ), + ), + ); + $tests['mapping in sequence starting on a new line'] = array($yaml, $expected); + + return $tests; + } } class B