Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitda7fc36

Browse files
committed
[Yaml] properly count skipped comment lines
1 parent326465d commitda7fc36

File tree

2 files changed

+66
-60
lines changed

2 files changed

+66
-60
lines changed

‎src/Symfony/Component/Yaml/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-
publicfunction__construct($offset =0,$totalNumberOfLines =null)
43+
publicfunction__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 =newself($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 =newself($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);
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 =newself($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
thrownewParseException('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 =newself($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])) {
@@ -317,14 +308,42 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
317308
returnempty($data) ?null :$data;
318309
}
319310

311+
privatefunctionparseBlock($offset,$yaml,$exceptionOnInvalidType,$objectSupport,$objectForMap)
312+
{
313+
$skippedLineNumbers =$this->skippedLineNumbers;
314+
315+
foreach ($this->locallySkippedLineNumbersas$lineNumber) {
316+
if ($lineNumber <$offset) {
317+
continue;
318+
}
319+
320+
$skippedLineNumbers[] =$lineNumber;
321+
}
322+
323+
$parser =newself($offset,$this->totalNumberOfLines,$skippedLineNumbers);
324+
$parser->refs = &$this->refs;
325+
326+
return$parser->parse($yaml,$exceptionOnInvalidType,$objectSupport,$objectForMap);
327+
}
328+
320329
/**
321330
* Returns the current line number (takes the offset into account).
322331
*
323332
* @return int The current line number
324333
*/
325334
privatefunctiongetRealCurrentLineNb()
326335
{
327-
return$this->currentLineNb +$this->offset;
336+
$realCurrentLineNumber =$this->currentLineNb +$this->offset;
337+
338+
foreach ($this->skippedLineNumbersas$skippedLineNumber) {
339+
if ($skippedLineNumber >$realCurrentLineNumber) {
340+
break;
341+
}
342+
343+
++$realCurrentLineNumber;
344+
}
345+
346+
return$realCurrentLineNumber;
328347
}
329348

330349
/**
@@ -426,7 +445,15 @@ private function getNextEmbedBlock($indentation = null, $inSequence = false)
426445
}
427446

428447
// we ignore "comment" lines only when we are not inside a scalar block
429-
if (empty($blockScalarIndentations) &&$this->isCurrentLineComment() &&false ===$this->checkIfPreviousNonCommentLineIsCollectionItem()) {
448+
if (empty($blockScalarIndentations) &&$this->isCurrentLineComment()) {
449+
// remember ignored comment lines (they are used later in nested
450+
// parser calls to determine real line numbers)
451+
//
452+
// CAUTION: beware to not populate the global property here as it
453+
// will otherwise influence the getRealCurrentLineNb() call here
454+
// for consecutive comment lines and subsequent embedded blocks
455+
$this->locallySkippedLineNumbers[] =$this->getRealCurrentLineNb();
456+
430457
continue;
431458
}
432459

@@ -786,44 +813,4 @@ private function isBlockScalarHeader()
786813
{
787814
return (bool)preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~',$this->currentLine);
788815
}
789-
790-
/**
791-
* Returns true if the current line is a collection item.
792-
*
793-
* @return bool
794-
*/
795-
privatefunctionisCurrentLineCollectionItem()
796-
{
797-
$ltrimmedLine =ltrim($this->currentLine,'');
798-
799-
return'' !==$ltrimmedLine &&'-' ===$ltrimmedLine[0];
800-
}
801-
802-
/**
803-
* Tests whether the current comment line is in a collection.
804-
*
805-
* @return bool
806-
*/
807-
privatefunctioncheckIfPreviousNonCommentLineIsCollectionItem()
808-
{
809-
$isCollectionItem =false;
810-
$moves =0;
811-
while ($this->moveToPreviousLine()) {
812-
++$moves;
813-
// If previous line is a comment, move back again.
814-
if ($this->isCurrentLineComment()) {
815-
continue;
816-
}
817-
$isCollectionItem =$this->isCurrentLineCollectionItem();
818-
break;
819-
}
820-
821-
// Move parser back to previous line.
822-
while ($moves >0) {
823-
$this->moveToNextLine();
824-
--$moves;
825-
}
826-
827-
return$isCollectionItem;
828-
}
829816
}

‎src/Symfony/Component/Yaml/Tests/ParserTest.php‎

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

610+
publicfunctiontestSequenceFollowedByCommentEmbeddedInMapping()
611+
{
612+
$yaml =<<<EOT
613+
a:
614+
b:
615+
- c
616+
# comment
617+
d: e
618+
EOT;
619+
$expected =array(
620+
'a' =>array(
621+
'b' =>array('c'),
622+
'd' =>'e',
623+
),
624+
);
625+
626+
$this->assertSame($expected,$this->parser->parse($yaml));
627+
}
628+
610629
/**
611630
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
612631
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp