From b27bceca638e179d3b13063c57a4aa3d52cae968 Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Wed, 3 Aug 2022 03:08:25 +0200 Subject: [PATCH 01/14] cs fix --- src/Symfony/Component/Yaml/Tests/DumperTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Yaml/Tests/DumperTest.php b/src/Symfony/Component/Yaml/Tests/DumperTest.php index 59a47a8130f31..4010e7bd78dda 100644 --- a/src/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/src/Symfony/Component/Yaml/Tests/DumperTest.php @@ -696,7 +696,7 @@ public function testDumpMultiLineStringAsScalarBlock() nested_inlined_multi_line_string: { inlined_multi_line: "foo\nbar\r\nempty line:\n\nbaz" } YAML -); + ); $this->assertSame($expected, $yml); $this->assertSame($data, $this->parser->parse($yml)); } From 8e618c5b200ccb0151e7622bf539fd51950ce8e4 Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 18:21:48 +0200 Subject: [PATCH 02/14] Dumper: Refactor: Use early return to drop else. --- src/Symfony/Component/Yaml/Dumper.php | 108 +++++++++++++------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 52db38c3b032b..b7ca0871dbc51 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -50,7 +50,6 @@ public function __construct(int $indentation = 4) */ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): string { - $output = ''; $prefix = $indent ? str_repeat(' ', $indent) : ''; $dumpObjectAsInlineMap = true; @@ -59,82 +58,83 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): } if ($inline <= 0 || (!\is_array($input) && !$input instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($input)) { - $output .= $prefix.Inline::dump($input, $flags); - } else { - $dumpAsMap = Inline::isHash($input); + return $prefix.Inline::dump($input, $flags); + } - foreach ($input as $key => $value) { - if ('' !== $output && "\n" !== $output[-1]) { - $output .= "\n"; - } + $dumpAsMap = Inline::isHash($input); + + $output = ''; + foreach ($input as $key => $value) { + if ('' !== $output && "\n" !== $output[-1]) { + $output .= "\n"; + } if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) { - // If the first line starts with a space character, the spec requires a blockIndicationIndicator - // http://www.yaml.org/spec/1.2/spec.html#id2793979 + // If the first line starts with a space character, the spec requires a blockIndicationIndicator + // http://www.yaml.org/spec/1.2/spec.html#id2793979 $blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : ''; - if (isset($value[-2]) && "\n" === $value[-2] && "\n" === $value[-1]) { - $blockChompingIndicator = '+'; - } elseif ("\n" === $value[-1]) { - $blockChompingIndicator = ''; - } else { - $blockChompingIndicator = '-'; - } + if (isset($value[-2]) && "\n" === $value[-2] && "\n" === $value[-1]) { + $blockChompingIndicator = '+'; + } elseif ("\n" === $value[-1]) { + $blockChompingIndicator = ''; + } else { + $blockChompingIndicator = '-'; + } - $output .= sprintf('%s%s%s |%s%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator, $blockChompingIndicator); + $output .= sprintf('%s%s%s |%s%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator, $blockChompingIndicator); - foreach (explode("\n", $value) as $row) { - if ('' === $row) { - $output .= "\n"; - } else { - $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); - } + foreach (explode("\n", $value) as $row) { + if ('' === $row) { + $output .= "\n"; + } else { + $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); } - - continue; } - if ($value instanceof TaggedValue) { - $output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag()); + continue; + } + + if ($value instanceof TaggedValue) { + $output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag()); if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) { - // If the first line starts with a space character, the spec requires a blockIndicationIndicator - // http://www.yaml.org/spec/1.2/spec.html#id2793979 + // If the first line starts with a space character, the spec requires a blockIndicationIndicator + // http://www.yaml.org/spec/1.2/spec.html#id2793979 $blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : ''; - $output .= sprintf(' |%s', $blockIndentationIndicator); - - foreach (explode("\n", $value->getValue()) as $row) { - $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); - } + $output .= sprintf(' |%s', $blockIndentationIndicator); - continue; - } - - if ($inline - 1 <= 0 || null === $value->getValue() || \is_scalar($value->getValue())) { - $output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n"; - } else { - $output .= "\n"; - $output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags); + foreach (explode("\n", $value->getValue()) as $row) { + $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); } continue; } - $dumpObjectAsInlineMap = true; - - if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { - $dumpObjectAsInlineMap = empty((array) $value); + if ($inline - 1 <= 0 || null === $value->getValue() || \is_scalar($value->getValue())) { + $output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n"; + } else { + $output .= "\n"; + $output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags); } - $willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value); + continue; + } + + $dumpObjectAsInlineMap = true; - $output .= sprintf('%s%s%s%s', - $prefix, - $dumpAsMap ? Inline::dump($key, $flags).':' : '-', - $willBeInlined ? ' ' : "\n", - $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags) - ).($willBeInlined ? "\n" : ''); + if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { + $dumpObjectAsInlineMap = empty((array) $value); } + + $willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value); + + $output .= sprintf('%s%s%s%s', + $prefix, + $dumpAsMap ? Inline::dump($key, $flags).':' : '-', + $willBeInlined ? ' ' : "\n", + $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags) + ).($willBeInlined ? "\n" : ''); } return $output; From c2283e35197f0e4d8b0a9f7c3177c2962d8e1b80 Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 18:26:24 +0200 Subject: [PATCH 03/14] Dumper: Refactor: Break long sprintf() calls to multiple lines. --- src/Symfony/Component/Yaml/Dumper.php | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index b7ca0871dbc51..b32c24d3d1b6b 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -82,13 +82,21 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): $blockChompingIndicator = '-'; } - $output .= sprintf('%s%s%s |%s%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator, $blockChompingIndicator); + $output .= sprintf('%s%s%s |%s%s', + $prefix, + $dumpAsMap ? Inline::dump($key, $flags).':' : '-', + '', + $blockIndentationIndicator, + $blockChompingIndicator); foreach (explode("\n", $value) as $row) { if ('' === $row) { $output .= "\n"; } else { - $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); + $output .= sprintf("\n%s%s%s", + $prefix, + str_repeat(' ', $this->indentation), + $row); } } @@ -96,7 +104,10 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): } if ($value instanceof TaggedValue) { - $output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag()); + $output .= sprintf('%s%s !%s', + $prefix, + $dumpAsMap ? Inline::dump($key, $flags) . ':' : '-', + $value->getTag()); if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) { // If the first line starts with a space character, the spec requires a blockIndicationIndicator @@ -105,7 +116,10 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): $output .= sprintf(' |%s', $blockIndentationIndicator); foreach (explode("\n", $value->getValue()) as $row) { - $output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row); + $output .= sprintf("\n%s%s%s", + $prefix, + str_repeat(' ', $this->indentation), + $row); } continue; From 4c8d4ca833c748ce3d02572a03d10cc67cf8129f Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 18:36:34 +0200 Subject: [PATCH 04/14] Dumper: Refactor: Use string concat instead of sprintf. --- src/Symfony/Component/Yaml/Dumper.php | 55 +++++++++++++++------------ 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index b32c24d3d1b6b..130d6cc634842 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -82,21 +82,22 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): $blockChompingIndicator = '-'; } - $output .= sprintf('%s%s%s |%s%s', - $prefix, - $dumpAsMap ? Inline::dump($key, $flags).':' : '-', - '', - $blockIndentationIndicator, - $blockChompingIndicator); + $output .= $prefix + .($dumpAsMap ? Inline::dump($key, $flags).':' : '-') + .' |' + .$blockIndentationIndicator + .$blockChompingIndicator + ; foreach (explode("\n", $value) as $row) { if ('' === $row) { $output .= "\n"; } else { - $output .= sprintf("\n%s%s%s", - $prefix, - str_repeat(' ', $this->indentation), - $row); + $output .= "\n" + .$prefix + .str_repeat(' ', $this->indentation) + .$row + ; } } @@ -104,10 +105,11 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): } if ($value instanceof TaggedValue) { - $output .= sprintf('%s%s !%s', - $prefix, - $dumpAsMap ? Inline::dump($key, $flags) . ':' : '-', - $value->getTag()); + $output .= $prefix + .($dumpAsMap ? Inline::dump($key, $flags).':' : '-') + .' !' + .$value->getTag() + ; if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) { // If the first line starts with a space character, the spec requires a blockIndicationIndicator @@ -116,10 +118,11 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): $output .= sprintf(' |%s', $blockIndentationIndicator); foreach (explode("\n", $value->getValue()) as $row) { - $output .= sprintf("\n%s%s%s", - $prefix, - str_repeat(' ', $this->indentation), - $row); + $output .= "\n" + .$prefix + .str_repeat(' ', $this->indentation) + .$row + ; } continue; @@ -143,12 +146,16 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): $willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value); - $output .= sprintf('%s%s%s%s', - $prefix, - $dumpAsMap ? Inline::dump($key, $flags).':' : '-', - $willBeInlined ? ' ' : "\n", - $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags) - ).($willBeInlined ? "\n" : ''); + $output .= $prefix + .($dumpAsMap ? Inline::dump($key, $flags).':' : '-') + .($willBeInlined ? ' ' : "\n") + .$this->dump( + $value, + $inline - 1, + $willBeInlined ? 0 : $indent + $this->indentation, + $flags) + .($willBeInlined ? "\n" : '') + ; } return $output; From 7487eea15870c51ec947ee0395f3d4e4943fe21e Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 18:42:56 +0200 Subject: [PATCH 05/14] Dumper: Refactor: Move shared concat parts to shared place in code. --- src/Symfony/Component/Yaml/Dumper.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 130d6cc634842..42588e1bca078 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -68,6 +68,8 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): if ('' !== $output && "\n" !== $output[-1]) { $output .= "\n"; } + $output .= $prefix; + $output .= $dumpAsMap ? Inline::dump($key, $flags).':' : '-'; if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) { // If the first line starts with a space character, the spec requires a blockIndicationIndicator @@ -82,9 +84,7 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): $blockChompingIndicator = '-'; } - $output .= $prefix - .($dumpAsMap ? Inline::dump($key, $flags).':' : '-') - .' |' + $output .= ' |' .$blockIndentationIndicator .$blockChompingIndicator ; @@ -105,11 +105,7 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): } if ($value instanceof TaggedValue) { - $output .= $prefix - .($dumpAsMap ? Inline::dump($key, $flags).':' : '-') - .' !' - .$value->getTag() - ; + $output .= ' !'.$value->getTag(); if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) { // If the first line starts with a space character, the spec requires a blockIndicationIndicator @@ -146,9 +142,7 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): $willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value); - $output .= $prefix - .($dumpAsMap ? Inline::dump($key, $flags).':' : '-') - .($willBeInlined ? ' ' : "\n") + $output .= ($willBeInlined ? ' ' : "\n") .$this->dump( $value, $inline - 1, From e1e9fec341944fe3a50c03b544715f589e2ca1c2 Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 18:48:58 +0200 Subject: [PATCH 06/14] Dumper: Refactor: Drop some local variables when handling multi-line literal block. --- src/Symfony/Component/Yaml/Dumper.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 42588e1bca078..546ba2375831b 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -72,23 +72,19 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): $output .= $dumpAsMap ? Inline::dump($key, $flags).':' : '-'; if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) { + $output .= ' |'; // If the first line starts with a space character, the spec requires a blockIndicationIndicator // http://www.yaml.org/spec/1.2/spec.html#id2793979 - $blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : ''; + if (' ' === substr($value, 0, 1)) { + $output .= $this->indentation; + } if (isset($value[-2]) && "\n" === $value[-2] && "\n" === $value[-1]) { - $blockChompingIndicator = '+'; - } elseif ("\n" === $value[-1]) { - $blockChompingIndicator = ''; - } else { - $blockChompingIndicator = '-'; + $output .= '+'; + } elseif ("\n" !== $value[-1]) { + $output .= '-'; } - $output .= ' |' - .$blockIndentationIndicator - .$blockChompingIndicator - ; - foreach (explode("\n", $value) as $row) { if ('' === $row) { $output .= "\n"; From dade12ad2b6612c2df15719b84adf0c939d54797 Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 18:50:22 +0200 Subject: [PATCH 07/14] Dumper: Refactor: Simplify condition in multi-line literal block. --- src/Symfony/Component/Yaml/Dumper.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 546ba2375831b..7451e4793bd42 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -86,14 +86,11 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): } foreach (explode("\n", $value) as $row) { - if ('' === $row) { - $output .= "\n"; - } else { - $output .= "\n" - .$prefix + $output .= "\n"; + if ('' !== $row) { + $output .= $prefix .str_repeat(' ', $this->indentation) - .$row - ; + .$row; } } From 85ca72f7d0734aef74815d6f4d0901e7f3ea41fe Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 18:53:47 +0200 Subject: [PATCH 08/14] Dumper: Refactor: Introduce $this->indentStr to reduce number of str_repeat() calls. --- src/Symfony/Component/Yaml/Dumper.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 7451e4793bd42..241fdefc83967 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -29,6 +29,13 @@ class Dumper */ protected $indentation; + /** + * String of spaces with length equal to $this->indentation. + * + * @var string + */ + private $indentStr; + public function __construct(int $indentation = 4) { if ($indentation < 1) { @@ -36,6 +43,7 @@ public function __construct(int $indentation = 4) } $this->indentation = $indentation; + $this->indentStr = str_repeat(' ', $indentation); } /** @@ -88,9 +96,7 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): foreach (explode("\n", $value) as $row) { $output .= "\n"; if ('' !== $row) { - $output .= $prefix - .str_repeat(' ', $this->indentation) - .$row; + $output .= $prefix.$this->indentStr.$row; } } From 2b3f8bbb3f7fba52deef426cdb2a7f1267c2b478 Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 17:41:48 +0200 Subject: [PATCH 09/14] Dumper + DumperTest: Fix and simplify TaggedValue dumping. --- src/Symfony/Component/Yaml/Dumper.php | 46 ++++++------------- .../Component/Yaml/Tests/DumperTest.php | 19 ++++---- 2 files changed, 22 insertions(+), 43 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 241fdefc83967..c7dfba6d86daa 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -79,7 +79,17 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): $output .= $prefix; $output .= $dumpAsMap ? Inline::dump($key, $flags).':' : '-'; - if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) { + $tagged = false; + if ($value instanceof TaggedValue) { + $output .= ' !'.$value->getTag(); + $value = $value->getValue(); + if ($value instanceof TaggedValue) { + throw new \InvalidArgumentException('Nested tags are not supported.'); + } + $tagged = true; + } + + if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) { $output .= ' |'; // If the first line starts with a space character, the spec requires a blockIndicationIndicator // http://www.yaml.org/spec/1.2/spec.html#id2793979 @@ -103,36 +113,6 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): continue; } - if ($value instanceof TaggedValue) { - $output .= ' !'.$value->getTag(); - - if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) { - // If the first line starts with a space character, the spec requires a blockIndicationIndicator - // http://www.yaml.org/spec/1.2/spec.html#id2793979 - $blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : ''; - $output .= sprintf(' |%s', $blockIndentationIndicator); - - foreach (explode("\n", $value->getValue()) as $row) { - $output .= "\n" - .$prefix - .str_repeat(' ', $this->indentation) - .$row - ; - } - - continue; - } - - if ($inline - 1 <= 0 || null === $value->getValue() || \is_scalar($value->getValue())) { - $output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n"; - } else { - $output .= "\n"; - $output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags); - } - - continue; - } - $dumpObjectAsInlineMap = true; if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { @@ -145,7 +125,9 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): .$this->dump( $value, $inline - 1, - $willBeInlined ? 0 : $indent + $this->indentation, + $willBeInlined + ? 0 + : $indent + ($tagged && !$dumpAsMap ? 2 : $this->indentation), $flags) .($willBeInlined ? "\n" : '') ; diff --git a/src/Symfony/Component/Yaml/Tests/DumperTest.php b/src/Symfony/Component/Yaml/Tests/DumperTest.php index 4010e7bd78dda..b1a6f7bdbcf5d 100644 --- a/src/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/src/Symfony/Component/Yaml/Tests/DumperTest.php @@ -588,7 +588,7 @@ public function testDumpingMultiLineStringAsScalarBlockTaggedValue() $data = [ 'foo' => new TaggedValue('bar', "foo\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz"), ]; - $expected = "foo: !bar |\n". + $expected = "foo: !bar |-\n". " foo\n". " line with trailing spaces:\n". " \n". @@ -596,7 +596,7 @@ public function testDumpingMultiLineStringAsScalarBlockTaggedValue() " integer like line:\n". " 123456789\n". " empty line:\n". - " \n". + "\n". ' baz'; $this->assertSame($expected, $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); @@ -608,12 +608,12 @@ public function testDumpingTaggedMultiLineInList() $data = [ new TaggedValue('bar', "a\nb"), ]; - $expected = "- !bar |\n a\n b"; + $expected = "- !bar |-\n a\n b"; $this->assertSame($expected, $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); // @todo Fix the parser, eliminate these exceptions. $this->expectException(ParseException::class); - $this->expectExceptionMessage('Unable to parse at line 3 (near "!bar |").'); + $this->expectExceptionMessage('Unable to parse at line 3 (near "!bar |-").'); $this->parser->parse($expected, Yaml::PARSE_CUSTOM_TAGS); } @@ -623,14 +623,11 @@ public function testDumpingTaggedMultiLineTrailingNewlinesInMap() $data = [ 'foo' => new TaggedValue('bar', "a\nb\n\n\n"), ]; - $expected = "foo: !bar |\n a\n b\n \n \n "; + $expected = "foo: !bar |+\n a\n b\n\n\n"; $this->assertSame($expected, $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); - // @todo Fix the parser, the result should be identical to $data. $this->assertSameData( - [ - 'foo' => new TaggedValue('bar', "a\nb\n"), - ], + $data, $this->parser->parse($expected, Yaml::PARSE_CUSTOM_TAGS)); } @@ -639,12 +636,12 @@ public function testDumpingTaggedMultiLineTrailingNewlinesInList() $data = [ new TaggedValue('bar', "a\nb\n\n\n"), ]; - $expected = "- !bar |\n a\n b\n \n \n "; + $expected = "- !bar |+\n a\n b\n\n\n"; $this->assertSame($expected, $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); // @todo Fix the parser, eliminate these exceptions. $this->expectException(ParseException::class); - $this->expectExceptionMessage('Unable to parse at line 6 (near "!bar |").'); + $this->expectExceptionMessage('Unable to parse at line 6 (near "!bar |+").'); $this->parser->parse($expected, Yaml::PARSE_CUSTOM_TAGS); } From fb917c2b3c428ca66a14aa32890e3122561f39bc Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 19:59:56 +0200 Subject: [PATCH 10/14] Dumper: Refactor: Move inline check to a separate method. --- src/Symfony/Component/Yaml/Dumper.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index c7dfba6d86daa..0658aa989269a 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -59,13 +59,8 @@ public function __construct(int $indentation = 4) public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): string { $prefix = $indent ? str_repeat(' ', $indent) : ''; - $dumpObjectAsInlineMap = true; - - if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($input instanceof \ArrayObject || $input instanceof \stdClass)) { - $dumpObjectAsInlineMap = empty((array) $input); - } - if ($inline <= 0 || (!\is_array($input) && !$input instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($input)) { + if ($this->shouldDumpAsInline($inline, $input, $flags)) { return $prefix.Inline::dump($input, $flags); } @@ -113,13 +108,7 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): continue; } - $dumpObjectAsInlineMap = true; - - if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { - $dumpObjectAsInlineMap = empty((array) $value); - } - - $willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value); + $willBeInlined = $this->shouldDumpAsInline($inline - 1, $value, $flags); $output .= ($willBeInlined ? ' ' : "\n") .$this->dump( @@ -135,4 +124,15 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): return $output; } + + private function shouldDumpAsInline(int $inline, $value, int $flags): bool + { + $dumpObjectAsInlineMap = true; + + if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { + $dumpObjectAsInlineMap = empty((array) $value); + } + + return $inline <= 0 || (!\is_array($value) && !$value instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($value); + } } From 5c5674cc45881d3e04f452cbd8e0fe0038ee48a5 Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 20:07:19 +0200 Subject: [PATCH 11/14] Dumper: Refactor inline check, part I. --- src/Symfony/Component/Yaml/Dumper.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 0658aa989269a..928085d31eb82 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -127,12 +127,16 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): private function shouldDumpAsInline(int $inline, $value, int $flags): bool { + if ($inline <= 0 || empty($value)) { + return true; + } + $dumpObjectAsInlineMap = true; if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { $dumpObjectAsInlineMap = empty((array) $value); } - return $inline <= 0 || (!\is_array($value) && !$value instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($value); + return !\is_array($value) && !$value instanceof TaggedValue && $dumpObjectAsInlineMap; } } From ff2dab99824292866f74bd747fb7467c846c2b2d Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 20:08:32 +0200 Subject: [PATCH 12/14] Dumper: Refactor inline check, part II. --- src/Symfony/Component/Yaml/Dumper.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 928085d31eb82..83fbddce1f337 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -131,12 +131,16 @@ private function shouldDumpAsInline(int $inline, $value, int $flags): bool return true; } + if (\is_array($value) || $value instanceof TaggedValue) { + return false; + } + $dumpObjectAsInlineMap = true; if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { $dumpObjectAsInlineMap = empty((array) $value); } - return !\is_array($value) && !$value instanceof TaggedValue && $dumpObjectAsInlineMap; + return $dumpObjectAsInlineMap; } } From 02e26f9e42f33c670154cbafe6a85e36ed98a183 Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 20:10:55 +0200 Subject: [PATCH 13/14] Dumper: Refactor inline check, part III. --- src/Symfony/Component/Yaml/Dumper.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 83fbddce1f337..6834bc566ccfd 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -135,12 +135,13 @@ private function shouldDumpAsInline(int $inline, $value, int $flags): bool return false; } - $dumpObjectAsInlineMap = true; - - if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { - $dumpObjectAsInlineMap = empty((array) $value); + if (Yaml::DUMP_OBJECT_AS_MAP & $flags + && ($value instanceof \ArrayObject || $value instanceof \stdClass) + && !empty((array) $value) + ) { + return false; } - return $dumpObjectAsInlineMap; + return true; } } From 3fe757026d43aff500e49d9a36e8c537ba830f95 Mon Sep 17 00:00:00 2001 From: Andreas Hennings Date: Tue, 21 Jun 2022 20:37:04 +0200 Subject: [PATCH 14/14] Dumper + DumperTest: Fix TaggedValue in top level. --- src/Symfony/Component/Yaml/Dumper.php | 20 +++++++++++++++++-- .../Component/Yaml/Tests/DumperTest.php | 14 ++++++------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 6834bc566ccfd..67102ed62c03b 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -60,8 +60,20 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): { $prefix = $indent ? str_repeat(' ', $indent) : ''; + $tag = null; + if ($input instanceof TaggedValue) { + $tag = $input->getTag(); + $input = $input->getValue(); + if ($input instanceof TaggedValue) { + throw new \InvalidArgumentException('Nested tags are not supported.'); + } + } + if ($this->shouldDumpAsInline($inline, $input, $flags)) { - return $prefix.Inline::dump($input, $flags); + return $prefix + .(null !== $tag ? '!'.$tag.' ' : '') + .Inline::dump($input, $flags) + ; } $dumpAsMap = Inline::isHash($input); @@ -122,6 +134,10 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): ; } + if (null !== $tag) { + $output = '!'.$tag."\n".$output; + } + return $output; } @@ -131,7 +147,7 @@ private function shouldDumpAsInline(int $inline, $value, int $flags): bool return true; } - if (\is_array($value) || $value instanceof TaggedValue) { + if (\is_array($value)) { return false; } diff --git a/src/Symfony/Component/Yaml/Tests/DumperTest.php b/src/Symfony/Component/Yaml/Tests/DumperTest.php index b1a6f7bdbcf5d..164b01c7e74b9 100644 --- a/src/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/src/Symfony/Component/Yaml/Tests/DumperTest.php @@ -443,20 +443,20 @@ public function testDumpingTaggedValueTopLevelAssocInline() public function testDumpingTaggedValueTopLevelAssoc() { $data = new TaggedValue('user', ['name' => 'jane']); + $expected = <<<'YAML' +!user +name: jane - // @todo Fix the dumper, the output should not be ''. - $expected = ''; - $yaml = $this->dumper->dump($data, 2); - $this->assertSame($expected, $yaml); +YAML; + $this->assertSame($expected, $this->dumper->dump($data, 2)); } public function testDumpingTaggedValueTopLevelMultiLine() { $data = new TaggedValue('text', "a\nb\n"); - - // @todo Fix the dumper, the output should not be ''. - $expected = ''; + $expected = '!text "a\\nb\\n"'; $this->assertSame($expected, $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); + $this->assertEquals($data, $this->parser->parse($expected, Yaml::PARSE_CUSTOM_TAGS)); } public function testDumpingTaggedValueSpecialCharsInTag()