[Yaml] recognize when a block scalar is left

The parser did not recognize when the block scalar was completely parsed
and thus treated following comments as they need to be kept leading to
parse errors on the following lines.
This commit is contained in:
Christian Flothmann 2015-12-28 15:55:02 +01:00
parent a89fe42811
commit 3a2216559b
2 changed files with 67 additions and 15 deletions

View File

@ -303,7 +303,11 @@ class Parser
private function getNextEmbedBlock($indentation = null, $inSequence = false) private function getNextEmbedBlock($indentation = null, $inSequence = false)
{ {
$oldLineIndentation = $this->getCurrentLineIndentation(); $oldLineIndentation = $this->getCurrentLineIndentation();
$insideBlockScalar = $this->isBlockScalarHeader(); $blockScalarIndentations = array();
if ($this->isBlockScalarHeader()) {
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
}
if (!$this->moveToNextLine()) { if (!$this->moveToNextLine()) {
return; return;
@ -340,8 +344,8 @@ class Parser
$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem(); $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();
if (!$insideBlockScalar) { if (empty($blockScalarIndentations) && $this->isBlockScalarHeader()) {
$insideBlockScalar = $this->isBlockScalarHeader(); $blockScalarIndentations[] = $this->getCurrentLineIndentation();
} }
$previousLineIndentation = $this->getCurrentLineIndentation(); $previousLineIndentation = $this->getCurrentLineIndentation();
@ -349,8 +353,17 @@ class Parser
while ($this->moveToNextLine()) { while ($this->moveToNextLine()) {
$indent = $this->getCurrentLineIndentation(); $indent = $this->getCurrentLineIndentation();
if (!$insideBlockScalar && $indent === $previousLineIndentation) { // terminate all block scalars that are more indented than the current line
$insideBlockScalar = $this->isBlockScalarHeader(); if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && trim($this->currentLine) !== '') {
foreach ($blockScalarIndentations as $key => $blockScalarIndentation) {
if ($blockScalarIndentation >= $this->getCurrentLineIndentation()) {
unset($blockScalarIndentations[$key]);
}
}
}
if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) {
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
} }
$previousLineIndentation = $indent; $previousLineIndentation = $indent;
@ -366,7 +379,7 @@ class Parser
} }
// we ignore "comment" lines only when we are not inside a scalar block // we ignore "comment" lines only when we are not inside a scalar block
if (!$insideBlockScalar && $this->isCurrentLineComment()) { if (empty($blockScalarIndentations) && $this->isCurrentLineComment()) {
continue; continue;
} }
@ -523,7 +536,7 @@ class Parser
$previousLineIndented = false; $previousLineIndented = false;
$previousLineBlank = false; $previousLineBlank = false;
for ($i = 0; $i < count($blockLines); $i++) { for ($i = 0; $i < count($blockLines); ++$i) {
if ('' === $blockLines[$i]) { if ('' === $blockLines[$i]) {
$text .= "\n"; $text .= "\n";
$previousLineIndented = false; $previousLineIndented = false;
@ -618,7 +631,7 @@ class Parser
//checking explicitly the first char of the trim is faster than loops or strpos //checking explicitly the first char of the trim is faster than loops or strpos
$ltrimmedLine = ltrim($this->currentLine, ' '); $ltrimmedLine = ltrim($this->currentLine, ' ');
return $ltrimmedLine[0] === '#'; return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#';
} }
/** /**

View File

@ -737,7 +737,9 @@ EOF;
public function getCommentLikeStringInScalarBlockData() public function getCommentLikeStringInScalarBlockData()
{ {
$yaml1 = <<<'EOT' $tests = array();
$yaml = <<<'EOT'
pages: pages:
- -
title: some title title: some title
@ -752,7 +754,7 @@ pages:
footer # comment3 footer # comment3
EOT; EOT;
$expected1 = array( $expected = array(
'pages' => array( 'pages' => array(
array( array(
'title' => 'some title', 'title' => 'some title',
@ -771,8 +773,9 @@ EOT
), ),
), ),
); );
$tests[] = array($yaml, $expected);
$yaml2 = <<<'EOT' $yaml = <<<'EOT'
test: | test: |
foo foo
# bar # bar
@ -787,7 +790,7 @@ collection:
# bar # bar
baz baz
EOT; EOT;
$expected2 = array( $expected = array(
'test' => <<<'EOT' 'test' => <<<'EOT'
foo foo
# bar # bar
@ -814,11 +817,47 @@ EOT
), ),
), ),
); );
$tests[] = array($yaml, $expected);
return array( $yaml = <<<EOT
array($yaml1, $expected1), foo:
array($yaml2, $expected2), bar:
scalar-block: >
line1
line2>
baz:
# comment
foobar: ~
EOT;
$expected = array(
'foo' => array(
'bar' => array(
'scalar-block' => 'line1 line2>',
),
'baz' => array(
'foobar' => null,
),
),
); );
$tests[] = array($yaml, $expected);
$yaml = <<<'EOT'
a:
b: hello
# c: |
# first row
# second row
d: hello
EOT;
$expected = array(
'a' => array(
'b' => 'hello',
'd' => 'hello',
),
);
$tests[] = array($yaml, $expected);
return $tests;
} }
public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks() public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks()