mirror of https://github.com/rectorphp/rector.git
Updated Rector to commit df8d2b78edd46542e6426fec606c3ea98d712532
df8d2b78ed
Copy subtype phpdoc on ClassPropertyAssignToConstructorPromotionRector (#8438) (#5603)
This commit is contained in:
parent
7f9bb2ae80
commit
69e22c50fb
|
@ -0,0 +1,94 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../symfony/yaml/Resources/bin/yaml-lint)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
namespace RectorPrefix202402\Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..' . '/autoload.php';
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
if (!\class_exists('RectorPrefix202402\\Composer\\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = \substr($path, 17);
|
||||
$this->realpath = \realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = \fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = \fread($this->handle, $count);
|
||||
if ($this->position === 0) {
|
||||
$data = \preg_replace('{^#!.*\\r?\\n}', '', $data);
|
||||
}
|
||||
$this->position += \strlen($data);
|
||||
return $data;
|
||||
}
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
public function stream_close()
|
||||
{
|
||||
\fclose($this->handle);
|
||||
}
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? \flock($this->handle, $operation) : \true;
|
||||
}
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === \fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = \ftell($this->handle);
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
public function stream_eof()
|
||||
{
|
||||
return \feof($this->handle);
|
||||
}
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return \true;
|
||||
}
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = \substr($path, 17);
|
||||
if (\file_exists($path)) {
|
||||
return \stat($path);
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (\function_exists('stream_get_wrappers') && \in_array('phpvfscomposer', \stream_get_wrappers(), \true) || \function_exists('stream_wrapper_register') && \stream_wrapper_register('phpvfscomposer', 'RectorPrefix202402\\Composer\\BinProxyWrapper')) {
|
||||
return include "phpvfscomposer://" . __DIR__ . '/..' . '/symfony/yaml/Resources/bin/yaml-lint';
|
||||
}
|
||||
}
|
||||
return include __DIR__ . '/..' . '/symfony/yaml/Resources/bin/yaml-lint';
|
|
@ -923,6 +923,18 @@ return array(
|
|||
'RectorPrefix202402\\Symfony\\Component\\Process\\Pipes\\WindowsPipes' => $vendorDir . '/symfony/process/Pipes/WindowsPipes.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Process\\Process' => $vendorDir . '/symfony/process/Process.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Process\\ProcessUtils' => $vendorDir . '/symfony/process/ProcessUtils.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Command\\LintCommand' => $vendorDir . '/symfony/yaml/Command/LintCommand.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Dumper' => $vendorDir . '/symfony/yaml/Dumper.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Escaper' => $vendorDir . '/symfony/yaml/Escaper.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Exception\\DumpException' => $vendorDir . '/symfony/yaml/Exception/DumpException.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/yaml/Exception/ExceptionInterface.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Exception\\ParseException' => $vendorDir . '/symfony/yaml/Exception/ParseException.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Exception\\RuntimeException' => $vendorDir . '/symfony/yaml/Exception/RuntimeException.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Inline' => $vendorDir . '/symfony/yaml/Inline.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Parser' => $vendorDir . '/symfony/yaml/Parser.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Tag\\TaggedValue' => $vendorDir . '/symfony/yaml/Tag/TaggedValue.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Unescaper' => $vendorDir . '/symfony/yaml/Unescaper.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Yaml' => $vendorDir . '/symfony/yaml/Yaml.php',
|
||||
'RectorPrefix202402\\Symfony\\Contracts\\Service\\Attribute\\Required' => $vendorDir . '/symfony/service-contracts/Attribute/Required.php',
|
||||
'RectorPrefix202402\\Symfony\\Contracts\\Service\\Attribute\\SubscribedService' => $vendorDir . '/symfony/service-contracts/Attribute/SubscribedService.php',
|
||||
'RectorPrefix202402\\Symfony\\Contracts\\Service\\ResetInterface' => $vendorDir . '/symfony/service-contracts/ResetInterface.php',
|
||||
|
|
|
@ -7,7 +7,7 @@ $baseDir = dirname($vendorDir);
|
|||
|
||||
return array(
|
||||
'ad155f8f1cf0d418fe49e248db8c661b' => $vendorDir . '/react/promise/src/functions_include.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'30bca7fff093e8069bed7c55247e2bf8' => $baseDir . '/src/functions/node_helper.php',
|
||||
);
|
||||
|
|
|
@ -17,6 +17,7 @@ return array(
|
|||
'RectorPrefix202402\\Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
|
||||
'RectorPrefix202402\\Symplify\\EasyParallel\\' => array($vendorDir . '/symplify/easy-parallel/src'),
|
||||
'RectorPrefix202402\\Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'),
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
|
||||
'RectorPrefix202402\\Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
|
||||
'RectorPrefix202402\\Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
|
||||
'RectorPrefix202402\\Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
|
||||
|
|
|
@ -8,8 +8,8 @@ class ComposerStaticInit2d887a2f87c676eb32b3e04612865e54
|
|||
{
|
||||
public static $files = array (
|
||||
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'30bca7fff093e8069bed7c55247e2bf8' => __DIR__ . '/../..' . '/src/functions/node_helper.php',
|
||||
);
|
||||
|
||||
|
@ -30,6 +30,7 @@ class ComposerStaticInit2d887a2f87c676eb32b3e04612865e54
|
|||
'RectorPrefix202402\\Webmozart\\Assert\\' => 36,
|
||||
'RectorPrefix202402\\Symplify\\EasyParallel\\' => 41,
|
||||
'RectorPrefix202402\\Symfony\\Contracts\\Service\\' => 45,
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\' => 42,
|
||||
'RectorPrefix202402\\Symfony\\Component\\Process\\' => 45,
|
||||
'RectorPrefix202402\\Symfony\\Component\\Finder\\' => 44,
|
||||
'RectorPrefix202402\\Symfony\\Component\\Filesystem\\' => 48,
|
||||
|
@ -113,6 +114,10 @@ class ComposerStaticInit2d887a2f87c676eb32b3e04612865e54
|
|||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/service-contracts',
|
||||
),
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/yaml',
|
||||
),
|
||||
'RectorPrefix202402\\Symfony\\Component\\Process\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/process',
|
||||
|
@ -1137,6 +1142,18 @@ class ComposerStaticInit2d887a2f87c676eb32b3e04612865e54
|
|||
'RectorPrefix202402\\Symfony\\Component\\Process\\Pipes\\WindowsPipes' => __DIR__ . '/..' . '/symfony/process/Pipes/WindowsPipes.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Process\\Process' => __DIR__ . '/..' . '/symfony/process/Process.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Process\\ProcessUtils' => __DIR__ . '/..' . '/symfony/process/ProcessUtils.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Command\\LintCommand' => __DIR__ . '/..' . '/symfony/yaml/Command/LintCommand.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Dumper' => __DIR__ . '/..' . '/symfony/yaml/Dumper.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Escaper' => __DIR__ . '/..' . '/symfony/yaml/Escaper.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Exception\\DumpException' => __DIR__ . '/..' . '/symfony/yaml/Exception/DumpException.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/yaml/Exception/ExceptionInterface.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Exception\\ParseException' => __DIR__ . '/..' . '/symfony/yaml/Exception/ParseException.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/yaml/Exception/RuntimeException.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Inline' => __DIR__ . '/..' . '/symfony/yaml/Inline.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Parser' => __DIR__ . '/..' . '/symfony/yaml/Parser.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Tag\\TaggedValue' => __DIR__ . '/..' . '/symfony/yaml/Tag/TaggedValue.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Unescaper' => __DIR__ . '/..' . '/symfony/yaml/Unescaper.php',
|
||||
'RectorPrefix202402\\Symfony\\Component\\Yaml\\Yaml' => __DIR__ . '/..' . '/symfony/yaml/Yaml.php',
|
||||
'RectorPrefix202402\\Symfony\\Contracts\\Service\\Attribute\\Required' => __DIR__ . '/..' . '/symfony/service-contracts/Attribute/Required.php',
|
||||
'RectorPrefix202402\\Symfony\\Contracts\\Service\\Attribute\\SubscribedService' => __DIR__ . '/..' . '/symfony/service-contracts/Attribute/SubscribedService.php',
|
||||
'RectorPrefix202402\\Symfony\\Contracts\\Service\\ResetInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ResetInterface.php',
|
||||
|
|
|
@ -1679,16 +1679,17 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/rectorphp\/rector-doctrine.git",
|
||||
"reference": "9057680e74d0243c60b9f6fb89c1fe448d363505"
|
||||
"reference": "4eb75185edb27fd390328303f8996ccf34a73e70"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-doctrine\/zipball\/9057680e74d0243c60b9f6fb89c1fe448d363505",
|
||||
"reference": "9057680e74d0243c60b9f6fb89c1fe448d363505",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-doctrine\/zipball\/4eb75185edb27fd390328303f8996ccf34a73e70",
|
||||
"reference": "4eb75185edb27fd390328303f8996ccf34a73e70",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2"
|
||||
"php": ">=8.2",
|
||||
"symfony\/yaml": "^6.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine\/orm": "^2.18",
|
||||
|
@ -1707,7 +1708,7 @@
|
|||
"tomasvotruba\/unused-public": "^0.3",
|
||||
"tracy\/tracy": "^2.10"
|
||||
},
|
||||
"time": "2024-02-09T11:41:38+00:00",
|
||||
"time": "2024-02-11T20:31:00+00:00",
|
||||
"default-branch": true,
|
||||
"type": "rector-extension",
|
||||
"extra": {
|
||||
|
@ -2531,6 +2532,81 @@
|
|||
],
|
||||
"install-path": "..\/symfony\/service-contracts"
|
||||
},
|
||||
{
|
||||
"name": "symfony\/yaml",
|
||||
"version": "v6.4.3",
|
||||
"version_normalized": "6.4.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/symfony\/yaml.git",
|
||||
"reference": "d75715985f0f94f978e3a8fa42533e10db921b90"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/symfony\/yaml\/zipball\/d75715985f0f94f978e3a8fa42533e10db921b90",
|
||||
"reference": "d75715985f0f94f978e3a8fa42533e10db921b90",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"symfony\/deprecation-contracts": "^2.5|^3",
|
||||
"symfony\/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony\/console": "<5.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony\/console": "^5.4|^6.0|^7.0"
|
||||
},
|
||||
"time": "2024-01-23T14:51:35+00:00",
|
||||
"bin": [
|
||||
"Resources\/bin\/yaml-lint"
|
||||
],
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"RectorPrefix202402\\Symfony\\Component\\Yaml\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"\/Tests\/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https:\/\/packagist.org\/downloads\/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https:\/\/symfony.com\/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Loads and dumps YAML files",
|
||||
"homepage": "https:\/\/symfony.com",
|
||||
"support": {
|
||||
"source": "https:\/\/github.com\/symfony\/yaml\/tree\/v6.4.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https:\/\/symfony.com\/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https:\/\/github.com\/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "..\/symfony\/yaml"
|
||||
},
|
||||
{
|
||||
"name": "symplify\/easy-parallel",
|
||||
"version": "11.2.2",
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -9,7 +9,7 @@ namespace Rector\RectorInstaller;
|
|||
*/
|
||||
final class GeneratedConfig
|
||||
{
|
||||
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main 9057680'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main 8d1aab2'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main f091938'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 5a62f17'));
|
||||
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main 4eb7518'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main 8d1aab2'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main f091938'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 5a62f17'));
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
"license": "MIT",
|
||||
"description": "Rector upgrades rules for Doctrine",
|
||||
"require": {
|
||||
"php": ">=8.2"
|
||||
"php": ">=8.2",
|
||||
"symfony\/yaml": "^6.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine\/orm": "^2.18",
|
||||
|
|
|
@ -36,6 +36,7 @@ humbug_phpscoper_expose_class('Product', 'RectorPrefix202402\Product');
|
|||
// Function aliases. For more information see:
|
||||
// https://github.com/humbug/php-scoper/blob/master/docs/further-reading.md#function-aliases
|
||||
if (!function_exists('formatErrorMessage')) { function formatErrorMessage() { return \RectorPrefix202402\formatErrorMessage(...func_get_args()); } }
|
||||
if (!function_exists('includeIfExists')) { function includeIfExists() { return \RectorPrefix202402\includeIfExists(...func_get_args()); } }
|
||||
if (!function_exists('mb_check_encoding')) { function mb_check_encoding() { return \RectorPrefix202402\mb_check_encoding(...func_get_args()); } }
|
||||
if (!function_exists('mb_chr')) { function mb_chr() { return \RectorPrefix202402\mb_chr(...func_get_args()); } }
|
||||
if (!function_exists('mb_convert_case')) { function mb_convert_case() { return \RectorPrefix202402\mb_convert_case(...func_get_args()); } }
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
6.3
|
||||
---
|
||||
|
||||
* Add support to dump int keys as strings by using the `Yaml::DUMP_NUMERIC_KEY_AS_STRING` flag
|
||||
|
||||
6.2
|
||||
---
|
||||
|
||||
* Add support for `!php/enum` and `!php/enum *->value`
|
||||
* Deprecate the `!php/const:` tag in key which will be replaced by the `!php/const` tag (without the colon) since 3.4
|
||||
|
||||
6.1
|
||||
---
|
||||
|
||||
* In cases where it will likely improve readability, strings containing single quotes will be double-quoted
|
||||
|
||||
5.4
|
||||
---
|
||||
|
||||
* Add new `lint:yaml dirname --exclude=/dirname/foo.yaml --exclude=/dirname/bar.yaml`
|
||||
option to exclude one or more specific files from multiple file list
|
||||
* Allow negatable for the parse tags option with `--no-parse-tags`
|
||||
|
||||
5.3
|
||||
---
|
||||
|
||||
* Added `github` format support & autodetection to render errors as annotations
|
||||
when running the YAML linter command in a Github Action environment.
|
||||
|
||||
5.1.0
|
||||
-----
|
||||
|
||||
* Added support for parsing numbers prefixed with `0o` as octal numbers.
|
||||
* Deprecated support for parsing numbers starting with `0` as octal numbers. They will be parsed as strings as of Symfony 6.0. Prefix numbers with `0o`
|
||||
so that they are parsed as octal numbers.
|
||||
|
||||
Before:
|
||||
|
||||
```yaml
|
||||
Yaml::parse('072');
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```yaml
|
||||
Yaml::parse('0o72');
|
||||
```
|
||||
|
||||
* Added `yaml-lint` binary.
|
||||
* Deprecated using the `!php/object` and `!php/const` tags without a value.
|
||||
|
||||
5.0.0
|
||||
-----
|
||||
|
||||
* Removed support for mappings inside multi-line strings.
|
||||
* removed support for implicit STDIN usage in the `lint:yaml` command, use `lint:yaml -` (append a dash) instead to make it explicit.
|
||||
|
||||
4.4.0
|
||||
-----
|
||||
|
||||
* Added support for parsing the inline notation spanning multiple lines.
|
||||
* Added support to dump `null` as `~` by using the `Yaml::DUMP_NULL_AS_TILDE` flag.
|
||||
* deprecated accepting STDIN implicitly when using the `lint:yaml` command, use `lint:yaml -` (append a dash) instead to make it explicit.
|
||||
|
||||
4.3.0
|
||||
-----
|
||||
|
||||
* Using a mapping inside a multi-line string is deprecated and will throw a `ParseException` in 5.0.
|
||||
|
||||
4.2.0
|
||||
-----
|
||||
|
||||
* added support for multiple files or directories in `LintCommand`
|
||||
|
||||
4.0.0
|
||||
-----
|
||||
|
||||
* The behavior of the non-specific tag `!` is changed and now forces
|
||||
non-evaluating your values.
|
||||
* complex mappings will throw a `ParseException`
|
||||
* support for the comma as a group separator for floats has been dropped, use
|
||||
the underscore instead
|
||||
* support for the `!!php/object` tag has been dropped, use the `!php/object`
|
||||
tag instead
|
||||
* duplicate mapping keys throw a `ParseException`
|
||||
* non-string mapping keys throw a `ParseException`, use the `Yaml::PARSE_KEYS_AS_STRINGS`
|
||||
flag to cast them to strings
|
||||
* `%` at the beginning of an unquoted string throw a `ParseException`
|
||||
* mappings with a colon (`:`) that is not followed by a whitespace throw a
|
||||
`ParseException`
|
||||
* the `Dumper::setIndentation()` method has been removed
|
||||
* being able to pass boolean options to the `Yaml::parse()`, `Yaml::dump()`,
|
||||
`Parser::parse()`, and `Dumper::dump()` methods to configure the behavior of
|
||||
the parser and dumper is no longer supported, pass bitmask flags instead
|
||||
* the constructor arguments of the `Parser` class have been removed
|
||||
* the `Inline` class is internal and no longer part of the BC promise
|
||||
* removed support for the `!str` tag, use the `!!str` tag instead
|
||||
* added support for tagged scalars.
|
||||
|
||||
```yml
|
||||
Yaml::parse('!foo bar', Yaml::PARSE_CUSTOM_TAGS);
|
||||
// returns TaggedValue('foo', 'bar');
|
||||
```
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* added support for parsing YAML files using the `Yaml::parseFile()` or `Parser::parseFile()` method
|
||||
|
||||
* the `Dumper`, `Parser`, and `Yaml` classes are marked as final
|
||||
|
||||
* Deprecated the `!php/object:` tag which will be replaced by the
|
||||
`!php/object` tag (without the colon) in 4.0.
|
||||
|
||||
* Deprecated the `!php/const:` tag which will be replaced by the
|
||||
`!php/const` tag (without the colon) in 4.0.
|
||||
|
||||
* Support for the `!str` tag is deprecated, use the `!!str` tag instead.
|
||||
|
||||
* Deprecated using the non-specific tag `!` as its behavior will change in 4.0.
|
||||
It will force non-evaluating your values in 4.0. Use plain integers or `!!float` instead.
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
* Starting an unquoted string with a question mark followed by a space is
|
||||
deprecated and will throw a `ParseException` in Symfony 4.0.
|
||||
|
||||
* Deprecated support for implicitly parsing non-string mapping keys as strings.
|
||||
Mapping keys that are no strings will lead to a `ParseException` in Symfony
|
||||
4.0. Use quotes to opt-in for keys to be parsed as strings.
|
||||
|
||||
Before:
|
||||
|
||||
```php
|
||||
$yaml = <<<YAML
|
||||
null: null key
|
||||
true: boolean true
|
||||
2.0: float key
|
||||
YAML;
|
||||
|
||||
Yaml::parse($yaml);
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```php
|
||||
|
||||
$yaml = <<<YAML
|
||||
"null": null key
|
||||
"true": boolean true
|
||||
"2.0": float key
|
||||
YAML;
|
||||
|
||||
Yaml::parse($yaml);
|
||||
```
|
||||
|
||||
* Omitted mapping values will be parsed as `null`.
|
||||
|
||||
* Omitting the key of a mapping is deprecated and will throw a `ParseException` in Symfony 4.0.
|
||||
|
||||
* Added support for dumping empty PHP arrays as YAML sequences:
|
||||
|
||||
```php
|
||||
Yaml::dump([], 0, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE);
|
||||
```
|
||||
|
||||
3.2.0
|
||||
-----
|
||||
|
||||
* Mappings with a colon (`:`) that is not followed by a whitespace are deprecated
|
||||
when the mapping key is not quoted and will lead to a `ParseException` in
|
||||
Symfony 4.0 (e.g. `foo:bar` must be `foo: bar`).
|
||||
|
||||
* Added support for parsing PHP constants:
|
||||
|
||||
```php
|
||||
Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT);
|
||||
```
|
||||
|
||||
* Support for silently ignoring duplicate mapping keys in YAML has been
|
||||
deprecated and will lead to a `ParseException` in Symfony 4.0.
|
||||
|
||||
3.1.0
|
||||
-----
|
||||
|
||||
* Added support to dump `stdClass` and `ArrayAccess` objects as YAML mappings
|
||||
through the `Yaml::DUMP_OBJECT_AS_MAP` flag.
|
||||
|
||||
* Strings that are not UTF-8 encoded will be dumped as base64 encoded binary
|
||||
data.
|
||||
|
||||
* Added support for dumping multi line strings as literal blocks.
|
||||
|
||||
* Added support for parsing base64 encoded binary data when they are tagged
|
||||
with the `!!binary` tag.
|
||||
|
||||
* Added support for parsing timestamps as `\DateTime` objects:
|
||||
|
||||
```php
|
||||
Yaml::parse('2001-12-15 21:59:43.10 -5', Yaml::PARSE_DATETIME);
|
||||
```
|
||||
|
||||
* `\DateTime` and `\DateTimeImmutable` objects are dumped as YAML timestamps.
|
||||
|
||||
* Deprecated usage of `%` at the beginning of an unquoted string.
|
||||
|
||||
* Added support for customizing the YAML parser behavior through an optional bit field:
|
||||
|
||||
```php
|
||||
Yaml::parse('{ "foo": "bar", "fiz": "cat" }', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE | Yaml::PARSE_OBJECT | Yaml::PARSE_OBJECT_FOR_MAP);
|
||||
```
|
||||
|
||||
* Added support for customizing the dumped YAML string through an optional bit field:
|
||||
|
||||
```php
|
||||
Yaml::dump(['foo' => new A(), 'bar' => 1], 0, 0, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE | Yaml::DUMP_OBJECT);
|
||||
```
|
||||
|
||||
3.0.0
|
||||
-----
|
||||
|
||||
* Yaml::parse() now throws an exception when a blackslash is not escaped
|
||||
in double-quoted strings
|
||||
|
||||
2.8.0
|
||||
-----
|
||||
|
||||
* Deprecated usage of a colon in an unquoted mapping value
|
||||
* Deprecated usage of @, \`, | and > at the beginning of an unquoted string
|
||||
* When surrounding strings with double-quotes, you must now escape `\` characters. Not
|
||||
escaping those characters (when surrounded by double-quotes) is deprecated.
|
||||
|
||||
Before:
|
||||
|
||||
```yml
|
||||
class: "Foo\Var"
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```yml
|
||||
class: "Foo\\Var"
|
||||
```
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
* Yaml::parse() does not evaluate loaded files as PHP files by default
|
||||
anymore (call Yaml::enablePhpParsing() to get back the old behavior)
|
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml\Command;
|
||||
|
||||
use RectorPrefix202402\Symfony\Component\Console\Attribute\AsCommand;
|
||||
use RectorPrefix202402\Symfony\Component\Console\CI\GithubActionReporter;
|
||||
use RectorPrefix202402\Symfony\Component\Console\Command\Command;
|
||||
use RectorPrefix202402\Symfony\Component\Console\Completion\CompletionInput;
|
||||
use RectorPrefix202402\Symfony\Component\Console\Completion\CompletionSuggestions;
|
||||
use RectorPrefix202402\Symfony\Component\Console\Exception\InvalidArgumentException;
|
||||
use RectorPrefix202402\Symfony\Component\Console\Exception\RuntimeException;
|
||||
use RectorPrefix202402\Symfony\Component\Console\Input\InputArgument;
|
||||
use RectorPrefix202402\Symfony\Component\Console\Input\InputInterface;
|
||||
use RectorPrefix202402\Symfony\Component\Console\Input\InputOption;
|
||||
use RectorPrefix202402\Symfony\Component\Console\Output\OutputInterface;
|
||||
use RectorPrefix202402\Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use RectorPrefix202402\Symfony\Component\Yaml\Exception\ParseException;
|
||||
use RectorPrefix202402\Symfony\Component\Yaml\Parser;
|
||||
use RectorPrefix202402\Symfony\Component\Yaml\Yaml;
|
||||
/**
|
||||
* Validates YAML files syntax and outputs encountered errors.
|
||||
*
|
||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
class LintCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @var \Symfony\Component\Yaml\Parser
|
||||
*/
|
||||
private $parser;
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $format;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $displayCorrectFiles;
|
||||
/**
|
||||
* @var \Closure|null
|
||||
*/
|
||||
private $directoryIteratorProvider;
|
||||
/**
|
||||
* @var \Closure|null
|
||||
*/
|
||||
private $isReadableProvider;
|
||||
public function __construct(?string $name = null, ?callable $directoryIteratorProvider = null, ?callable $isReadableProvider = null)
|
||||
{
|
||||
parent::__construct($name);
|
||||
$this->directoryIteratorProvider = null === $directoryIteratorProvider ? null : \Closure::fromCallable($directoryIteratorProvider);
|
||||
$this->isReadableProvider = null === $isReadableProvider ? null : \Closure::fromCallable($isReadableProvider);
|
||||
}
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')->addOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', \implode('", "', $this->getAvailableFormatOptions())))->addOption('exclude', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Path(s) to exclude')->addOption('parse-tags', null, InputOption::VALUE_NEGATABLE, 'Parse custom tags', null)->setHelp(<<<EOF
|
||||
The <info>%command.name%</info> command lints a YAML file and outputs to STDOUT
|
||||
the first encountered syntax error.
|
||||
|
||||
You can validates YAML contents passed from STDIN:
|
||||
|
||||
<info>cat filename | php %command.full_name% -</info>
|
||||
|
||||
You can also validate the syntax of a file:
|
||||
|
||||
<info>php %command.full_name% filename</info>
|
||||
|
||||
Or of a whole directory:
|
||||
|
||||
<info>php %command.full_name% dirname</info>
|
||||
<info>php %command.full_name% dirname --format=json</info>
|
||||
|
||||
You can also exclude one or more specific files:
|
||||
|
||||
<info>php %command.full_name% dirname --exclude="dirname/foo.yaml" --exclude="dirname/bar.yaml"</info>
|
||||
|
||||
EOF
|
||||
);
|
||||
}
|
||||
protected function execute(InputInterface $input, OutputInterface $output) : int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$filenames = (array) $input->getArgument('filename');
|
||||
$excludes = $input->getOption('exclude');
|
||||
$this->format = $input->getOption('format');
|
||||
$flags = $input->getOption('parse-tags');
|
||||
if (null === $this->format) {
|
||||
// Autodetect format according to CI environment
|
||||
$this->format = \class_exists(GithubActionReporter::class) && GithubActionReporter::isGithubActionEnvironment() ? 'github' : 'txt';
|
||||
}
|
||||
$flags = $flags ? Yaml::PARSE_CUSTOM_TAGS : 0;
|
||||
$this->displayCorrectFiles = $output->isVerbose();
|
||||
if (['-'] === $filenames) {
|
||||
return $this->display($io, [$this->validate(\file_get_contents('php://stdin'), $flags)]);
|
||||
}
|
||||
if (!$filenames) {
|
||||
throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
|
||||
}
|
||||
$filesInfo = [];
|
||||
foreach ($filenames as $filename) {
|
||||
if (!$this->isReadable($filename)) {
|
||||
throw new RuntimeException(\sprintf('File or directory "%s" is not readable.', $filename));
|
||||
}
|
||||
foreach ($this->getFiles($filename) as $file) {
|
||||
if (!\in_array($file->getPathname(), $excludes, \true)) {
|
||||
$filesInfo[] = $this->validate(\file_get_contents($file), $flags, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->display($io, $filesInfo);
|
||||
}
|
||||
private function validate(string $content, int $flags, ?string $file = null) : array
|
||||
{
|
||||
$prevErrorHandler = \set_error_handler(function ($level, $message, $file, $line) use(&$prevErrorHandler) {
|
||||
if (\E_USER_DEPRECATED === $level) {
|
||||
throw new ParseException($message, $this->getParser()->getRealCurrentLineNb() + 1);
|
||||
}
|
||||
return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : \false;
|
||||
});
|
||||
try {
|
||||
$this->getParser()->parse($content, Yaml::PARSE_CONSTANT | $flags);
|
||||
} catch (ParseException $e) {
|
||||
return ['file' => $file, 'line' => $e->getParsedLine(), 'valid' => \false, 'message' => $e->getMessage()];
|
||||
} finally {
|
||||
\restore_error_handler();
|
||||
}
|
||||
return ['file' => $file, 'valid' => \true];
|
||||
}
|
||||
private function display(SymfonyStyle $io, array $files) : int
|
||||
{
|
||||
switch ($this->format) {
|
||||
case 'txt':
|
||||
return $this->displayTxt($io, $files);
|
||||
case 'json':
|
||||
return $this->displayJson($io, $files);
|
||||
case 'github':
|
||||
return $this->displayTxt($io, $files, \true);
|
||||
default:
|
||||
throw new InvalidArgumentException(\sprintf('Supported formats are "%s".', \implode('", "', $this->getAvailableFormatOptions())));
|
||||
}
|
||||
}
|
||||
private function displayTxt(SymfonyStyle $io, array $filesInfo, bool $errorAsGithubAnnotations = \false) : int
|
||||
{
|
||||
$countFiles = \count($filesInfo);
|
||||
$erroredFiles = 0;
|
||||
$suggestTagOption = \false;
|
||||
if ($errorAsGithubAnnotations) {
|
||||
$githubReporter = new GithubActionReporter($io);
|
||||
}
|
||||
foreach ($filesInfo as $info) {
|
||||
if ($info['valid'] && $this->displayCorrectFiles) {
|
||||
$io->comment('<info>OK</info>' . ($info['file'] ? \sprintf(' in %s', $info['file']) : ''));
|
||||
} elseif (!$info['valid']) {
|
||||
++$erroredFiles;
|
||||
$io->text('<error> ERROR </error>' . ($info['file'] ? \sprintf(' in %s', $info['file']) : ''));
|
||||
$io->text(\sprintf('<error> >> %s</error>', $info['message']));
|
||||
if (\strpos($info['message'], 'PARSE_CUSTOM_TAGS') !== \false) {
|
||||
$suggestTagOption = \true;
|
||||
}
|
||||
if ($errorAsGithubAnnotations) {
|
||||
$githubReporter->error($info['message'], $info['file'] ?? 'php://stdin', $info['line']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0 === $erroredFiles) {
|
||||
$io->success(\sprintf('All %d YAML files contain valid syntax.', $countFiles));
|
||||
} else {
|
||||
$io->warning(\sprintf('%d YAML files have valid syntax and %d contain errors.%s', $countFiles - $erroredFiles, $erroredFiles, $suggestTagOption ? ' Use the --parse-tags option if you want parse custom tags.' : ''));
|
||||
}
|
||||
return \min($erroredFiles, 1);
|
||||
}
|
||||
private function displayJson(SymfonyStyle $io, array $filesInfo) : int
|
||||
{
|
||||
$errors = 0;
|
||||
\array_walk($filesInfo, function (&$v) use(&$errors) {
|
||||
$v['file'] = (string) $v['file'];
|
||||
if (!$v['valid']) {
|
||||
++$errors;
|
||||
}
|
||||
if (isset($v['message']) && \strpos($v['message'], 'PARSE_CUSTOM_TAGS') !== \false) {
|
||||
$v['message'] .= ' Use the --parse-tags option if you want parse custom tags.';
|
||||
}
|
||||
});
|
||||
$io->writeln(\json_encode($filesInfo, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES));
|
||||
return \min($errors, 1);
|
||||
}
|
||||
private function getFiles(string $fileOrDirectory) : iterable
|
||||
{
|
||||
if (\is_file($fileOrDirectory)) {
|
||||
(yield new \SplFileInfo($fileOrDirectory));
|
||||
return;
|
||||
}
|
||||
foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
|
||||
if (!\in_array($file->getExtension(), ['yml', 'yaml'])) {
|
||||
continue;
|
||||
}
|
||||
(yield $file);
|
||||
}
|
||||
}
|
||||
private function getParser() : Parser
|
||||
{
|
||||
return $this->parser = $this->parser ?? new Parser();
|
||||
}
|
||||
private function getDirectoryIterator(string $directory) : iterable
|
||||
{
|
||||
$default = function ($directory) {
|
||||
return new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS), \RecursiveIteratorIterator::LEAVES_ONLY);
|
||||
};
|
||||
if (null !== $this->directoryIteratorProvider) {
|
||||
return ($this->directoryIteratorProvider)($directory, $default);
|
||||
}
|
||||
return $default($directory);
|
||||
}
|
||||
private function isReadable(string $fileOrDirectory) : bool
|
||||
{
|
||||
$default = \Closure::fromCallable('is_readable');
|
||||
if (null !== $this->isReadableProvider) {
|
||||
return ($this->isReadableProvider)($fileOrDirectory, $default);
|
||||
}
|
||||
return $default($fileOrDirectory);
|
||||
}
|
||||
public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void
|
||||
{
|
||||
if ($input->mustSuggestOptionValuesFor('format')) {
|
||||
$suggestions->suggestValues($this->getAvailableFormatOptions());
|
||||
}
|
||||
}
|
||||
private function getAvailableFormatOptions() : array
|
||||
{
|
||||
return ['txt', 'json', 'github'];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml;
|
||||
|
||||
use RectorPrefix202402\Symfony\Component\Yaml\Tag\TaggedValue;
|
||||
/**
|
||||
* Dumper dumps PHP variables to YAML strings.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class Dumper
|
||||
{
|
||||
/**
|
||||
* The amount of spaces to use for indentation of nested nodes.
|
||||
* @var int
|
||||
*/
|
||||
private $indentation;
|
||||
public function __construct(int $indentation = 4)
|
||||
{
|
||||
if ($indentation < 1) {
|
||||
throw new \InvalidArgumentException('The indentation must be greater than zero.');
|
||||
}
|
||||
$this->indentation = $indentation;
|
||||
}
|
||||
/**
|
||||
* Dumps a PHP value to YAML.
|
||||
*
|
||||
* @param mixed $input The PHP value
|
||||
* @param int $inline The level where you switch to inline YAML
|
||||
* @param int $indent The level of indentation (used internally)
|
||||
* @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
|
||||
*/
|
||||
public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0) : string
|
||||
{
|
||||
$output = '';
|
||||
$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)) {
|
||||
$output .= $prefix . Inline::dump($input, $flags);
|
||||
} elseif ($input instanceof TaggedValue) {
|
||||
$output .= $this->dumpTaggedValue($input, $inline, $indent, $flags, $prefix);
|
||||
} else {
|
||||
$dumpAsMap = Inline::isHash($input);
|
||||
foreach ($input as $key => $value) {
|
||||
if ('' !== $output && "\n" !== $output[-1]) {
|
||||
$output .= "\n";
|
||||
}
|
||||
if (\is_int($key) && Yaml::DUMP_NUMERIC_KEY_AS_STRING & $flags) {
|
||||
$key = (string) $key;
|
||||
}
|
||||
if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && \strpos($value, "\n") !== \false && \strpos($value, "\r") === \false) {
|
||||
$blockIndentationIndicator = $this->getBlockIndentationIndicator($value);
|
||||
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);
|
||||
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());
|
||||
if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && \strpos($value->getValue(), "\n") !== \false && \strpos($value->getValue(), "\r\n") === \false) {
|
||||
$blockIndentationIndicator = $this->getBlockIndentationIndicator($value->getValue());
|
||||
$output .= \sprintf(' |%s', $blockIndentationIndicator);
|
||||
foreach (\explode("\n", $value->getValue()) as $row) {
|
||||
$output .= \sprintf("\n%s%s%s", $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)) {
|
||||
$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;
|
||||
}
|
||||
private function dumpTaggedValue(TaggedValue $value, int $inline, int $indent, int $flags, string $prefix) : string
|
||||
{
|
||||
$output = \sprintf('%s!%s', $prefix ? $prefix . ' ' : '', $value->getTag());
|
||||
if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && \strpos($value->getValue(), "\n") !== \false && \strpos($value->getValue(), "\r\n") === \false) {
|
||||
$blockIndentationIndicator = $this->getBlockIndentationIndicator($value->getValue());
|
||||
$output .= \sprintf(' |%s', $blockIndentationIndicator);
|
||||
foreach (\explode("\n", $value->getValue()) as $row) {
|
||||
$output .= \sprintf("\n%s%s%s", $prefix, \str_repeat(' ', $this->indentation), $row);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
if ($inline - 1 <= 0 || null === $value->getValue() || \is_scalar($value->getValue())) {
|
||||
return $output . ' ' . $this->dump($value->getValue(), $inline - 1, 0, $flags) . "\n";
|
||||
}
|
||||
return $output . "\n" . $this->dump($value->getValue(), $inline - 1, $indent, $flags);
|
||||
}
|
||||
private function getBlockIndentationIndicator(string $value) : string
|
||||
{
|
||||
$lines = \explode("\n", $value);
|
||||
// If the first line (that is neither empty nor contains only spaces)
|
||||
// starts with a space character, the spec requires a block indentation indicator
|
||||
// http://www.yaml.org/spec/1.2/spec.html#id2793979
|
||||
foreach ($lines as $line) {
|
||||
if ('' !== \trim($line, ' ')) {
|
||||
return ' ' === \substr($line, 0, 1) ? (string) $this->indentation : '';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml;
|
||||
|
||||
/**
|
||||
* Escaper encapsulates escaping rules for single and double-quoted
|
||||
* YAML strings.
|
||||
*
|
||||
* @author Matthew Lewinski <matthew@lewinski.org>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class Escaper
|
||||
{
|
||||
// Characters that would cause a dumped string to require double quoting.
|
||||
public const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]||
| |
|
";
|
||||
// Mapping arrays for escaping a double quoted string. The backslash is
|
||||
// first to ensure proper escaping because str_replace operates iteratively
|
||||
// on the input arrays. This ordering of the characters avoids the use of strtr,
|
||||
// which performs more slowly.
|
||||
private const ESCAPEES = ['\\', '\\\\', '\\"', '"', "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\t", "\n", "\v", "\f", "\r", "\x0e", "\x0f", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", "", "
", " ", "
", "
"];
|
||||
private const ESCAPED = ['\\\\', '\\"', '\\\\', '\\"', '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a', '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f', '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f', '\\x7f', '\\N', '\\_', '\\L', '\\P'];
|
||||
/**
|
||||
* Determines if a PHP value would require double quoting in YAML.
|
||||
*
|
||||
* @param string $value A PHP value
|
||||
*/
|
||||
public static function requiresDoubleQuoting(string $value) : bool
|
||||
{
|
||||
return 0 < \preg_match('/' . self::REGEX_CHARACTER_TO_ESCAPE . '/u', $value);
|
||||
}
|
||||
/**
|
||||
* Escapes and surrounds a PHP value with double quotes.
|
||||
*
|
||||
* @param string $value A PHP value
|
||||
*/
|
||||
public static function escapeWithDoubleQuotes(string $value) : string
|
||||
{
|
||||
return \sprintf('"%s"', \str_replace(self::ESCAPEES, self::ESCAPED, $value));
|
||||
}
|
||||
/**
|
||||
* Determines if a PHP value would require single quoting in YAML.
|
||||
*
|
||||
* @param string $value A PHP value
|
||||
*/
|
||||
public static function requiresSingleQuoting(string $value) : bool
|
||||
{
|
||||
// Determines if a PHP value is entirely composed of a value that would
|
||||
// require single quoting in YAML.
|
||||
if (\in_array(\strtolower($value), ['null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'])) {
|
||||
return \true;
|
||||
}
|
||||
// Determines if the PHP value contains any single characters that would
|
||||
// cause it to require single quoting in YAML.
|
||||
return 0 < \preg_match('/[ \\s \' " \\: \\{ \\} \\[ \\] , & \\* \\# \\?] | \\A[ \\- ? | < > = ! % @ ` \\p{Zs}]/xu', $value);
|
||||
}
|
||||
/**
|
||||
* Escapes and surrounds a PHP value with single quotes.
|
||||
*
|
||||
* @param string $value A PHP value
|
||||
*/
|
||||
public static function escapeWithSingleQuotes(string $value) : string
|
||||
{
|
||||
return \sprintf("'%s'", \str_replace('\'', '\'\'', $value));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml\Exception;
|
||||
|
||||
/**
|
||||
* Exception class thrown when an error occurs during dumping.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class DumpException extends RuntimeException
|
||||
{
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml\Exception;
|
||||
|
||||
/**
|
||||
* Exception interface for all exceptions thrown by the component.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface ExceptionInterface extends \Throwable
|
||||
{
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml\Exception;
|
||||
|
||||
/**
|
||||
* Exception class thrown when an error occurs during parsing.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ParseException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $parsedFile;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $parsedLine;
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $snippet;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $rawMessage;
|
||||
/**
|
||||
* @param string $message The error message
|
||||
* @param int $parsedLine The line where the error occurred
|
||||
* @param string|null $snippet The snippet of code near the problem
|
||||
* @param string|null $parsedFile The file name where the error occurred
|
||||
*/
|
||||
public function __construct(string $message, int $parsedLine = -1, ?string $snippet = null, ?string $parsedFile = null, ?\Throwable $previous = null)
|
||||
{
|
||||
$this->parsedFile = $parsedFile;
|
||||
$this->parsedLine = $parsedLine;
|
||||
$this->snippet = $snippet;
|
||||
$this->rawMessage = $message;
|
||||
$this->updateRepr();
|
||||
parent::__construct($this->message, 0, $previous);
|
||||
}
|
||||
/**
|
||||
* Gets the snippet of code near the error.
|
||||
*/
|
||||
public function getSnippet() : string
|
||||
{
|
||||
return $this->snippet;
|
||||
}
|
||||
/**
|
||||
* Sets the snippet of code near the error.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSnippet(string $snippet)
|
||||
{
|
||||
$this->snippet = $snippet;
|
||||
$this->updateRepr();
|
||||
}
|
||||
/**
|
||||
* Gets the filename where the error occurred.
|
||||
*
|
||||
* This method returns null if a string is parsed.
|
||||
*/
|
||||
public function getParsedFile() : string
|
||||
{
|
||||
return $this->parsedFile;
|
||||
}
|
||||
/**
|
||||
* Sets the filename where the error occurred.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setParsedFile(string $parsedFile)
|
||||
{
|
||||
$this->parsedFile = $parsedFile;
|
||||
$this->updateRepr();
|
||||
}
|
||||
/**
|
||||
* Gets the line where the error occurred.
|
||||
*/
|
||||
public function getParsedLine() : int
|
||||
{
|
||||
return $this->parsedLine;
|
||||
}
|
||||
/**
|
||||
* Sets the line where the error occurred.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setParsedLine(int $parsedLine)
|
||||
{
|
||||
$this->parsedLine = $parsedLine;
|
||||
$this->updateRepr();
|
||||
}
|
||||
private function updateRepr() : void
|
||||
{
|
||||
$this->message = $this->rawMessage;
|
||||
$dot = \false;
|
||||
if (\substr_compare($this->message, '.', -\strlen('.')) === 0) {
|
||||
$this->message = \substr($this->message, 0, -1);
|
||||
$dot = \true;
|
||||
}
|
||||
if (null !== $this->parsedFile) {
|
||||
$this->message .= \sprintf(' in %s', \json_encode($this->parsedFile, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
if ($this->parsedLine >= 0) {
|
||||
$this->message .= \sprintf(' at line %d', $this->parsedLine);
|
||||
}
|
||||
if ($this->snippet) {
|
||||
$this->message .= \sprintf(' (near "%s")', $this->snippet);
|
||||
}
|
||||
if ($dot) {
|
||||
$this->message .= '.';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml\Exception;
|
||||
|
||||
/**
|
||||
* Exception class thrown when an error occurs during parsing.
|
||||
*
|
||||
* @author Romain Neutron <imprec@gmail.com>
|
||||
*/
|
||||
class RuntimeException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
|
@ -0,0 +1,735 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml;
|
||||
|
||||
use RectorPrefix202402\Symfony\Component\Yaml\Exception\DumpException;
|
||||
use RectorPrefix202402\Symfony\Component\Yaml\Exception\ParseException;
|
||||
use RectorPrefix202402\Symfony\Component\Yaml\Tag\TaggedValue;
|
||||
/**
|
||||
* Inline implements a YAML parser/dumper for the YAML inline syntax.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class Inline
|
||||
{
|
||||
public const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public static $parsedLineNumber = -1;
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public static $parsedFilename;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $exceptionOnInvalidType = \false;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $objectSupport = \false;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $objectForMap = \false;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $constantSupport = \false;
|
||||
public static function initialize(int $flags, ?int $parsedLineNumber = null, ?string $parsedFilename = null) : void
|
||||
{
|
||||
self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags);
|
||||
self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags);
|
||||
self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags);
|
||||
self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags);
|
||||
self::$parsedFilename = $parsedFilename;
|
||||
if (null !== $parsedLineNumber) {
|
||||
self::$parsedLineNumber = $parsedLineNumber;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Converts a YAML string to a PHP value.
|
||||
*
|
||||
* @param int $flags A bit field of Yaml::PARSE_* constants to customize the YAML parser behavior
|
||||
* @param array $references Mapping of variable names to values
|
||||
*
|
||||
* @throws ParseException
|
||||
* @return mixed
|
||||
*/
|
||||
public static function parse(string $value, int $flags = 0, array &$references = [])
|
||||
{
|
||||
self::initialize($flags);
|
||||
$value = \trim($value);
|
||||
if ('' === $value) {
|
||||
return '';
|
||||
}
|
||||
$i = 0;
|
||||
$tag = self::parseTag($value, $i, $flags);
|
||||
switch ($value[$i]) {
|
||||
case '[':
|
||||
$result = self::parseSequence($value, $flags, $i, $references);
|
||||
++$i;
|
||||
break;
|
||||
case '{':
|
||||
$result = self::parseMapping($value, $flags, $i, $references);
|
||||
++$i;
|
||||
break;
|
||||
default:
|
||||
$result = self::parseScalar($value, $flags, null, $i, \true, $references);
|
||||
}
|
||||
// some comments are allowed at the end
|
||||
if (\preg_replace('/\\s*#.*$/A', '', \substr($value, $i))) {
|
||||
throw new ParseException(\sprintf('Unexpected characters near "%s".', \substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
|
||||
}
|
||||
if (null !== $tag && '' !== $tag) {
|
||||
return new TaggedValue($tag, $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* Dumps a given PHP variable to a YAML string.
|
||||
*
|
||||
* @param mixed $value The PHP variable to convert
|
||||
* @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
|
||||
*
|
||||
* @throws DumpException When trying to dump PHP resource
|
||||
*/
|
||||
public static function dump($value, int $flags = 0) : string
|
||||
{
|
||||
switch (\true) {
|
||||
case \is_resource($value):
|
||||
if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) {
|
||||
throw new DumpException(\sprintf('Unable to dump PHP resources in a YAML file ("%s").', \get_resource_type($value)));
|
||||
}
|
||||
return self::dumpNull($flags);
|
||||
case $value instanceof \DateTimeInterface:
|
||||
return $value->format((function () use($value) {
|
||||
switch (\true) {
|
||||
case !($length = \strlen(\rtrim($value->format('u'), '0'))):
|
||||
return 'c';
|
||||
case $length < 4:
|
||||
return 'Y-m-d\\TH:i:s.vP';
|
||||
default:
|
||||
return 'Y-m-d\\TH:i:s.uP';
|
||||
}
|
||||
})());
|
||||
case $value instanceof \UnitEnum:
|
||||
return \sprintf('!php/const %s::%s', \get_class($value), $value->name);
|
||||
case \is_object($value):
|
||||
if ($value instanceof TaggedValue) {
|
||||
return '!' . $value->getTag() . ' ' . self::dump($value->getValue(), $flags);
|
||||
}
|
||||
if (Yaml::DUMP_OBJECT & $flags) {
|
||||
return '!php/object ' . self::dump(\serialize($value));
|
||||
}
|
||||
if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) {
|
||||
return self::dumpHashArray($value, $flags);
|
||||
}
|
||||
if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) {
|
||||
throw new DumpException('Object support when dumping a YAML file has been disabled.');
|
||||
}
|
||||
return self::dumpNull($flags);
|
||||
case \is_array($value):
|
||||
return self::dumpArray($value, $flags);
|
||||
case null === $value:
|
||||
return self::dumpNull($flags);
|
||||
case \true === $value:
|
||||
return 'true';
|
||||
case \false === $value:
|
||||
return 'false';
|
||||
case \is_int($value):
|
||||
return $value;
|
||||
case \is_numeric($value) && \false === \strpbrk($value, "\f\n\r\t\v"):
|
||||
$locale = \setlocale(\LC_NUMERIC, 0);
|
||||
if (\false !== $locale) {
|
||||
\setlocale(\LC_NUMERIC, 'C');
|
||||
}
|
||||
if (\is_float($value)) {
|
||||
$repr = (string) $value;
|
||||
if (\is_infinite($value)) {
|
||||
$repr = \str_ireplace('INF', '.Inf', $repr);
|
||||
} elseif (\floor($value) == $value && $repr == $value) {
|
||||
// Preserve float data type since storing a whole number will result in integer value.
|
||||
if (\strpos($repr, 'E') === \false) {
|
||||
$repr .= '.0';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$repr = \is_string($value) ? "'{$value}'" : (string) $value;
|
||||
}
|
||||
if (\false !== $locale) {
|
||||
\setlocale(\LC_NUMERIC, $locale);
|
||||
}
|
||||
return $repr;
|
||||
case '' == $value:
|
||||
return "''";
|
||||
case self::isBinaryString($value):
|
||||
return '!!binary ' . \base64_encode($value);
|
||||
case Escaper::requiresDoubleQuoting($value):
|
||||
return Escaper::escapeWithDoubleQuotes($value);
|
||||
case Escaper::requiresSingleQuoting($value):
|
||||
$singleQuoted = Escaper::escapeWithSingleQuotes($value);
|
||||
if (\strpos($value, "'") === \false) {
|
||||
return $singleQuoted;
|
||||
}
|
||||
// Attempt double-quoting the string instead to see if it's more efficient.
|
||||
$doubleQuoted = Escaper::escapeWithDoubleQuotes($value);
|
||||
return \strlen($doubleQuoted) < \strlen($singleQuoted) ? $doubleQuoted : $singleQuoted;
|
||||
case Parser::preg_match('{^[0-9]+[_0-9]*$}', $value):
|
||||
case Parser::preg_match(self::getHexRegex(), $value):
|
||||
case Parser::preg_match(self::getTimestampRegex(), $value):
|
||||
return Escaper::escapeWithSingleQuotes($value);
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check if given array is hash or just normal indexed array.
|
||||
* @param mixed[]|\ArrayObject|\stdClass $value
|
||||
*/
|
||||
public static function isHash($value) : bool
|
||||
{
|
||||
if ($value instanceof \stdClass || $value instanceof \ArrayObject) {
|
||||
return \true;
|
||||
}
|
||||
$expectedKey = 0;
|
||||
foreach ($value as $key => $val) {
|
||||
if ($key !== $expectedKey++) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
/**
|
||||
* Dumps a PHP array to a YAML string.
|
||||
*
|
||||
* @param array $value The PHP array to dump
|
||||
* @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
|
||||
*/
|
||||
private static function dumpArray(array $value, int $flags) : string
|
||||
{
|
||||
// array
|
||||
if (($value || Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE & $flags) && !self::isHash($value)) {
|
||||
$output = [];
|
||||
foreach ($value as $val) {
|
||||
$output[] = self::dump($val, $flags);
|
||||
}
|
||||
return \sprintf('[%s]', \implode(', ', $output));
|
||||
}
|
||||
return self::dumpHashArray($value, $flags);
|
||||
}
|
||||
/**
|
||||
* Dumps hash array to a YAML string.
|
||||
*
|
||||
* @param array|\ArrayObject|\stdClass $value The hash array to dump
|
||||
* @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
|
||||
*/
|
||||
private static function dumpHashArray($value, int $flags) : string
|
||||
{
|
||||
$output = [];
|
||||
foreach ($value as $key => $val) {
|
||||
if (\is_int($key) && Yaml::DUMP_NUMERIC_KEY_AS_STRING & $flags) {
|
||||
$key = (string) $key;
|
||||
}
|
||||
$output[] = \sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags));
|
||||
}
|
||||
return \sprintf('{ %s }', \implode(', ', $output));
|
||||
}
|
||||
private static function dumpNull(int $flags) : string
|
||||
{
|
||||
if (Yaml::DUMP_NULL_AS_TILDE & $flags) {
|
||||
return '~';
|
||||
}
|
||||
return 'null';
|
||||
}
|
||||
/**
|
||||
* Parses a YAML scalar.
|
||||
*
|
||||
* @throws ParseException When malformed inline YAML string is parsed
|
||||
* @return mixed
|
||||
*/
|
||||
public static function parseScalar(string $scalar, int $flags = 0, ?array $delimiters = null, int &$i = 0, bool $evaluate = \true, array &$references = [], ?bool &$isQuoted = null)
|
||||
{
|
||||
if (\in_array($scalar[$i], ['"', "'"], \true)) {
|
||||
// quoted scalar
|
||||
$isQuoted = \true;
|
||||
$output = self::parseQuotedScalar($scalar, $i);
|
||||
if (null !== $delimiters) {
|
||||
$tmp = \ltrim(\substr($scalar, $i), " \n");
|
||||
if ('' === $tmp) {
|
||||
throw new ParseException(\sprintf('Unexpected end of line, expected one of "%s".', \implode('', $delimiters)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
if (!\in_array($tmp[0], $delimiters)) {
|
||||
throw new ParseException(\sprintf('Unexpected characters (%s).', \substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// "normal" string
|
||||
$isQuoted = \false;
|
||||
if (!$delimiters) {
|
||||
$output = \substr($scalar, $i);
|
||||
$i += \strlen($output);
|
||||
// remove comments
|
||||
if (Parser::preg_match('/[ \\t]+#/', $output, $match, \PREG_OFFSET_CAPTURE)) {
|
||||
$output = \substr($output, 0, $match[0][1]);
|
||||
}
|
||||
} elseif (Parser::preg_match('/^(.*?)(' . \implode('|', $delimiters) . ')/', \substr($scalar, $i), $match)) {
|
||||
$output = $match[1];
|
||||
$i += \strlen($output);
|
||||
$output = \trim($output);
|
||||
} else {
|
||||
throw new ParseException(\sprintf('Malformed inline YAML string: "%s".', $scalar), self::$parsedLineNumber + 1, null, self::$parsedFilename);
|
||||
}
|
||||
// a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >)
|
||||
if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0] || '%' === $output[0])) {
|
||||
throw new ParseException(\sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0]), self::$parsedLineNumber + 1, $output, self::$parsedFilename);
|
||||
}
|
||||
if ($evaluate) {
|
||||
$output = self::evaluateScalar($output, $flags, $references, $isQuoted);
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
/**
|
||||
* Parses a YAML quoted scalar.
|
||||
*
|
||||
* @throws ParseException When malformed inline YAML string is parsed
|
||||
*/
|
||||
private static function parseQuotedScalar(string $scalar, int &$i = 0) : string
|
||||
{
|
||||
if (!Parser::preg_match('/' . self::REGEX_QUOTED_STRING . '/Au', \substr($scalar, $i), $match)) {
|
||||
throw new ParseException(\sprintf('Malformed inline YAML string: "%s".', \substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
$output = \substr($match[0], 1, -1);
|
||||
$unescaper = new Unescaper();
|
||||
if ('"' == $scalar[$i]) {
|
||||
$output = $unescaper->unescapeDoubleQuotedString($output);
|
||||
} else {
|
||||
$output = $unescaper->unescapeSingleQuotedString($output);
|
||||
}
|
||||
$i += \strlen($match[0]);
|
||||
return $output;
|
||||
}
|
||||
/**
|
||||
* Parses a YAML sequence.
|
||||
*
|
||||
* @throws ParseException When malformed inline YAML string is parsed
|
||||
*/
|
||||
private static function parseSequence(string $sequence, int $flags, int &$i = 0, array &$references = []) : array
|
||||
{
|
||||
$output = [];
|
||||
$len = \strlen($sequence);
|
||||
++$i;
|
||||
// [foo, bar, ...]
|
||||
while ($i < $len) {
|
||||
if (']' === $sequence[$i]) {
|
||||
return $output;
|
||||
}
|
||||
if (',' === $sequence[$i] || ' ' === $sequence[$i]) {
|
||||
++$i;
|
||||
continue;
|
||||
}
|
||||
$tag = self::parseTag($sequence, $i, $flags);
|
||||
switch ($sequence[$i]) {
|
||||
case '[':
|
||||
// nested sequence
|
||||
$value = self::parseSequence($sequence, $flags, $i, $references);
|
||||
break;
|
||||
case '{':
|
||||
// nested mapping
|
||||
$value = self::parseMapping($sequence, $flags, $i, $references);
|
||||
break;
|
||||
default:
|
||||
$value = self::parseScalar($sequence, $flags, [',', ']'], $i, null === $tag, $references, $isQuoted);
|
||||
// the value can be an array if a reference has been resolved to an array var
|
||||
if (\is_string($value) && !$isQuoted && \strpos($value, ': ') !== \false) {
|
||||
// embedded mapping?
|
||||
try {
|
||||
$pos = 0;
|
||||
$value = self::parseMapping('{' . $value . '}', $flags, $pos, $references);
|
||||
} catch (\InvalidArgumentException $exception) {
|
||||
// no, it's not
|
||||
}
|
||||
}
|
||||
if (!$isQuoted && \is_string($value) && '' !== $value && '&' === $value[0] && Parser::preg_match(Parser::REFERENCE_PATTERN, $value, $matches)) {
|
||||
$references[$matches['ref']] = $matches['value'];
|
||||
$value = $matches['value'];
|
||||
}
|
||||
--$i;
|
||||
}
|
||||
if (null !== $tag && '' !== $tag) {
|
||||
$value = new TaggedValue($tag, $value);
|
||||
}
|
||||
$output[] = $value;
|
||||
++$i;
|
||||
}
|
||||
throw new ParseException(\sprintf('Malformed inline YAML string: "%s".', $sequence), self::$parsedLineNumber + 1, null, self::$parsedFilename);
|
||||
}
|
||||
/**
|
||||
* Parses a YAML mapping.
|
||||
*
|
||||
* @throws ParseException When malformed inline YAML string is parsed
|
||||
* @return mixed[]|\stdClass
|
||||
*/
|
||||
private static function parseMapping(string $mapping, int $flags, int &$i = 0, array &$references = [])
|
||||
{
|
||||
$output = [];
|
||||
$len = \strlen($mapping);
|
||||
++$i;
|
||||
$allowOverwrite = \false;
|
||||
// {foo: bar, bar:foo, ...}
|
||||
while ($i < $len) {
|
||||
switch ($mapping[$i]) {
|
||||
case ' ':
|
||||
case ',':
|
||||
case "\n":
|
||||
++$i;
|
||||
continue 2;
|
||||
case '}':
|
||||
if (self::$objectForMap) {
|
||||
return (object) $output;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
// key
|
||||
$offsetBeforeKeyParsing = $i;
|
||||
$isKeyQuoted = \in_array($mapping[$i], ['"', "'"], \true);
|
||||
$key = self::parseScalar($mapping, $flags, [':', ' '], $i, \false);
|
||||
if ($offsetBeforeKeyParsing === $i) {
|
||||
throw new ParseException('Missing mapping key.', self::$parsedLineNumber + 1, $mapping);
|
||||
}
|
||||
if ('!php/const' === $key || '!php/enum' === $key) {
|
||||
$key .= ' ' . self::parseScalar($mapping, $flags, [':'], $i, \false);
|
||||
$key = self::evaluateScalar($key, $flags);
|
||||
}
|
||||
if (\false === ($i = \strpos($mapping, ':', $i))) {
|
||||
break;
|
||||
}
|
||||
if (!$isKeyQuoted) {
|
||||
$evaluatedKey = self::evaluateScalar($key, $flags, $references);
|
||||
if ('' !== $key && $evaluatedKey !== $key && !\is_string($evaluatedKey) && !\is_int($evaluatedKey)) {
|
||||
throw new ParseException('Implicit casting of incompatible mapping keys to strings is not supported. Quote your evaluable mapping keys instead.', self::$parsedLineNumber + 1, $mapping);
|
||||
}
|
||||
}
|
||||
if (!$isKeyQuoted && (!isset($mapping[$i + 1]) || !\in_array($mapping[$i + 1], [' ', ',', '[', ']', '{', '}', "\n"], \true))) {
|
||||
throw new ParseException('Colons must be followed by a space or an indication character (i.e. " ", ",", "[", "]", "{", "}").', self::$parsedLineNumber + 1, $mapping);
|
||||
}
|
||||
if ('<<' === $key) {
|
||||
$allowOverwrite = \true;
|
||||
}
|
||||
while ($i < $len) {
|
||||
if (':' === $mapping[$i] || ' ' === $mapping[$i] || "\n" === $mapping[$i]) {
|
||||
++$i;
|
||||
continue;
|
||||
}
|
||||
$tag = self::parseTag($mapping, $i, $flags);
|
||||
switch ($mapping[$i]) {
|
||||
case '[':
|
||||
// nested sequence
|
||||
$value = self::parseSequence($mapping, $flags, $i, $references);
|
||||
// Spec: Keys MUST be unique; first one wins.
|
||||
// Parser cannot abort this mapping earlier, since lines
|
||||
// are processed sequentially.
|
||||
// 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])) {
|
||||
if (null !== $tag) {
|
||||
$output[$key] = new TaggedValue($tag, $value);
|
||||
} else {
|
||||
$output[$key] = $value;
|
||||
}
|
||||
} elseif (isset($output[$key])) {
|
||||
throw new ParseException(\sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
|
||||
}
|
||||
break;
|
||||
case '{':
|
||||
// nested mapping
|
||||
$value = self::parseMapping($mapping, $flags, $i, $references);
|
||||
// Spec: Keys MUST be unique; first one wins.
|
||||
// Parser cannot abort this mapping earlier, since lines
|
||||
// are processed sequentially.
|
||||
// But overwriting is allowed when a merge node is used in current block.
|
||||
if ('<<' === $key) {
|
||||
$output += $value;
|
||||
} elseif ($allowOverwrite || !isset($output[$key])) {
|
||||
if (null !== $tag) {
|
||||
$output[$key] = new TaggedValue($tag, $value);
|
||||
} else {
|
||||
$output[$key] = $value;
|
||||
}
|
||||
} elseif (isset($output[$key])) {
|
||||
throw new ParseException(\sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$value = self::parseScalar($mapping, $flags, [',', '}', "\n"], $i, null === $tag, $references, $isValueQuoted);
|
||||
// Spec: Keys MUST be unique; first one wins.
|
||||
// Parser cannot abort this mapping earlier, since lines
|
||||
// are processed sequentially.
|
||||
// But overwriting is allowed when a merge node is used in current block.
|
||||
if ('<<' === $key) {
|
||||
$output += $value;
|
||||
} elseif ($allowOverwrite || !isset($output[$key])) {
|
||||
if (!$isValueQuoted && \is_string($value) && '' !== $value && '&' === $value[0] && !self::isBinaryString($value) && Parser::preg_match(Parser::REFERENCE_PATTERN, $value, $matches)) {
|
||||
$references[$matches['ref']] = $matches['value'];
|
||||
$value = $matches['value'];
|
||||
}
|
||||
if (null !== $tag) {
|
||||
$output[$key] = new TaggedValue($tag, $value);
|
||||
} else {
|
||||
$output[$key] = $value;
|
||||
}
|
||||
} elseif (isset($output[$key])) {
|
||||
throw new ParseException(\sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
|
||||
}
|
||||
--$i;
|
||||
}
|
||||
++$i;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
throw new ParseException(\sprintf('Malformed inline YAML string: "%s".', $mapping), self::$parsedLineNumber + 1, null, self::$parsedFilename);
|
||||
}
|
||||
/**
|
||||
* Evaluates scalars and replaces magic values.
|
||||
*
|
||||
* @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved
|
||||
* @return mixed
|
||||
*/
|
||||
private static function evaluateScalar(string $scalar, int $flags, array &$references = [], ?bool &$isQuotedString = null)
|
||||
{
|
||||
$isQuotedString = \false;
|
||||
$scalar = \trim($scalar);
|
||||
if (\strncmp($scalar, '*', \strlen('*')) === 0) {
|
||||
if (\false !== ($pos = \strpos($scalar, '#'))) {
|
||||
$value = \substr($scalar, 1, $pos - 2);
|
||||
} else {
|
||||
$value = \substr($scalar, 1);
|
||||
}
|
||||
// an unquoted *
|
||||
if (\false === $value || '' === $value) {
|
||||
throw new ParseException('A reference must contain at least one character.', self::$parsedLineNumber + 1, $value, self::$parsedFilename);
|
||||
}
|
||||
if (!\array_key_exists($value, $references)) {
|
||||
throw new ParseException(\sprintf('Reference "%s" does not exist.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
|
||||
}
|
||||
return $references[$value];
|
||||
}
|
||||
$scalarLower = \strtolower($scalar);
|
||||
switch (\true) {
|
||||
case 'null' === $scalarLower:
|
||||
case '' === $scalar:
|
||||
case '~' === $scalar:
|
||||
return null;
|
||||
case 'true' === $scalarLower:
|
||||
return \true;
|
||||
case 'false' === $scalarLower:
|
||||
return \false;
|
||||
case '!' === $scalar[0]:
|
||||
switch (\true) {
|
||||
case \strncmp($scalar, '!!str ', \strlen('!!str ')) === 0:
|
||||
$s = (string) \substr($scalar, 6);
|
||||
if (\in_array($s[0] ?? '', ['"', "'"], \true)) {
|
||||
$isQuotedString = \true;
|
||||
$s = self::parseQuotedScalar($s);
|
||||
}
|
||||
return $s;
|
||||
case \strncmp($scalar, '! ', \strlen('! ')) === 0:
|
||||
return \substr($scalar, 2);
|
||||
case \strncmp($scalar, '!php/object', \strlen('!php/object')) === 0:
|
||||
if (self::$objectSupport) {
|
||||
if (!isset($scalar[12])) {
|
||||
throw new ParseException('Missing value for tag "!php/object".', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
return \unserialize(self::parseScalar(\substr($scalar, 12)));
|
||||
}
|
||||
if (self::$exceptionOnInvalidType) {
|
||||
throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
return null;
|
||||
case \strncmp($scalar, '!php/const', \strlen('!php/const')) === 0:
|
||||
if (self::$constantSupport) {
|
||||
if (!isset($scalar[11])) {
|
||||
throw new ParseException('Missing value for tag "!php/const".', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
$i = 0;
|
||||
if (\defined($const = self::parseScalar(\substr($scalar, 11), 0, null, $i, \false))) {
|
||||
return \constant($const);
|
||||
}
|
||||
throw new ParseException(\sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
if (self::$exceptionOnInvalidType) {
|
||||
throw new ParseException(\sprintf('The string "%s" could not be parsed as a constant. Did you forget to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
return null;
|
||||
case \strncmp($scalar, '!php/enum', \strlen('!php/enum')) === 0:
|
||||
if (self::$constantSupport) {
|
||||
if (!isset($scalar[11])) {
|
||||
throw new ParseException('Missing value for tag "!php/enum".', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
$i = 0;
|
||||
$enum = self::parseScalar(\substr($scalar, 10), 0, null, $i, \false);
|
||||
if ($useValue = \substr_compare($enum, '->value', -\strlen('->value')) === 0) {
|
||||
$enum = \substr($enum, 0, -7);
|
||||
}
|
||||
if (!\defined($enum)) {
|
||||
throw new ParseException(\sprintf('The enum "%s" is not defined.', $enum), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
$value = \constant($enum);
|
||||
if (!$value instanceof \UnitEnum) {
|
||||
throw new ParseException(\sprintf('The string "%s" is not the name of a valid enum.', $enum), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
if (!$useValue) {
|
||||
return $value;
|
||||
}
|
||||
if (!$value instanceof \BackedEnum) {
|
||||
throw new ParseException(\sprintf('The enum "%s" defines no value next to its name.', $enum), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
return $value->value;
|
||||
}
|
||||
if (self::$exceptionOnInvalidType) {
|
||||
throw new ParseException(\sprintf('The string "%s" could not be parsed as an enum. Did you forget to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
return null;
|
||||
case \strncmp($scalar, '!!float ', \strlen('!!float ')) === 0:
|
||||
return (float) \substr($scalar, 8);
|
||||
case \strncmp($scalar, '!!binary ', \strlen('!!binary ')) === 0:
|
||||
return self::evaluateBinaryScalar(\substr($scalar, 9));
|
||||
}
|
||||
throw new ParseException(\sprintf('The string "%s" could not be parsed as it uses an unsupported built-in tag.', $scalar), self::$parsedLineNumber, $scalar, self::$parsedFilename);
|
||||
case \preg_match('/^(?:\\+|-)?0o(?P<value>[0-7_]++)$/', $scalar, $matches):
|
||||
$value = \str_replace('_', '', $matches['value']);
|
||||
if ('-' === $scalar[0]) {
|
||||
return -\octdec($value);
|
||||
}
|
||||
return \octdec($value);
|
||||
case \in_array($scalar[0], ['+', '-', '.'], \true) || \is_numeric($scalar[0]):
|
||||
if (Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar)) {
|
||||
$scalar = \str_replace('_', '', $scalar);
|
||||
}
|
||||
switch (\true) {
|
||||
case \ctype_digit($scalar):
|
||||
case '-' === $scalar[0] && \ctype_digit(\substr($scalar, 1)):
|
||||
$cast = (int) $scalar;
|
||||
return $scalar === (string) $cast ? $cast : $scalar;
|
||||
case \is_numeric($scalar):
|
||||
case Parser::preg_match(self::getHexRegex(), $scalar):
|
||||
$scalar = \str_replace('_', '', $scalar);
|
||||
return '0x' === $scalar[0] . $scalar[1] ? \hexdec($scalar) : (float) $scalar;
|
||||
case '.inf' === $scalarLower:
|
||||
case '.nan' === $scalarLower:
|
||||
return -\log(0);
|
||||
case '-.inf' === $scalarLower:
|
||||
return \log(0);
|
||||
case Parser::preg_match('/^(-|\\+)?[0-9][0-9_]*(\\.[0-9_]+)?$/', $scalar):
|
||||
return (float) \str_replace('_', '', $scalar);
|
||||
case Parser::preg_match(self::getTimestampRegex(), $scalar):
|
||||
// When no timezone is provided in the parsed date, YAML spec says we must assume UTC.
|
||||
$time = new \DateTimeImmutable($scalar, new \DateTimeZone('UTC'));
|
||||
if (Yaml::PARSE_DATETIME & $flags) {
|
||||
return $time;
|
||||
}
|
||||
if ('' !== \rtrim($time->format('u'), '0')) {
|
||||
return (float) $time->format('U.u');
|
||||
}
|
||||
try {
|
||||
if (\false !== ($scalar = $time->getTimestamp())) {
|
||||
return $scalar;
|
||||
}
|
||||
} catch (\ValueError $exception) {
|
||||
// no-op
|
||||
}
|
||||
return $time->format('U');
|
||||
}
|
||||
}
|
||||
return (string) $scalar;
|
||||
}
|
||||
private static function parseTag(string $value, int &$i, int $flags) : ?string
|
||||
{
|
||||
if ('!' !== $value[$i]) {
|
||||
return null;
|
||||
}
|
||||
$tagLength = \strcspn($value, " \t\n[]{},", $i + 1);
|
||||
$tag = \substr($value, $i + 1, $tagLength);
|
||||
$nextOffset = $i + $tagLength + 1;
|
||||
$nextOffset += \strspn($value, ' ', $nextOffset);
|
||||
if ('' === $tag && (!isset($value[$nextOffset]) || \in_array($value[$nextOffset], [']', '}', ','], \true))) {
|
||||
throw new ParseException('Using the unquoted scalar value "!" is not supported. You must quote it.', self::$parsedLineNumber + 1, $value, self::$parsedFilename);
|
||||
}
|
||||
// Is followed by a scalar and is a built-in tag
|
||||
if ('' !== $tag && (!isset($value[$nextOffset]) || !\in_array($value[$nextOffset], ['[', '{'], \true)) && ('!' === $tag[0] || \in_array($tag, ['str', 'php/const', 'php/enum', 'php/object'], \true))) {
|
||||
// Manage in {@link self::evaluateScalar()}
|
||||
return null;
|
||||
}
|
||||
$i = $nextOffset;
|
||||
// Built-in tags
|
||||
if ('' !== $tag && '!' === $tag[0]) {
|
||||
throw new ParseException(\sprintf('The built-in tag "!%s" is not implemented.', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
|
||||
}
|
||||
if ('' !== $tag && !isset($value[$i])) {
|
||||
throw new ParseException(\sprintf('Missing value for tag "%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
|
||||
}
|
||||
if ('' === $tag || Yaml::PARSE_CUSTOM_TAGS & $flags) {
|
||||
return $tag;
|
||||
}
|
||||
throw new ParseException(\sprintf('Tags support is not enabled. Enable the "Yaml::PARSE_CUSTOM_TAGS" flag to use "!%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
|
||||
}
|
||||
public static function evaluateBinaryScalar(string $scalar) : string
|
||||
{
|
||||
$parsedBinaryData = self::parseScalar(\preg_replace('/\\s/', '', $scalar));
|
||||
if (0 !== \strlen($parsedBinaryData) % 4) {
|
||||
throw new ParseException(\sprintf('The normalized base64 encoded data (data without whitespace characters) length must be a multiple of four (%d bytes given).', \strlen($parsedBinaryData)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
if (!Parser::preg_match('#^[A-Z0-9+/]+={0,2}$#i', $parsedBinaryData)) {
|
||||
throw new ParseException(\sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
|
||||
}
|
||||
return \base64_decode($parsedBinaryData, \true);
|
||||
}
|
||||
private static function isBinaryString(string $value) : bool
|
||||
{
|
||||
return !\preg_match('//u', $value) || \preg_match('/[^\\x00\\x07-\\x0d\\x1B\\x20-\\xff]/', $value);
|
||||
}
|
||||
/**
|
||||
* Gets a regex that matches a YAML date.
|
||||
*
|
||||
* @see http://www.yaml.org/spec/1.2/spec.html#id2761573
|
||||
*/
|
||||
private static function getTimestampRegex() : string
|
||||
{
|
||||
return <<<EOF
|
||||
~^
|
||||
(?P<year>[0-9][0-9][0-9][0-9])
|
||||
-(?P<month>[0-9][0-9]?)
|
||||
-(?P<day>[0-9][0-9]?)
|
||||
(?:(?:[Tt]|[ \t]+)
|
||||
(?P<hour>[0-9][0-9]?)
|
||||
:(?P<minute>[0-9][0-9])
|
||||
:(?P<second>[0-9][0-9])
|
||||
(?:\\.(?P<fraction>[0-9]*))?
|
||||
(?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
|
||||
(?::(?P<tz_minute>[0-9][0-9]))?))?)?
|
||||
\$~x
|
||||
EOF;
|
||||
}
|
||||
/**
|
||||
* Gets a regex that matches a YAML number in hexadecimal notation.
|
||||
*/
|
||||
private static function getHexRegex() : string
|
||||
{
|
||||
return '~^0x[0-9a-f_]++$~i';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2004-present Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,13 @@
|
|||
Yaml Component
|
||||
==============
|
||||
|
||||
The Yaml component loads and dumps YAML files.
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* [Documentation](https://symfony.com/doc/current/components/yaml.html)
|
||||
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
||||
* [Report issues](https://github.com/symfony/symfony/issues) and
|
||||
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
||||
in the [main Symfony repository](https://github.com/symfony/symfony)
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
namespace RectorPrefix202402;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
if ('cli' !== \PHP_SAPI) {
|
||||
throw new \Exception('This script must be run from the command line.');
|
||||
}
|
||||
/**
|
||||
* Runs the Yaml lint command.
|
||||
*
|
||||
* @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
|
||||
*/
|
||||
use RectorPrefix202402\Symfony\Component\Console\Application;
|
||||
use RectorPrefix202402\Symfony\Component\Yaml\Command\LintCommand;
|
||||
function includeIfExists(string $file) : bool
|
||||
{
|
||||
return \file_exists($file) && (include $file);
|
||||
}
|
||||
if (!includeIfExists(__DIR__ . '/../../../../autoload.php') && !includeIfExists(__DIR__ . '/../../vendor/autoload.php') && !includeIfExists(__DIR__ . '/../../../../../../vendor/autoload.php')) {
|
||||
\fwrite(\STDERR, 'Install dependencies using Composer.' . \PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
if (!\class_exists(Application::class)) {
|
||||
\fwrite(\STDERR, 'You need the "symfony/console" component in order to run the Yaml linter.' . \PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
(new Application())->add($command = new LintCommand())->getApplication()->setDefaultCommand($command->getName(), \true)->run();
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml\Tag;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
* @author Guilhem N. <egetick@gmail.com>
|
||||
*/
|
||||
final class TaggedValue
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $tag;
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $value;
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __construct(string $tag, $value)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
$this->value = $value;
|
||||
}
|
||||
public function getTag() : string
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml;
|
||||
|
||||
use RectorPrefix202402\Symfony\Component\Yaml\Exception\ParseException;
|
||||
/**
|
||||
* Unescaper encapsulates unescaping rules for single and double-quoted
|
||||
* YAML strings.
|
||||
*
|
||||
* @author Matthew Lewinski <matthew@lewinski.org>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class Unescaper
|
||||
{
|
||||
/**
|
||||
* Regex fragment that matches an escaped character in a double quoted string.
|
||||
*/
|
||||
public const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)';
|
||||
/**
|
||||
* Unescapes a single quoted string.
|
||||
*
|
||||
* @param string $value A single quoted string
|
||||
*/
|
||||
public function unescapeSingleQuotedString(string $value) : string
|
||||
{
|
||||
return \str_replace('\'\'', '\'', $value);
|
||||
}
|
||||
/**
|
||||
* Unescapes a double quoted string.
|
||||
*
|
||||
* @param string $value A double quoted string
|
||||
*/
|
||||
public function unescapeDoubleQuotedString(string $value) : string
|
||||
{
|
||||
$callback = function ($match) {
|
||||
return $this->unescapeCharacter($match[0]);
|
||||
};
|
||||
// evaluate the string
|
||||
return \preg_replace_callback('/' . self::REGEX_ESCAPED_CHARACTER . '/u', $callback, $value);
|
||||
}
|
||||
/**
|
||||
* Unescapes a character that was found in a double-quoted string.
|
||||
*
|
||||
* @param string $value An escaped character
|
||||
*/
|
||||
private function unescapeCharacter(string $value) : string
|
||||
{
|
||||
switch ($value[1]) {
|
||||
case '0':
|
||||
return "\x00";
|
||||
case 'a':
|
||||
return "\x07";
|
||||
case 'b':
|
||||
return "\x08";
|
||||
case 't':
|
||||
return "\t";
|
||||
case "\t":
|
||||
return "\t";
|
||||
case 'n':
|
||||
return "\n";
|
||||
case 'v':
|
||||
return "\v";
|
||||
case 'f':
|
||||
return "\f";
|
||||
case 'r':
|
||||
return "\r";
|
||||
case 'e':
|
||||
return "\x1b";
|
||||
case ' ':
|
||||
return ' ';
|
||||
case '"':
|
||||
return '"';
|
||||
case '/':
|
||||
return '/';
|
||||
case '\\':
|
||||
return '\\';
|
||||
case 'N':
|
||||
return "
";
|
||||
case '_':
|
||||
return " ";
|
||||
case 'L':
|
||||
return "
";
|
||||
case 'P':
|
||||
return "
";
|
||||
case 'x':
|
||||
return self::utf8chr(\hexdec(\substr($value, 2, 2)));
|
||||
case 'u':
|
||||
return self::utf8chr(\hexdec(\substr($value, 2, 4)));
|
||||
case 'U':
|
||||
return self::utf8chr(\hexdec(\substr($value, 2, 8)));
|
||||
default:
|
||||
throw new ParseException(\sprintf('Found unknown escape character "%s".', $value));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the UTF-8 character for the given code point.
|
||||
*/
|
||||
private static function utf8chr(int $c) : string
|
||||
{
|
||||
if (0x80 > ($c %= 0x200000)) {
|
||||
return \chr($c);
|
||||
}
|
||||
if (0x800 > $c) {
|
||||
return \chr(0xc0 | $c >> 6) . \chr(0x80 | $c & 0x3f);
|
||||
}
|
||||
if (0x10000 > $c) {
|
||||
return \chr(0xe0 | $c >> 12) . \chr(0x80 | $c >> 6 & 0x3f) . \chr(0x80 | $c & 0x3f);
|
||||
}
|
||||
return \chr(0xf0 | $c >> 18) . \chr(0x80 | $c >> 12 & 0x3f) . \chr(0x80 | $c >> 6 & 0x3f) . \chr(0x80 | $c & 0x3f);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace RectorPrefix202402\Symfony\Component\Yaml;
|
||||
|
||||
use RectorPrefix202402\Symfony\Component\Yaml\Exception\ParseException;
|
||||
/**
|
||||
* Yaml offers convenience methods to load and dump YAML.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class Yaml
|
||||
{
|
||||
public const DUMP_OBJECT = 1;
|
||||
public const PARSE_EXCEPTION_ON_INVALID_TYPE = 2;
|
||||
public const PARSE_OBJECT = 4;
|
||||
public const PARSE_OBJECT_FOR_MAP = 8;
|
||||
public const DUMP_EXCEPTION_ON_INVALID_TYPE = 16;
|
||||
public const PARSE_DATETIME = 32;
|
||||
public const DUMP_OBJECT_AS_MAP = 64;
|
||||
public const DUMP_MULTI_LINE_LITERAL_BLOCK = 128;
|
||||
public const PARSE_CONSTANT = 256;
|
||||
public const PARSE_CUSTOM_TAGS = 512;
|
||||
public const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024;
|
||||
public const DUMP_NULL_AS_TILDE = 2048;
|
||||
public const DUMP_NUMERIC_KEY_AS_STRING = 4096;
|
||||
/**
|
||||
* Parses a YAML file into a PHP value.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* $array = Yaml::parseFile('config.yml');
|
||||
* print_r($array);
|
||||
*
|
||||
* @param string $filename The path to the YAML file to be parsed
|
||||
* @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
|
||||
*
|
||||
* @throws ParseException If the file could not be read or the YAML is not valid
|
||||
* @return mixed
|
||||
*/
|
||||
public static function parseFile(string $filename, int $flags = 0)
|
||||
{
|
||||
$yaml = new Parser();
|
||||
return $yaml->parseFile($filename, $flags);
|
||||
}
|
||||
/**
|
||||
* Parses YAML into a PHP value.
|
||||
*
|
||||
* Usage:
|
||||
* <code>
|
||||
* $array = Yaml::parse(file_get_contents('config.yml'));
|
||||
* print_r($array);
|
||||
* </code>
|
||||
*
|
||||
* @param string $input A string containing YAML
|
||||
* @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
|
||||
*
|
||||
* @throws ParseException If the YAML is not valid
|
||||
* @return mixed
|
||||
*/
|
||||
public static function parse(string $input, int $flags = 0)
|
||||
{
|
||||
$yaml = new Parser();
|
||||
return $yaml->parse($input, $flags);
|
||||
}
|
||||
/**
|
||||
* Dumps a PHP value to a YAML string.
|
||||
*
|
||||
* The dump method, when supplied with an array, will do its best
|
||||
* to convert the array into friendly YAML.
|
||||
*
|
||||
* @param mixed $input The PHP value
|
||||
* @param int $inline The level where you switch to inline YAML
|
||||
* @param int $indent The amount of spaces to use for indentation of nested nodes
|
||||
* @param int $flags A bit field of DUMP_* constants to customize the dumped YAML string
|
||||
*/
|
||||
public static function dump($input, int $inline = 2, int $indent = 4, int $flags = 0) : string
|
||||
{
|
||||
$yaml = new Dumper($indent);
|
||||
return $yaml->dump($input, $inline, 0, $flags);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "symfony\/yaml",
|
||||
"type": "library",
|
||||
"description": "Loads and dumps YAML files",
|
||||
"keywords": [],
|
||||
"homepage": "https:\/\/symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https:\/\/symfony.com\/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"symfony\/deprecation-contracts": "^2.5|^3",
|
||||
"symfony\/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony\/console": "^5.4|^6.0|^7.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony\/console": "<5.4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"RectorPrefix202402\\Symfony\\Component\\Yaml\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"\/Tests\/"
|
||||
]
|
||||
},
|
||||
"bin": [
|
||||
"Resources\/bin\/yaml-lint"
|
||||
],
|
||||
"minimum-stability": "dev"
|
||||
}
|
Loading…
Reference in New Issue