Skip to content

Commit 8c157a6

Browse files
Merge branch '2.7' into 2.8
* 2.7: [HttpFoundation] Use UPSERT for sessions stored in PgSql >= 9.5 [Console] fixed PHPDoc [travis] HHVM 3.12 LTS Fix feature detection for IE [Form] Fixed collapsed choice attributes [Console] added explanation of messages usage in a progress bar force enabling the external XML entity loaders [Yaml] properly count skipped comment lines Conflicts: src/Symfony/Component/Translation/Loader/XliffFileLoader.php
2 parents d847282 + f3c0ae4 commit 8c157a6

File tree

2 files changed

+66
-60
lines changed

2 files changed

+66
-60
lines changed

Parser.php

Lines changed: 47 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,21 @@ class Parser
3030
private $currentLineNb = -1;
3131
private $currentLine = '';
3232
private $refs = array();
33+
private $skippedLineNumbers = array();
34+
private $locallySkippedLineNumbers = array();
3335

3436
/**
3537
* Constructor.
3638
*
3739
* @param int $offset The offset of YAML document (used for line numbers in error messages)
3840
* @param int|null $totalNumberOfLines The overall number of lines being parsed
41+
* @param int[] $skippedLineNumbers Number of comment lines that have been skipped by the parser
3942
*/
40-
public function __construct($offset = 0, $totalNumberOfLines = null)
43+
public function __construct($offset = 0, $totalNumberOfLines = null, array $skippedLineNumbers = array())
4144
{
4245
$this->offset = $offset;
4346
$this->totalNumberOfLines = $totalNumberOfLines;
47+
$this->skippedLineNumbers = $skippedLineNumbers;
4448
}
4549

4650
/**
@@ -101,25 +105,18 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
101105

102106
// array
103107
if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
104-
$c = $this->getRealCurrentLineNb() + 1;
105-
$parser = new self($c, $this->totalNumberOfLines);
106-
$parser->refs = &$this->refs;
107-
$data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap);
108+
$data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap);
108109
} else {
109110
if (isset($values['leadspaces'])
110111
&& preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
111112
) {
112113
// this is a compact notation element, add to next block and parse
113-
$c = $this->getRealCurrentLineNb();
114-
$parser = new self($c, $this->totalNumberOfLines);
115-
$parser->refs = &$this->refs;
116-
117114
$block = $values['value'];
118115
if ($this->isNextLineIndented()) {
119116
$block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + strlen($values['leadspaces']) + 1);
120117
}
121118

122-
$data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
119+
$data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
123120
} else {
124121
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
125122
}
@@ -175,10 +172,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
175172
} else {
176173
$value = $this->getNextEmbedBlock();
177174
}
178-
$c = $this->getRealCurrentLineNb() + 1;
179-
$parser = new self($c, $this->totalNumberOfLines);
180-
$parser->refs = &$this->refs;
181-
$parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
175+
$parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
182176

183177
if (!is_array($parsed)) {
184178
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
@@ -226,10 +220,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
226220
$data[$key] = null;
227221
}
228222
} else {
229-
$c = $this->getRealCurrentLineNb() + 1;
230-
$parser = new self($c, $this->totalNumberOfLines);
231-
$parser->refs = &$this->refs;
232-
$value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
223+
$value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
233224
// Spec: Keys MUST be unique; first one wins.
234225
// But overwriting is allowed when a merge node is used in current block.
235226
if ($allowOverwrite || !isset($data[$key])) {
@@ -323,14 +314,42 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
323314
return empty($data) ? null : $data;
324315
}
325316

317+
private function parseBlock($offset, $yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap)
318+
{
319+
$skippedLineNumbers = $this->skippedLineNumbers;
320+
321+
foreach ($this->locallySkippedLineNumbers as $lineNumber) {
322+
if ($lineNumber < $offset) {
323+
continue;
324+
}
325+
326+
$skippedLineNumbers[] = $lineNumber;
327+
}
328+
329+
$parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers);
330+
$parser->refs = &$this->refs;
331+
332+
return $parser->parse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap);
333+
}
334+
326335
/**
327336
* Returns the current line number (takes the offset into account).
328337
*
329338
* @return int The current line number
330339
*/
331340
private function getRealCurrentLineNb()
332341
{
333-
return $this->currentLineNb + $this->offset;
342+
$realCurrentLineNumber = $this->currentLineNb + $this->offset;
343+
344+
foreach ($this->skippedLineNumbers as $skippedLineNumber) {
345+
if ($skippedLineNumber > $realCurrentLineNumber) {
346+
break;
347+
}
348+
349+
++$realCurrentLineNumber;
350+
}
351+
352+
return $realCurrentLineNumber;
334353
}
335354

336355
/**
@@ -432,7 +451,15 @@ private function getNextEmbedBlock($indentation = null, $inSequence = false)
432451
}
433452

434453
// we ignore "comment" lines only when we are not inside a scalar block
435-
if (empty($blockScalarIndentations) && $this->isCurrentLineComment() && false === $this->checkIfPreviousNonCommentLineIsCollectionItem()) {
454+
if (empty($blockScalarIndentations) && $this->isCurrentLineComment()) {
455+
// remember ignored comment lines (they are used later in nested
456+
// parser calls to determine real line numbers)
457+
//
458+
// CAUTION: beware to not populate the global property here as it
459+
// will otherwise influence the getRealCurrentLineNb() call here
460+
// for consecutive comment lines and subsequent embedded blocks
461+
$this->locallySkippedLineNumbers[] = $this->getRealCurrentLineNb();
462+
436463
continue;
437464
}
438465

@@ -802,44 +829,4 @@ private function isBlockScalarHeader()
802829
{
803830
return (bool) preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine);
804831
}
805-
806-
/**
807-
* Returns true if the current line is a collection item.
808-
*
809-
* @return bool
810-
*/
811-
private function isCurrentLineCollectionItem()
812-
{
813-
$ltrimmedLine = ltrim($this->currentLine, ' ');
814-
815-
return '' !== $ltrimmedLine && '-' === $ltrimmedLine[0];
816-
}
817-
818-
/**
819-
* Tests whether the current comment line is in a collection.
820-
*
821-
* @return bool
822-
*/
823-
private function checkIfPreviousNonCommentLineIsCollectionItem()
824-
{
825-
$isCollectionItem = false;
826-
$moves = 0;
827-
while ($this->moveToPreviousLine()) {
828-
++$moves;
829-
// If previous line is a comment, move back again.
830-
if ($this->isCurrentLineComment()) {
831-
continue;
832-
}
833-
$isCollectionItem = $this->isCurrentLineCollectionItem();
834-
break;
835-
}
836-
837-
// Move parser back to previous line.
838-
while ($moves > 0) {
839-
$this->moveToNextLine();
840-
--$moves;
841-
}
842-
843-
return $isCollectionItem;
844-
}
845832
}

Tests/ParserTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,25 @@ public function testSequenceInMappingStartedBySingleDashLine()
656656
$this->assertSame($expected, $this->parser->parse($yaml));
657657
}
658658

659+
public function testSequenceFollowedByCommentEmbeddedInMapping()
660+
{
661+
$yaml = <<<EOT
662+
a:
663+
b:
664+
- c
665+
# comment
666+
d: e
667+
EOT;
668+
$expected = array(
669+
'a' => array(
670+
'b' => array('c'),
671+
'd' => 'e',
672+
),
673+
);
674+
675+
$this->assertSame($expected, $this->parser->parse($yaml));
676+
}
677+
659678
/**
660679
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
661680
*/

0 commit comments

Comments
 (0)