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

View File

@ -737,7 +737,9 @@ EOF;
public function getCommentLikeStringInScalarBlockData()
{
$yaml1 = <<<'EOT'
$tests = array();
$yaml = <<<'EOT'
pages:
-
title: some title
@ -752,7 +754,7 @@ pages:
footer # comment3
EOT;
$expected1 = array(
$expected = array(
'pages' => array(
array(
'title' => 'some title',
@ -771,8 +773,9 @@ EOT
),
),
);
$tests[] = array($yaml, $expected);
$yaml2 = <<<'EOT'
$yaml = <<<'EOT'
test: |
foo
# bar
@ -787,7 +790,7 @@ collection:
# bar
baz
EOT;
$expected2 = array(
$expected = array(
'test' => <<<'EOT'
foo
# bar
@ -814,11 +817,47 @@ EOT
),
),
);
$tests[] = array($yaml, $expected);
return array(
array($yaml1, $expected1),
array($yaml2, $expected2),
$yaml = <<<EOT
foo:
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()