Skip to content

Commit

Permalink
substitute aliases in inline mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
xabbuh committed Nov 20, 2017
1 parent 675a3fe commit dd26c80
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 60 deletions.
22 changes: 19 additions & 3 deletions src/Symfony/Component/Yaml/Inline.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ private static function parseMapping($mapping, &$i = 0, $references = array())
$output = array();
$len = strlen($mapping);
++$i;
$allowOverwrite = false;

// {foo: bar, bar:foo, ...}
while ($i < $len) {
Expand All @@ -384,6 +385,10 @@ private static function parseMapping($mapping, &$i = 0, $references = array())
// key
$key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);

if ('<<' === $key) {
$allowOverwrite = true;
}

// value
$done = false;

Expand All @@ -395,7 +400,12 @@ private static function parseMapping($mapping, &$i = 0, $references = array())
// Spec: Keys MUST be unique; first one wins.
// Parser cannot abort this mapping earlier, since lines
// are processed sequentially.
if (!isset($output[$key])) {
// But overwriting is allowed when a merge node is used in current block.
if ('<<' === $key) {
foreach ($value as $parsedValue) {
$output += $parsedValue;
}
} elseif ($allowOverwrite || !isset($output[$key])) {
$output[$key] = $value;
}
$done = true;
Expand All @@ -406,7 +416,10 @@ private static function parseMapping($mapping, &$i = 0, $references = array())
// Spec: Keys MUST be unique; first one wins.
// Parser cannot abort this mapping earlier, since lines
// are processed sequentially.
if (!isset($output[$key])) {
// But overwriting is allowed when a merge node is used in current block.
if ('<<' === $key) {
$output += $value;
} elseif ($allowOverwrite || !isset($output[$key])) {
$output[$key] = $value;
}
$done = true;
Expand All @@ -419,7 +432,10 @@ private static function parseMapping($mapping, &$i = 0, $references = array())
// Spec: Keys MUST be unique; first one wins.
// Parser cannot abort this mapping earlier, since lines
// are processed sequentially.
if (!isset($output[$key])) {
// But overwriting is allowed when a merge node is used in current block.
if ('<<' === $key) {
$output += $value;
} elseif ($allowOverwrite || !isset($output[$key])) {
$output[$key] = $value;
}
$done = true;
Expand Down
55 changes: 1 addition & 54 deletions src/Symfony/Component/Yaml/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -491,59 +491,6 @@ private function moveToPreviousLine()
return true;
}

/**
* Substitute from alias where is used a <<
*
* @param mixed $values Parsed YAML in which aliases are not substituted
*
* @return mixed YAML with substituted aliases
*
* @throws Exception\ParseException When indentation problem are detected
*/
private function substituteAliases($values)
{
if (is_array($values)) {
$keys = array();
foreach ($values as $key => $value) {
if ($key ==='<<' && preg_grep('/^\*.+/', (array) $value) === array_values((array) $value)) {
$values[$key] = array();
foreach ((array) $value as $ref) {
$refName = substr($ref, 1);
if (!array_key_exists($refName, $this->refs)) {
throw new ParseException(
sprintf('Reference "%s" does not exist.', $refName),
$this->getRealCurrentLineNb() + 1,
$this->currentLine
);
}

$keys = array_merge(
$keys,
array_diff(array_keys($this->refs[$refName]), $keys)
);
$values[$key] = array_replace($this->refs[$refName], $values[$key]);
}
} elseif (!isset($result[$key]) || is_array($result[$key])) {
$keys[] = $key;
$values[$key] = $this->substituteAliases($value);
}
}

if (isset($values['<<'])) {
$values = array_replace($values['<<'], $values);
unset($values['<<']);
uksort(
$values,
function ($a, $b) use ($keys) {
return array_search($a, $keys, true) - array_search($b, $keys, true);
}
);
}
}

return $values;
}

/**
* Parses a YAML value.
*
Expand Down Expand Up @@ -579,7 +526,7 @@ private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $ob
}

try {
return $this->substituteAliases(Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs));
return Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);
Expand Down
6 changes: 3 additions & 3 deletions src/Symfony/Component/Yaml/Tests/Fixtures/sfMergeKey.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ php: |
array(
'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull'),
'bar' => array('a' => 'before', 'd' => 'other', 'e' => null, 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
'bar_inline' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
'bar_inline' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'e' => 'notnull', 'x' => 'Oren'),
'duplicate' => array('foo' => 'bar'),
'foo2' => array('a' => 'Ballmer'),
'ding' => array('fi', 'fei', 'fo', 'fam'),
'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'),
'head' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
'taz' => array('a' => 'Steve', 'w' => array('p' => 1234)),
'nested' => array('a' => 'Steve', 'w' => array('p' => 12345), 'd' => 'Doug', 'z' => array('p' => 12345)),
'head_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam'),
'recursive_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => array('a' => 'Ballmer'), 'fi', 'fei', 'fo', 'fam')
'head_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
'recursive_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => array('a' => 'Ballmer'), 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
)

0 comments on commit dd26c80

Please sign in to comment.