[Yaml] improve deprecation message and changelog

This commit is contained in:
Christian Flothmann 2016-08-27 11:58:27 +02:00
parent df8cf70673
commit a7128f8c96
6 changed files with 27 additions and 21 deletions

View File

@ -74,8 +74,8 @@ Validator
Yaml Yaml
---- ----
* Support for silently ignoring duplicate keys in YAML has been deprecated and * Support for silently ignoring duplicate mapping keys in YAML has been
will lead to a `ParseException` in Symfony 4.0. deprecated and will lead to a `ParseException` in Symfony 4.0.
* Mappings with a colon that is not followed by a space are deprecated and * Mappings with a colon that is not followed by a space are deprecated and
will lead to a `ParseException` in Symfony 4.0. will lead to a `ParseException` in Symfony 4.0.

View File

@ -233,8 +233,7 @@ Yaml
* The `!!php/object` tag to indicate dumped PHP objects was removed in favor of * The `!!php/object` tag to indicate dumped PHP objects was removed in favor of
the `!php/object` tag. the `!php/object` tag.
* Duplicate keys in YAML leads to a `ParseException`. * Duplicate mapping keys lead to a `ParseException`.
Validator Validator
--------- ---------

View File

@ -13,8 +13,8 @@ CHANGELOG
Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT); Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT);
``` ```
* Support for silently ignoring duplicate keys in YAML has been deprecated and * Support for silently ignoring duplicate mapping keys in YAML has been
will lead to a `ParseException` in Symfony 4.0. deprecated and will lead to a `ParseException` in Symfony 4.0.
3.1.0 3.1.0
----- -----

View File

@ -25,6 +25,8 @@ class Inline
{ {
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')'; const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
public static $parsedLineNumber;
private static $exceptionOnInvalidType = false; private static $exceptionOnInvalidType = false;
private static $objectSupport = false; private static $objectSupport = false;
private static $objectForMap = false; private static $objectForMap = false;
@ -476,7 +478,7 @@ class Inline
if (!isset($output[$key])) { if (!isset($output[$key])) {
$output[$key] = $value; $output[$key] = $value;
} else { } else {
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED); @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED);
} }
$done = true; $done = true;
break; break;
@ -489,7 +491,7 @@ class Inline
if (!isset($output[$key])) { if (!isset($output[$key])) {
$output[$key] = $value; $output[$key] = $value;
} else { } else {
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED); @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED);
} }
$done = true; $done = true;
break; break;
@ -504,7 +506,7 @@ class Inline
if (!isset($output[$key])) { if (!isset($output[$key])) {
$output[$key] = $value; $output[$key] = $value;
} else { } else {
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED); @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED);
} }
$done = true; $done = true;
--$i; --$i;

View File

@ -156,6 +156,7 @@ class Parser
// force correct settings // force correct settings
Inline::parse(null, $flags, $this->refs); Inline::parse(null, $flags, $this->refs);
try { try {
Inline::$parsedLineNumber = $this->getRealCurrentLineNb();
$key = Inline::parseScalar($values['key']); $key = Inline::parseScalar($values['key']);
} catch (ParseException $e) { } catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1); $e->setParsedLine($this->getRealCurrentLineNb() + 1);
@ -242,16 +243,18 @@ class Parser
if ($allowOverwrite || !isset($data[$key])) { if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = null; $data[$key] = null;
} else { } else {
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED); @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED);
} }
} else { } else {
// remember the parsed line number here in case we need it to provide some contexts in error messages below
$realCurrentLineNbKey = $this->getRealCurrentLineNb();
$value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags); $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags);
// Spec: Keys MUST be unique; first one wins. // Spec: Keys MUST be unique; first one wins.
// But overwriting is allowed when a merge node is used in current block. // But overwriting is allowed when a merge node is used in current block.
if ($allowOverwrite || !isset($data[$key])) { if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = $value; $data[$key] = $value;
} else { } else {
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED); @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, $realCurrentLineNbKey + 1), E_USER_DEPRECATED);
} }
} }
} else { } else {
@ -261,7 +264,7 @@ class Parser
if ($allowOverwrite || !isset($data[$key])) { if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = $value; $data[$key] = $value;
} else { } else {
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED); @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED);
} }
} }
if ($isRef) { if ($isRef) {
@ -276,6 +279,7 @@ class Parser
// 1-liner optionally followed by newline(s) // 1-liner optionally followed by newline(s)
if (is_string($value) && $this->lines[0] === trim($value)) { if (is_string($value) && $this->lines[0] === trim($value)) {
try { try {
Inline::$parsedLineNumber = $this->getRealCurrentLineNb();
$value = Inline::parse($this->lines[0], $flags, $this->refs); $value = Inline::parse($this->lines[0], $flags, $this->refs);
} catch (ParseException $e) { } catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1); $e->setParsedLine($this->getRealCurrentLineNb() + 1);
@ -578,6 +582,7 @@ class Parser
} }
try { try {
Inline::$parsedLineNumber = $this->getRealCurrentLineNb();
$parsedValue = Inline::parse($value, $flags, $this->refs); $parsedValue = Inline::parse($value, $flags, $this->refs);
if ('mapping' === $context && is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) { if ('mapping' === $context && is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) {

View File

@ -813,9 +813,9 @@ EOD;
* @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered * @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered
* throws \Symfony\Component\Yaml\Exception\ParseException in 4.0 * throws \Symfony\Component\Yaml\Exception\ParseException in 4.0
*/ */
public function testParseExceptionOnDuplicate($input, $duplicate_key) public function testParseExceptionOnDuplicate($input, $duplicateKey, $lineNumber)
{ {
ErrorAssert::assertDeprecationsAreTriggered(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $duplicate_key), function () use ($input) { ErrorAssert::assertDeprecationsAreTriggered(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $duplicateKey, $lineNumber), function () use ($input) {
Yaml::parse($input); Yaml::parse($input);
}); });
} }
@ -827,25 +827,25 @@ EOD;
$yaml = <<<EOD $yaml = <<<EOD
parent: { child: first, child: duplicate } parent: { child: first, child: duplicate }
EOD; EOD;
$tests[] = array($yaml, 'child'); $tests[] = array($yaml, 'child', 1);
$yaml = <<<EOD $yaml = <<<EOD
parent: parent:
child: first, child: first,
child: duplicate child: duplicate
EOD; EOD;
$tests[] = array($yaml, 'child'); $tests[] = array($yaml, 'child', 3);
$yaml = <<<EOD $yaml = <<<EOD
parent: { child: foo } parent: { child: foo }
parent: { child: bar } parent: { child: bar }
EOD; EOD;
$tests[] = array($yaml, 'parent'); $tests[] = array($yaml, 'parent', 2);
$yaml = <<<EOD $yaml = <<<EOD
parent: { child_mapping: { value: bar}, child_mapping: { value: bar} } parent: { child_mapping: { value: bar}, child_mapping: { value: bar} }
EOD; EOD;
$tests[] = array($yaml, 'child_mapping'); $tests[] = array($yaml, 'child_mapping', 1);
$yaml = <<<EOD $yaml = <<<EOD
parent: parent:
@ -854,12 +854,12 @@ parent:
child_mapping: child_mapping:
value: bar value: bar
EOD; EOD;
$tests[] = array($yaml, 'child_mapping'); $tests[] = array($yaml, 'child_mapping', 4);
$yaml = <<<EOD $yaml = <<<EOD
parent: { child_sequence: ['key1', 'key2', 'key3'], child_sequence: ['key1', 'key2', 'key3'] } parent: { child_sequence: ['key1', 'key2', 'key3'], child_sequence: ['key1', 'key2', 'key3'] }
EOD; EOD;
$tests[] = array($yaml, 'child_sequence'); $tests[] = array($yaml, 'child_sequence', 1);
$yaml = <<<EOD $yaml = <<<EOD
parent: parent:
@ -872,7 +872,7 @@ parent:
- key2 - key2
- key3 - key3
EOD; EOD;
$tests[] = array($yaml, 'child_sequence'); $tests[] = array($yaml, 'child_sequence', 6);
return $tests; return $tests;
} }