diff options
author | Andrew Dolgov <[email protected]> | 2022-03-22 12:24:31 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2022-03-22 12:24:31 +0300 |
commit | 1c4f7ab3b838b23afb2ee4dab14acbf75956e952 (patch) | |
tree | 0a19274107d717efe92d2c0376cd3105fead5a11 /vendor/sebastian | |
parent | 711662948768492e8d05b778a7d80eacaec368d2 (diff) |
* add phpunit as a dev dependency
* add some basic tests for UrlHelper::rewrite_relative()
* fix UrlHelper::rewrite_relative() to work better on non-absolute
relative URL paths
Diffstat (limited to 'vendor/sebastian')
192 files changed, 14405 insertions, 0 deletions
diff --git a/vendor/sebastian/cli-parser/ChangeLog.md b/vendor/sebastian/cli-parser/ChangeLog.md new file mode 100644 index 000000000..9431ec594 --- /dev/null +++ b/vendor/sebastian/cli-parser/ChangeLog.md @@ -0,0 +1,15 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. + +## [1.0.1] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [1.0.0] - 2020-08-12 + +* Initial release + +[1.0.0]: https://github.com/sebastianbergmann/cli-parser/compare/bb7bb3297957927962b0a3335befe7b66f7462e9...1.0.0 diff --git a/vendor/sebastian/cli-parser/LICENSE b/vendor/sebastian/cli-parser/LICENSE new file mode 100644 index 000000000..0e33c0591 --- /dev/null +++ b/vendor/sebastian/cli-parser/LICENSE @@ -0,0 +1,33 @@ +sebastian/cli-parser + +Copyright (c) 2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/cli-parser/README.md b/vendor/sebastian/cli-parser/README.md new file mode 100644 index 000000000..39c17a72c --- /dev/null +++ b/vendor/sebastian/cli-parser/README.md @@ -0,0 +1,17 @@ +# sebastian/cli-parser + +Library for parsing `$_SERVER['argv']`, extracted from `phpunit/phpunit`. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/cli-parser +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/cli-parser +``` diff --git a/vendor/sebastian/cli-parser/composer.json b/vendor/sebastian/cli-parser/composer.json new file mode 100644 index 000000000..34c376f91 --- /dev/null +++ b/vendor/sebastian/cli-parser/composer.json @@ -0,0 +1,41 @@ +{ + "name": "sebastian/cli-parser", + "description": "Library for parsing CLI options", + "type": "library", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues" + }, + "prefer-stable": true, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + } +} diff --git a/vendor/sebastian/cli-parser/infection.json b/vendor/sebastian/cli-parser/infection.json new file mode 100644 index 000000000..09546514f --- /dev/null +++ b/vendor/sebastian/cli-parser/infection.json @@ -0,0 +1,12 @@ +{ + "source": { + "directories": [ + "src" + ] + }, + "mutators": { + "@default": true + }, + "minMsi": 100, + "minCoveredMsi": 100 +} diff --git a/vendor/sebastian/cli-parser/src/Parser.php b/vendor/sebastian/cli-parser/src/Parser.php new file mode 100644 index 000000000..a4f728bc6 --- /dev/null +++ b/vendor/sebastian/cli-parser/src/Parser.php @@ -0,0 +1,204 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/cli-parser. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CliParser; + +use function array_map; +use function array_merge; +use function array_shift; +use function array_slice; +use function assert; +use function count; +use function current; +use function explode; +use function is_array; +use function is_int; +use function is_string; +use function key; +use function next; +use function preg_replace; +use function reset; +use function sort; +use function strlen; +use function strpos; +use function strstr; +use function substr; + +final class Parser +{ + /** + * @psalm-param list<string> $argv + * @psalm-param list<string> $longOptions + * + * @throws AmbiguousOptionException + * @throws RequiredOptionArgumentMissingException + * @throws OptionDoesNotAllowArgumentException + * @throws UnknownOptionException + */ + public function parse(array $argv, string $shortOptions, array $longOptions = null): array + { + if (empty($argv)) { + return [[], []]; + } + + $options = []; + $nonOptions = []; + + if ($longOptions) { + sort($longOptions); + } + + if (isset($argv[0][0]) && $argv[0][0] !== '-') { + array_shift($argv); + } + + reset($argv); + + $argv = array_map('trim', $argv); + + while (false !== $arg = current($argv)) { + $i = key($argv); + + assert(is_int($i)); + + next($argv); + + if ($arg === '') { + continue; + } + + if ($arg === '--') { + $nonOptions = array_merge($nonOptions, array_slice($argv, $i + 1)); + + break; + } + + if ($arg[0] !== '-' || (strlen($arg) > 1 && $arg[1] === '-' && !$longOptions)) { + $nonOptions[] = $arg; + + continue; + } + + if (strlen($arg) > 1 && $arg[1] === '-' && is_array($longOptions)) { + $this->parseLongOption( + substr($arg, 2), + $longOptions, + $options, + $argv + ); + } else { + $this->parseShortOption( + substr($arg, 1), + $shortOptions, + $options, + $argv + ); + } + } + + return [$options, $nonOptions]; + } + + /** + * @throws RequiredOptionArgumentMissingException + */ + private function parseShortOption(string $arg, string $shortOptions, array &$opts, array &$args): void + { + $argLength = strlen($arg); + + for ($i = 0; $i < $argLength; $i++) { + $option = $arg[$i]; + $optionArgument = null; + + if ($arg[$i] === ':' || ($spec = strstr($shortOptions, $option)) === false) { + throw new UnknownOptionException('-' . $option); + } + + assert(is_string($spec)); + + if (strlen($spec) > 1 && $spec[1] === ':') { + if ($i + 1 < $argLength) { + $opts[] = [$option, substr($arg, $i + 1)]; + + break; + } + + if (!(strlen($spec) > 2 && $spec[2] === ':')) { + $optionArgument = current($args); + + if (!$optionArgument) { + throw new RequiredOptionArgumentMissingException('-' . $option); + } + + assert(is_string($optionArgument)); + + next($args); + } + } + + $opts[] = [$option, $optionArgument]; + } + } + + /** + * @psalm-param list<string> $longOptions + * + * @throws AmbiguousOptionException + * @throws RequiredOptionArgumentMissingException + * @throws OptionDoesNotAllowArgumentException + * @throws UnknownOptionException + */ + private function parseLongOption(string $arg, array $longOptions, array &$opts, array &$args): void + { + $count = count($longOptions); + $list = explode('=', $arg); + $option = $list[0]; + $optionArgument = null; + + if (count($list) > 1) { + $optionArgument = $list[1]; + } + + $optionLength = strlen($option); + + foreach ($longOptions as $i => $longOption) { + $opt_start = substr($longOption, 0, $optionLength); + + if ($opt_start !== $option) { + continue; + } + + $opt_rest = substr($longOption, $optionLength); + + if ($opt_rest !== '' && $i + 1 < $count && $option[0] !== '=' && strpos($longOptions[$i + 1], $option) === 0) { + throw new AmbiguousOptionException('--' . $option); + } + + if (substr($longOption, -1) === '=') { + /* @noinspection StrlenInEmptyStringCheckContextInspection */ + if (substr($longOption, -2) !== '==' && !strlen((string) $optionArgument)) { + if (false === $optionArgument = current($args)) { + throw new RequiredOptionArgumentMissingException('--' . $option); + } + + next($args); + } + } elseif ($optionArgument) { + throw new OptionDoesNotAllowArgumentException('--' . $option); + } + + $fullOption = '--' . preg_replace('/={1,2}$/', '', $longOption); + $opts[] = [$fullOption, $optionArgument]; + + return; + } + + throw new UnknownOptionException('--' . $option); + } +} diff --git a/vendor/sebastian/cli-parser/src/exceptions/AmbiguousOptionException.php b/vendor/sebastian/cli-parser/src/exceptions/AmbiguousOptionException.php new file mode 100644 index 000000000..a99f63697 --- /dev/null +++ b/vendor/sebastian/cli-parser/src/exceptions/AmbiguousOptionException.php @@ -0,0 +1,26 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/cli-parser. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CliParser; + +use function sprintf; +use RuntimeException; + +final class AmbiguousOptionException extends RuntimeException implements Exception +{ + public function __construct(string $option) + { + parent::__construct( + sprintf( + 'Option "%s" is ambiguous', + $option + ) + ); + } +} diff --git a/vendor/sebastian/cli-parser/src/exceptions/Exception.php b/vendor/sebastian/cli-parser/src/exceptions/Exception.php new file mode 100644 index 000000000..f35ad2457 --- /dev/null +++ b/vendor/sebastian/cli-parser/src/exceptions/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/cli-parser. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CliParser; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/cli-parser/src/exceptions/OptionDoesNotAllowArgumentException.php b/vendor/sebastian/cli-parser/src/exceptions/OptionDoesNotAllowArgumentException.php new file mode 100644 index 000000000..0aad29ac0 --- /dev/null +++ b/vendor/sebastian/cli-parser/src/exceptions/OptionDoesNotAllowArgumentException.php @@ -0,0 +1,26 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/cli-parser. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CliParser; + +use function sprintf; +use RuntimeException; + +final class OptionDoesNotAllowArgumentException extends RuntimeException implements Exception +{ + public function __construct(string $option) + { + parent::__construct( + sprintf( + 'Option "%s" does not allow an argument', + $option + ) + ); + } +} diff --git a/vendor/sebastian/cli-parser/src/exceptions/RequiredOptionArgumentMissingException.php b/vendor/sebastian/cli-parser/src/exceptions/RequiredOptionArgumentMissingException.php new file mode 100644 index 000000000..d2a930b62 --- /dev/null +++ b/vendor/sebastian/cli-parser/src/exceptions/RequiredOptionArgumentMissingException.php @@ -0,0 +1,26 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/cli-parser. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CliParser; + +use function sprintf; +use RuntimeException; + +final class RequiredOptionArgumentMissingException extends RuntimeException implements Exception +{ + public function __construct(string $option) + { + parent::__construct( + sprintf( + 'Required argument for option "%s" is missing', + $option + ) + ); + } +} diff --git a/vendor/sebastian/cli-parser/src/exceptions/UnknownOptionException.php b/vendor/sebastian/cli-parser/src/exceptions/UnknownOptionException.php new file mode 100644 index 000000000..e98d9fd02 --- /dev/null +++ b/vendor/sebastian/cli-parser/src/exceptions/UnknownOptionException.php @@ -0,0 +1,26 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/cli-parser. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CliParser; + +use function sprintf; +use RuntimeException; + +final class UnknownOptionException extends RuntimeException implements Exception +{ + public function __construct(string $option) + { + parent::__construct( + sprintf( + 'Unknown option "%s"', + $option + ) + ); + } +} diff --git a/vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md b/vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md new file mode 100644 index 000000000..43a5db90d --- /dev/null +++ b/vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md @@ -0,0 +1,38 @@ +# Change Log + +All notable changes to `sebastianbergmann/code-unit-reverse-lookup` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [2.0.3] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [2.0.2] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [2.0.1] - 2020-06-15 + +### Changed + +* Tests etc. are now ignored for archive exports + +## 2.0.0 - 2020-02-07 + +### Removed + +* This component is no longer supported on PHP 5.6, PHP 7.0, PHP 7.1, and PHP 7.2 + +## 1.0.0 - 2016-02-13 + +### Added + +* Initial release + +[2.0.3]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/2.0.2...2.0.3 +[2.0.2]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/2.0.1...2.0.2 +[2.0.1]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/sebastianbergmann/code-unit-reverse-lookup/compare/1.0.0...2.0.0 diff --git a/vendor/sebastian/code-unit-reverse-lookup/LICENSE b/vendor/sebastian/code-unit-reverse-lookup/LICENSE new file mode 100644 index 000000000..dc4bf7019 --- /dev/null +++ b/vendor/sebastian/code-unit-reverse-lookup/LICENSE @@ -0,0 +1,33 @@ +code-unit-reverse-lookup + +Copyright (c) 2016-2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/code-unit-reverse-lookup/README.md b/vendor/sebastian/code-unit-reverse-lookup/README.md new file mode 100644 index 000000000..1c0ca235e --- /dev/null +++ b/vendor/sebastian/code-unit-reverse-lookup/README.md @@ -0,0 +1,20 @@ +# sebastian/code-unit-reverse-lookup + +[![CI Status](https://github.com/sebastianbergmann/code-unit-reverse-lookup/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/code-unit-reverse-lookup/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/code-unit-reverse-lookup/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/code-unit-reverse-lookup) + +Looks up which function or method a line of code belongs to. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/code-unit-reverse-lookup +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/code-unit-reverse-lookup +``` diff --git a/vendor/sebastian/code-unit-reverse-lookup/composer.json b/vendor/sebastian/code-unit-reverse-lookup/composer.json new file mode 100644 index 000000000..cff96167a --- /dev/null +++ b/vendor/sebastian/code-unit-reverse-lookup/composer.json @@ -0,0 +1,36 @@ +{ + "name": "sebastian/code-unit-reverse-lookup", + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]" + } + ], + "prefer-stable": true, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + } +} diff --git a/vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php b/vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php new file mode 100644 index 000000000..35de53981 --- /dev/null +++ b/vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php @@ -0,0 +1,125 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit-reverse-lookup. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnitReverseLookup; + +use function array_merge; +use function assert; +use function get_declared_classes; +use function get_declared_traits; +use function get_defined_functions; +use function is_array; +use function range; +use ReflectionClass; +use ReflectionFunction; +use ReflectionFunctionAbstract; +use ReflectionMethod; + +/** + * @since Class available since Release 1.0.0 + */ +class Wizard +{ + /** + * @var array + */ + private $lookupTable = []; + + /** + * @var array + */ + private $processedClasses = []; + + /** + * @var array + */ + private $processedFunctions = []; + + /** + * @param string $filename + * @param int $lineNumber + * + * @return string + */ + public function lookup($filename, $lineNumber) + { + if (!isset($this->lookupTable[$filename][$lineNumber])) { + $this->updateLookupTable(); + } + + if (isset($this->lookupTable[$filename][$lineNumber])) { + return $this->lookupTable[$filename][$lineNumber]; + } + + return $filename . ':' . $lineNumber; + } + + private function updateLookupTable(): void + { + $this->processClassesAndTraits(); + $this->processFunctions(); + } + + private function processClassesAndTraits(): void + { + $classes = get_declared_classes(); + $traits = get_declared_traits(); + + assert(is_array($classes)); + assert(is_array($traits)); + + foreach (array_merge($classes, $traits) as $classOrTrait) { + if (isset($this->processedClasses[$classOrTrait])) { + continue; + } + + $reflector = new ReflectionClass($classOrTrait); + + foreach ($reflector->getMethods() as $method) { + $this->processFunctionOrMethod($method); + } + + $this->processedClasses[$classOrTrait] = true; + } + } + + private function processFunctions(): void + { + foreach (get_defined_functions()['user'] as $function) { + if (isset($this->processedFunctions[$function])) { + continue; + } + + $this->processFunctionOrMethod(new ReflectionFunction($function)); + + $this->processedFunctions[$function] = true; + } + } + + private function processFunctionOrMethod(ReflectionFunctionAbstract $functionOrMethod): void + { + if ($functionOrMethod->isInternal()) { + return; + } + + $name = $functionOrMethod->getName(); + + if ($functionOrMethod instanceof ReflectionMethod) { + $name = $functionOrMethod->getDeclaringClass()->getName() . '::' . $name; + } + + if (!isset($this->lookupTable[$functionOrMethod->getFileName()])) { + $this->lookupTable[$functionOrMethod->getFileName()] = []; + } + + foreach (range($functionOrMethod->getStartLine(), $functionOrMethod->getEndLine()) as $line) { + $this->lookupTable[$functionOrMethod->getFileName()][$line] = $name; + } + } +} diff --git a/vendor/sebastian/code-unit/.psalm/baseline.xml b/vendor/sebastian/code-unit/.psalm/baseline.xml new file mode 100644 index 000000000..e44889190 --- /dev/null +++ b/vendor/sebastian/code-unit/.psalm/baseline.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44"> + <file src="src/Mapper.php"> + <ArgumentTypeCoercion occurrences="16"> + <code>$firstPart</code> + <code>$firstPart</code> + <code>$firstPart</code> + <code>$firstPart</code> + <code>$firstPart</code> + <code>$firstPart</code> + <code>$firstPart</code> + <code>$firstPart</code> + <code>$firstPart</code> + <code>$secondPart</code> + <code>$unit</code> + <code>$unit</code> + <code>$unit</code> + <code>$unit</code> + <code>$unit</code> + <code>$unit</code> + </ArgumentTypeCoercion> + </file> +</files> diff --git a/vendor/sebastian/code-unit/.psalm/config.xml b/vendor/sebastian/code-unit/.psalm/config.xml new file mode 100644 index 000000000..a39e9a4c3 --- /dev/null +++ b/vendor/sebastian/code-unit/.psalm/config.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<psalm + totallyTyped="true" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="https://getpsalm.org/schema/config" + xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" + resolveFromConfigFile="false" + errorBaseline=".psalm/baseline.xml" +> + <projectFiles> + <directory name="src" /> + <ignoreFiles> + <directory name="vendor" /> + </ignoreFiles> + </projectFiles> +</psalm> diff --git a/vendor/sebastian/code-unit/ChangeLog.md b/vendor/sebastian/code-unit/ChangeLog.md new file mode 100644 index 000000000..0978e651e --- /dev/null +++ b/vendor/sebastian/code-unit/ChangeLog.md @@ -0,0 +1,65 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [1.0.8] - 2020-10-26 + +### Fixed + +* `SebastianBergmann\CodeUnit\Exception` now correctly extends `\Throwable` + +## [1.0.7] - 2020-10-02 + +### Fixed + +* `SebastianBergmann\CodeUnit\Mapper::stringToCodeUnits()` no longer attempts to create `CodeUnit` objects for code units that are not declared in userland + +## [1.0.6] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [1.0.5] - 2020-06-26 + +### Fixed + +* [#3](https://github.com/sebastianbergmann/code-unit/issues/3): Regression in 1.0.4 + +## [1.0.4] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [1.0.3] - 2020-06-15 + +### Changed + +* Tests etc. are now ignored for archive exports + +## [1.0.2] - 2020-04-30 + +### Fixed + +* `Mapper::stringToCodeUnits()` raised the wrong exception for `Class::method` when a class named `Class` exists but does not have a method named `method` + +## [1.0.1] - 2020-04-27 + +### Fixed + +* [#2](https://github.com/sebastianbergmann/code-unit/issues/2): `Mapper::stringToCodeUnits()` breaks when `ClassName<extended>` is used for class that extends built-in class + +## [1.0.0] - 2020-03-30 + +* Initial release + +[1.0.8]: https://github.com/sebastianbergmann/code-unit/compare/1.0.7...1.0.8 +[1.0.7]: https://github.com/sebastianbergmann/code-unit/compare/1.0.6...1.0.7 +[1.0.6]: https://github.com/sebastianbergmann/code-unit/compare/1.0.5...1.0.6 +[1.0.5]: https://github.com/sebastianbergmann/code-unit/compare/1.0.4...1.0.5 +[1.0.4]: https://github.com/sebastianbergmann/code-unit/compare/1.0.3...1.0.4 +[1.0.3]: https://github.com/sebastianbergmann/code-unit/compare/1.0.2...1.0.3 +[1.0.2]: https://github.com/sebastianbergmann/code-unit/compare/1.0.1...1.0.2 +[1.0.1]: https://github.com/sebastianbergmann/code-unit/compare/1.0.0...1.0.1 +[1.0.0]: https://github.com/sebastianbergmann/code-unit/compare/530c3900e5db9bcb8516da545bef0d62536cedaa...1.0.0 diff --git a/vendor/sebastian/code-unit/LICENSE b/vendor/sebastian/code-unit/LICENSE new file mode 100644 index 000000000..b99bc8ac4 --- /dev/null +++ b/vendor/sebastian/code-unit/LICENSE @@ -0,0 +1,33 @@ +sebastian/code-unit + +Copyright (c) 2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/code-unit/README.md b/vendor/sebastian/code-unit/README.md new file mode 100644 index 000000000..d20227a9b --- /dev/null +++ b/vendor/sebastian/code-unit/README.md @@ -0,0 +1,17 @@ +# sebastian/code-unit + +Collection of value objects that represent the PHP code units. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/code-unit +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/code-unit +``` diff --git a/vendor/sebastian/code-unit/composer.json b/vendor/sebastian/code-unit/composer.json new file mode 100644 index 000000000..5b86ec589 --- /dev/null +++ b/vendor/sebastian/code-unit/composer.json @@ -0,0 +1,50 @@ +{ + "name": "sebastian/code-unit", + "description": "Collection of value objects that represent the PHP code units", + "type": "library", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues" + }, + "prefer-stable": true, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "autoload-dev": { + "classmap": [ + "tests/_fixture" + ], + "files": [ + "tests/_fixture/file_with_multiple_code_units.php", + "tests/_fixture/function.php" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + } +} diff --git a/vendor/sebastian/code-unit/src/ClassMethodUnit.php b/vendor/sebastian/code-unit/src/ClassMethodUnit.php new file mode 100644 index 000000000..f9ddac29e --- /dev/null +++ b/vendor/sebastian/code-unit/src/ClassMethodUnit.php @@ -0,0 +1,24 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +/** + * @psalm-immutable + */ +final class ClassMethodUnit extends CodeUnit +{ + /** + * @psalm-assert-if-true ClassMethodUnit $this + */ + public function isClassMethod(): bool + { + return true; + } +} diff --git a/vendor/sebastian/code-unit/src/ClassUnit.php b/vendor/sebastian/code-unit/src/ClassUnit.php new file mode 100644 index 000000000..3ba0ee661 --- /dev/null +++ b/vendor/sebastian/code-unit/src/ClassUnit.php @@ -0,0 +1,24 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +/** + * @psalm-immutable + */ +final class ClassUnit extends CodeUnit +{ + /** + * @psalm-assert-if-true ClassUnit $this + */ + public function isClass(): bool + { + return true; + } +} diff --git a/vendor/sebastian/code-unit/src/CodeUnit.php b/vendor/sebastian/code-unit/src/CodeUnit.php new file mode 100644 index 000000000..9e5cceb35 --- /dev/null +++ b/vendor/sebastian/code-unit/src/CodeUnit.php @@ -0,0 +1,445 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +use function range; +use function sprintf; +use ReflectionClass; +use ReflectionFunction; +use ReflectionMethod; + +/** + * @psalm-immutable + */ +abstract class CodeUnit +{ + /** + * @var string + */ + private $name; + + /** + * @var string + */ + private $sourceFileName; + + /** + * @var array + * @psalm-var list<int> + */ + private $sourceLines; + + /** + * @psalm-param class-string $className + * + * @throws InvalidCodeUnitException + * @throws ReflectionException + */ + public static function forClass(string $className): ClassUnit + { + self::ensureUserDefinedClass($className); + + $reflector = self::reflectorForClass($className); + + return new ClassUnit( + $className, + $reflector->getFileName(), + range( + $reflector->getStartLine(), + $reflector->getEndLine() + ) + ); + } + + /** + * @psalm-param class-string $className + * + * @throws InvalidCodeUnitException + * @throws ReflectionException + */ + public static function forClassMethod(string $className, string $methodName): ClassMethodUnit + { + self::ensureUserDefinedClass($className); + + $reflector = self::reflectorForClassMethod($className, $methodName); + + return new ClassMethodUnit( + $className . '::' . $methodName, + $reflector->getFileName(), + range( + $reflector->getStartLine(), + $reflector->getEndLine() + ) + ); + } + + /** + * @psalm-param class-string $interfaceName + * + * @throws InvalidCodeUnitException + * @throws ReflectionException + */ + public static function forInterface(string $interfaceName): InterfaceUnit + { + self::ensureUserDefinedInterface($interfaceName); + + $reflector = self::reflectorForClass($interfaceName); + + return new InterfaceUnit( + $interfaceName, + $reflector->getFileName(), + range( + $reflector->getStartLine(), + $reflector->getEndLine() + ) + ); + } + + /** + * @psalm-param class-string $interfaceName + * + * @throws InvalidCodeUnitException + * @throws ReflectionException + */ + public static function forInterfaceMethod(string $interfaceName, string $methodName): InterfaceMethodUnit + { + self::ensureUserDefinedInterface($interfaceName); + + $reflector = self::reflectorForClassMethod($interfaceName, $methodName); + + return new InterfaceMethodUnit( + $interfaceName . '::' . $methodName, + $reflector->getFileName(), + range( + $reflector->getStartLine(), + $reflector->getEndLine() + ) + ); + } + + /** + * @psalm-param class-string $traitName + * + * @throws InvalidCodeUnitException + * @throws ReflectionException + */ + public static function forTrait(string $traitName): TraitUnit + { + self::ensureUserDefinedTrait($traitName); + + $reflector = self::reflectorForClass($traitName); + + return new TraitUnit( + $traitName, + $reflector->getFileName(), + range( + $reflector->getStartLine(), + $reflector->getEndLine() + ) + ); + } + + /** + * @psalm-param class-string $traitName + * + * @throws InvalidCodeUnitException + * @throws ReflectionException + */ + public static function forTraitMethod(string $traitName, string $methodName): TraitMethodUnit + { + self::ensureUserDefinedTrait($traitName); + + $reflector = self::reflectorForClassMethod($traitName, $methodName); + + return new TraitMethodUnit( + $traitName . '::' . $methodName, + $reflector->getFileName(), + range( + $reflector->getStartLine(), + $reflector->getEndLine() + ) + ); + } + + /** + * @psalm-param callable-string $functionName + * + * @throws InvalidCodeUnitException + * @throws ReflectionException + */ + public static function forFunction(string $functionName): FunctionUnit + { + $reflector = self::reflectorForFunction($functionName); + + if (!$reflector->isUserDefined()) { + throw new InvalidCodeUnitException( + sprintf( + '"%s" is not a user-defined function', + $functionName + ) + ); + } + + return new FunctionUnit( + $functionName, + $reflector->getFileName(), + range( + $reflector->getStartLine(), + $reflector->getEndLine() + ) + ); + } + + /** + * @psalm-param list<int> $sourceLines + */ + private function __construct(string $name, string $sourceFileName, array $sourceLines) + { + $this->name = $name; + $this->sourceFileName = $sourceFileName; + $this->sourceLines = $sourceLines; + } + + public function name(): string + { + return $this->name; + } + + public function sourceFileName(): string + { + return $this->sourceFileName; + } + + /** + * @psalm-return list<int> + */ + public function sourceLines(): array + { + return $this->sourceLines; + } + + public function isClass(): bool + { + return false; + } + + public function isClassMethod(): bool + { + return false; + } + + public function isInterface(): bool + { + return false; + } + + public function isInterfaceMethod(): bool + { + return false; + } + + public function isTrait(): bool + { + return false; + } + + public function isTraitMethod(): bool + { + return false; + } + + public function isFunction(): bool + { + return false; + } + + /** + * @psalm-param class-string $className + * + * @throws InvalidCodeUnitException + */ + private static function ensureUserDefinedClass(string $className): void + { + try { + $reflector = new ReflectionClass($className); + + if ($reflector->isInterface()) { + throw new InvalidCodeUnitException( + sprintf( + '"%s" is an interface and not a class', + $className + ) + ); + } + + if ($reflector->isTrait()) { + throw new InvalidCodeUnitException( + sprintf( + '"%s" is a trait and not a class', + $className + ) + ); + } + + if (!$reflector->isUserDefined()) { + throw new InvalidCodeUnitException( + sprintf( + '"%s" is not a user-defined class', + $className + ) + ); + } + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @psalm-param class-string $interfaceName + * + * @throws InvalidCodeUnitException + */ + private static function ensureUserDefinedInterface(string $interfaceName): void + { + try { + $reflector = new ReflectionClass($interfaceName); + + if (!$reflector->isInterface()) { + throw new InvalidCodeUnitException( + sprintf( + '"%s" is not an interface', + $interfaceName + ) + ); + } + + if (!$reflector->isUserDefined()) { + throw new InvalidCodeUnitException( + sprintf( + '"%s" is not a user-defined interface', + $interfaceName + ) + ); + } + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @psalm-param class-string $traitName + * + * @throws InvalidCodeUnitException + */ + private static function ensureUserDefinedTrait(string $traitName): void + { + try { + $reflector = new ReflectionClass($traitName); + + if (!$reflector->isTrait()) { + throw new InvalidCodeUnitException( + sprintf( + '"%s" is not a trait', + $traitName + ) + ); + } + + // @codeCoverageIgnoreStart + if (!$reflector->isUserDefined()) { + throw new InvalidCodeUnitException( + sprintf( + '"%s" is not a user-defined trait', + $traitName + ) + ); + } + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private static function reflectorForClass(string $className): ReflectionClass + { + try { + return new ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private static function reflectorForClassMethod(string $className, string $methodName): ReflectionMethod + { + try { + return new ReflectionMethod($className, $methodName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @psalm-param callable-string $functionName + * + * @throws ReflectionException + */ + private static function reflectorForFunction(string $functionName): ReflectionFunction + { + try { + return new ReflectionFunction($functionName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } +} diff --git a/vendor/sebastian/code-unit/src/CodeUnitCollection.php b/vendor/sebastian/code-unit/src/CodeUnitCollection.php new file mode 100644 index 000000000..f53db8a12 --- /dev/null +++ b/vendor/sebastian/code-unit/src/CodeUnitCollection.php @@ -0,0 +1,84 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +use function array_merge; +use function count; +use Countable; +use IteratorAggregate; + +final class CodeUnitCollection implements Countable, IteratorAggregate +{ + /** + * @psalm-var list<CodeUnit> + */ + private $codeUnits = []; + + /** + * @psalm-param list<CodeUnit> $items + */ + public static function fromArray(array $items): self + { + $collection = new self; + + foreach ($items as $item) { + $collection->add($item); + } + + return $collection; + } + + public static function fromList(CodeUnit ...$items): self + { + return self::fromArray($items); + } + + private function __construct() + { + } + + /** + * @psalm-return list<CodeUnit> + */ + public function asArray(): array + { + return $this->codeUnits; + } + + public function getIterator(): CodeUnitCollectionIterator + { + return new CodeUnitCollectionIterator($this); + } + + public function count(): int + { + return count($this->codeUnits); + } + + public function isEmpty(): bool + { + return empty($this->codeUnits); + } + + public function mergeWith(self $other): self + { + return self::fromArray( + array_merge( + $this->asArray(), + $other->asArray() + ) + ); + } + + private function add(CodeUnit $item): void + { + $this->codeUnits[] = $item; + } +} diff --git a/vendor/sebastian/code-unit/src/CodeUnitCollectionIterator.php b/vendor/sebastian/code-unit/src/CodeUnitCollectionIterator.php new file mode 100644 index 000000000..bdc86d888 --- /dev/null +++ b/vendor/sebastian/code-unit/src/CodeUnitCollectionIterator.php @@ -0,0 +1,55 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +use Iterator; + +final class CodeUnitCollectionIterator implements Iterator +{ + /** + * @psalm-var list<CodeUnit> + */ + private $codeUnits; + + /** + * @var int + */ + private $position = 0; + + public function __construct(CodeUnitCollection $collection) + { + $this->codeUnits = $collection->asArray(); + } + + public function rewind(): void + { + $this->position = 0; + } + + public function valid(): bool + { + return isset($this->codeUnits[$this->position]); + } + + public function key(): int + { + return $this->position; + } + + public function current(): CodeUnit + { + return $this->codeUnits[$this->position]; + } + + public function next(): void + { + $this->position++; + } +} diff --git a/vendor/sebastian/code-unit/src/FunctionUnit.php b/vendor/sebastian/code-unit/src/FunctionUnit.php new file mode 100644 index 000000000..df76cf195 --- /dev/null +++ b/vendor/sebastian/code-unit/src/FunctionUnit.php @@ -0,0 +1,24 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +/** + * @psalm-immutable + */ +final class FunctionUnit extends CodeUnit +{ + /** + * @psalm-assert-if-true FunctionUnit $this + */ + public function isFunction(): bool + { + return true; + } +} diff --git a/vendor/sebastian/code-unit/src/InterfaceMethodUnit.php b/vendor/sebastian/code-unit/src/InterfaceMethodUnit.php new file mode 100644 index 000000000..fcd44f41a --- /dev/null +++ b/vendor/sebastian/code-unit/src/InterfaceMethodUnit.php @@ -0,0 +1,24 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +/** + * @psalm-immutable + */ +final class InterfaceMethodUnit extends CodeUnit +{ + /** + * @psalm-assert-if-true InterfaceMethod $this + */ + public function isInterfaceMethod(): bool + { + return true; + } +} diff --git a/vendor/sebastian/code-unit/src/InterfaceUnit.php b/vendor/sebastian/code-unit/src/InterfaceUnit.php new file mode 100644 index 000000000..5cf585bfd --- /dev/null +++ b/vendor/sebastian/code-unit/src/InterfaceUnit.php @@ -0,0 +1,24 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +/** + * @psalm-immutable + */ +final class InterfaceUnit extends CodeUnit +{ + /** + * @psalm-assert-if-true InterfaceUnit $this + */ + public function isInterface(): bool + { + return true; + } +} diff --git a/vendor/sebastian/code-unit/src/Mapper.php b/vendor/sebastian/code-unit/src/Mapper.php new file mode 100644 index 000000000..a72b3b0dd --- /dev/null +++ b/vendor/sebastian/code-unit/src/Mapper.php @@ -0,0 +1,414 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +use function array_keys; +use function array_merge; +use function array_unique; +use function array_values; +use function class_exists; +use function explode; +use function function_exists; +use function interface_exists; +use function ksort; +use function method_exists; +use function sort; +use function sprintf; +use function str_replace; +use function strpos; +use function trait_exists; +use ReflectionClass; +use ReflectionFunction; +use ReflectionMethod; + +final class Mapper +{ + /** + * @psalm-return array<string,list<int>> + */ + public function codeUnitsToSourceLines(CodeUnitCollection $codeUnits): array + { + $result = []; + + foreach ($codeUnits as $codeUnit) { + $sourceFileName = $codeUnit->sourceFileName(); + + if (!isset($result[$sourceFileName])) { + $result[$sourceFileName] = []; + } + + $result[$sourceFileName] = array_merge($result[$sourceFileName], $codeUnit->sourceLines()); + } + + foreach (array_keys($result) as $sourceFileName) { + $result[$sourceFileName] = array_values(array_unique($result[$sourceFileName])); + + sort($result[$sourceFileName]); + } + + ksort($result); + + return $result; + } + + /** + * @throws InvalidCodeUnitException + * @throws ReflectionException + */ + public function stringToCodeUnits(string $unit): CodeUnitCollection + { + if (strpos($unit, '::') !== false) { + [$firstPart, $secondPart] = explode('::', $unit); + + if (empty($firstPart) && $this->isUserDefinedFunction($secondPart)) { + return CodeUnitCollection::fromList(CodeUnit::forFunction($secondPart)); + } + + if ($this->isUserDefinedClass($firstPart)) { + if ($secondPart === '<public>') { + return $this->publicMethodsOfClass($firstPart); + } + + if ($secondPart === '<!public>') { + return $this->protectedAndPrivateMethodsOfClass($firstPart); + } + + if ($secondPart === '<protected>') { + return $this->protectedMethodsOfClass($firstPart); + } + + if ($secondPart === '<!protected>') { + return $this->publicAndPrivateMethodsOfClass($firstPart); + } + + if ($secondPart === '<private>') { + return $this->privateMethodsOfClass($firstPart); + } + + if ($secondPart === '<!private>') { + return $this->publicAndProtectedMethodsOfClass($firstPart); + } + + if ($this->isUserDefinedMethod($firstPart, $secondPart)) { + return CodeUnitCollection::fromList(CodeUnit::forClassMethod($firstPart, $secondPart)); + } + } + + if ($this->isUserDefinedInterface($firstPart)) { + return CodeUnitCollection::fromList(CodeUnit::forInterfaceMethod($firstPart, $secondPart)); + } + + if ($this->isUserDefinedTrait($firstPart)) { + return CodeUnitCollection::fromList(CodeUnit::forTraitMethod($firstPart, $secondPart)); + } + } else { + if ($this->isUserDefinedClass($unit)) { + $units = [CodeUnit::forClass($unit)]; + + foreach ($this->reflectorForClass($unit)->getTraits() as $trait) { + if (!$trait->isUserDefined()) { + // @codeCoverageIgnoreStart + continue; + // @codeCoverageIgnoreEnd + } + + $units[] = CodeUnit::forTrait($trait->getName()); + } + + return CodeUnitCollection::fromArray($units); + } + + if ($this->isUserDefinedInterface($unit)) { + return CodeUnitCollection::fromList(CodeUnit::forInterface($unit)); + } + + if ($this->isUserDefinedTrait($unit)) { + return CodeUnitCollection::fromList(CodeUnit::forTrait($unit)); + } + + if ($this->isUserDefinedFunction($unit)) { + return CodeUnitCollection::fromList(CodeUnit::forFunction($unit)); + } + + $unit = str_replace('<extended>', '', $unit); + + if ($this->isUserDefinedClass($unit)) { + return $this->classAndParentClassesAndTraits($unit); + } + } + + throw new InvalidCodeUnitException( + sprintf( + '"%s" is not a valid code unit', + $unit + ) + ); + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private function publicMethodsOfClass(string $className): CodeUnitCollection + { + return $this->methodsOfClass($className, ReflectionMethod::IS_PUBLIC); + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private function publicAndProtectedMethodsOfClass(string $className): CodeUnitCollection + { + return $this->methodsOfClass($className, ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED); + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private function publicAndPrivateMethodsOfClass(string $className): CodeUnitCollection + { + return $this->methodsOfClass($className, ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PRIVATE); + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private function protectedMethodsOfClass(string $className): CodeUnitCollection + { + return $this->methodsOfClass($className, ReflectionMethod::IS_PROTECTED); + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private function protectedAndPrivateMethodsOfClass(string $className): CodeUnitCollection + { + return $this->methodsOfClass($className, ReflectionMethod::IS_PROTECTED | ReflectionMethod::IS_PRIVATE); + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private function privateMethodsOfClass(string $className): CodeUnitCollection + { + return $this->methodsOfClass($className, ReflectionMethod::IS_PRIVATE); + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private function methodsOfClass(string $className, int $filter): CodeUnitCollection + { + $units = []; + + foreach ($this->reflectorForClass($className)->getMethods($filter) as $method) { + if (!$method->isUserDefined()) { + continue; + } + + $units[] = CodeUnit::forClassMethod($className, $method->getName()); + } + + return CodeUnitCollection::fromArray($units); + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private function classAndParentClassesAndTraits(string $className): CodeUnitCollection + { + $units = [CodeUnit::forClass($className)]; + + $reflector = $this->reflectorForClass($className); + + foreach ($this->reflectorForClass($className)->getTraits() as $trait) { + if (!$trait->isUserDefined()) { + // @codeCoverageIgnoreStart + continue; + // @codeCoverageIgnoreEnd + } + + $units[] = CodeUnit::forTrait($trait->getName()); + } + + while ($reflector = $reflector->getParentClass()) { + if (!$reflector->isUserDefined()) { + break; + } + + $units[] = CodeUnit::forClass($reflector->getName()); + + foreach ($reflector->getTraits() as $trait) { + if (!$trait->isUserDefined()) { + // @codeCoverageIgnoreStart + continue; + // @codeCoverageIgnoreEnd + } + + $units[] = CodeUnit::forTrait($trait->getName()); + } + } + + return CodeUnitCollection::fromArray($units); + } + + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private function reflectorForClass(string $className): ReflectionClass + { + try { + return new ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @throws ReflectionException + */ + private function isUserDefinedFunction(string $functionName): bool + { + if (!function_exists($functionName)) { + return false; + } + + try { + return (new ReflectionFunction($functionName))->isUserDefined(); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @throws ReflectionException + */ + private function isUserDefinedClass(string $className): bool + { + if (!class_exists($className)) { + return false; + } + + try { + return (new ReflectionClass($className))->isUserDefined(); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @throws ReflectionException + */ + private function isUserDefinedInterface(string $interfaceName): bool + { + if (!interface_exists($interfaceName)) { + return false; + } + + try { + return (new ReflectionClass($interfaceName))->isUserDefined(); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @throws ReflectionException + */ + private function isUserDefinedTrait(string $traitName): bool + { + if (!trait_exists($traitName)) { + return false; + } + + try { + return (new ReflectionClass($traitName))->isUserDefined(); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @throws ReflectionException + */ + private function isUserDefinedMethod(string $className, string $methodName): bool + { + if (!class_exists($className)) { + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + if (!method_exists($className, $methodName)) { + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + try { + return (new ReflectionMethod($className, $methodName))->isUserDefined(); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new ReflectionException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } +} diff --git a/vendor/sebastian/code-unit/src/TraitMethodUnit.php b/vendor/sebastian/code-unit/src/TraitMethodUnit.php new file mode 100644 index 000000000..a58f7249f --- /dev/null +++ b/vendor/sebastian/code-unit/src/TraitMethodUnit.php @@ -0,0 +1,24 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +/** + * @psalm-immutable + */ +final class TraitMethodUnit extends CodeUnit +{ + /** + * @psalm-assert-if-true TraitMethodUnit $this + */ + public function isTraitMethod(): bool + { + return true; + } +} diff --git a/vendor/sebastian/code-unit/src/TraitUnit.php b/vendor/sebastian/code-unit/src/TraitUnit.php new file mode 100644 index 000000000..abddfc112 --- /dev/null +++ b/vendor/sebastian/code-unit/src/TraitUnit.php @@ -0,0 +1,24 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +/** + * @psalm-immutable + */ +final class TraitUnit extends CodeUnit +{ + /** + * @psalm-assert-if-true TraitUnit $this + */ + public function isTrait(): bool + { + return true; + } +} diff --git a/vendor/sebastian/code-unit/src/exceptions/Exception.php b/vendor/sebastian/code-unit/src/exceptions/Exception.php new file mode 100644 index 000000000..74d0eeef8 --- /dev/null +++ b/vendor/sebastian/code-unit/src/exceptions/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/code-unit/src/exceptions/InvalidCodeUnitException.php b/vendor/sebastian/code-unit/src/exceptions/InvalidCodeUnitException.php new file mode 100644 index 000000000..60a3da82b --- /dev/null +++ b/vendor/sebastian/code-unit/src/exceptions/InvalidCodeUnitException.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +use RuntimeException; + +final class InvalidCodeUnitException extends RuntimeException implements Exception +{ +} diff --git a/vendor/sebastian/code-unit/src/exceptions/NoTraitException.php b/vendor/sebastian/code-unit/src/exceptions/NoTraitException.php new file mode 100644 index 000000000..e9b9b9c7a --- /dev/null +++ b/vendor/sebastian/code-unit/src/exceptions/NoTraitException.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +use RuntimeException; + +final class NoTraitException extends RuntimeException implements Exception +{ +} diff --git a/vendor/sebastian/code-unit/src/exceptions/ReflectionException.php b/vendor/sebastian/code-unit/src/exceptions/ReflectionException.php new file mode 100644 index 000000000..232012783 --- /dev/null +++ b/vendor/sebastian/code-unit/src/exceptions/ReflectionException.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/code-unit. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeUnit; + +use RuntimeException; + +final class ReflectionException extends RuntimeException implements Exception +{ +} diff --git a/vendor/sebastian/comparator/ChangeLog.md b/vendor/sebastian/comparator/ChangeLog.md new file mode 100644 index 000000000..64c0251c1 --- /dev/null +++ b/vendor/sebastian/comparator/ChangeLog.md @@ -0,0 +1,108 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.0.6] - 2020-10-26 + +### Fixed + +* `SebastianBergmann\Comparator\Exception` now correctly extends `\Throwable` + +## [4.0.5] - 2020-09-30 + +### Fixed + +* [#89](https://github.com/sebastianbergmann/comparator/pull/89): Handle PHP 8 `ValueError` + +## [4.0.4] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [4.0.3] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [4.0.2] - 2020-06-15 + +### Fixed + +* [#85](https://github.com/sebastianbergmann/comparator/issues/85): Version 4.0.1 breaks backward compatibility + +## [4.0.1] - 2020-06-15 + +### Changed + +* Tests etc. are now ignored for archive exports + +## [4.0.0] - 2020-02-07 + +### Removed + +* Removed support for PHP 7.1 and PHP 7.2 + +## [3.0.2] - 2018-07-12 + +### Changed + +* By default, `MockObjectComparator` is now tried before all other (default) comparators + +## [3.0.1] - 2018-06-14 + +### Fixed + +* [#53](https://github.com/sebastianbergmann/comparator/pull/53): `DOMNodeComparator` ignores `$ignoreCase` parameter +* [#58](https://github.com/sebastianbergmann/comparator/pull/58): `ScalarComparator` does not handle extremely ugly string comparison edge cases + +## [3.0.0] - 2018-04-18 + +### Fixed + +* Fixed [#48](https://github.com/sebastianbergmann/comparator/issues/48): `DateTimeComparator` does not support fractional second deltas + +### Removed + +* Removed support for PHP 7.0 + +## [2.1.3] - 2018-02-01 + +### Changed + +* This component is now compatible with version 3 of `sebastian/diff` + +## [2.1.2] - 2018-01-12 + +### Fixed + +* Fix comparison of `DateTimeImmutable` objects + +## [2.1.1] - 2017-12-22 + +### Fixed + +* Fixed [phpunit/#2923](https://github.com/sebastianbergmann/phpunit/issues/2923): Unexpected failed date matching + +## [2.1.0] - 2017-11-03 + +### Added + +* Added `SebastianBergmann\Comparator\Factory::reset()` to unregister all non-default comparators +* Added support for `phpunit/phpunit-mock-objects` version `^5.0` + +[4.0.6]: https://github.com/sebastianbergmann/comparator/compare/4.0.5...4.0.6 +[4.0.5]: https://github.com/sebastianbergmann/comparator/compare/4.0.4...4.0.5 +[4.0.4]: https://github.com/sebastianbergmann/comparator/compare/4.0.3...4.0.4 +[4.0.3]: https://github.com/sebastianbergmann/comparator/compare/4.0.2...4.0.3 +[4.0.2]: https://github.com/sebastianbergmann/comparator/compare/4.0.1...4.0.2 +[4.0.1]: https://github.com/sebastianbergmann/comparator/compare/4.0.0...4.0.1 +[4.0.0]: https://github.com/sebastianbergmann/comparator/compare/3.0.2...4.0.0 +[3.0.2]: https://github.com/sebastianbergmann/comparator/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/sebastianbergmann/comparator/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/sebastianbergmann/comparator/compare/2.1.3...3.0.0 +[2.1.3]: https://github.com/sebastianbergmann/comparator/compare/2.1.2...2.1.3 +[2.1.2]: https://github.com/sebastianbergmann/comparator/compare/2.1.1...2.1.2 +[2.1.1]: https://github.com/sebastianbergmann/comparator/compare/2.1.0...2.1.1 +[2.1.0]: https://github.com/sebastianbergmann/comparator/compare/2.0.2...2.1.0 diff --git a/vendor/sebastian/comparator/LICENSE b/vendor/sebastian/comparator/LICENSE new file mode 100644 index 000000000..6ad70cbaf --- /dev/null +++ b/vendor/sebastian/comparator/LICENSE @@ -0,0 +1,33 @@ +Comparator + +Copyright (c) 2002-2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/comparator/README.md b/vendor/sebastian/comparator/README.md new file mode 100644 index 000000000..f6002db65 --- /dev/null +++ b/vendor/sebastian/comparator/README.md @@ -0,0 +1,41 @@ +# sebastian/comparator + +[![CI Status](https://github.com/sebastianbergmann/comparator/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/comparator/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/comparator/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/comparator) + +This component provides the functionality to compare PHP values for equality. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/comparator +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/comparator +``` + +## Usage + +```php +<?php +use SebastianBergmann\Comparator\Factory; +use SebastianBergmann\Comparator\ComparisonFailure; + +$date1 = new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')); +$date2 = new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/Chicago')); + +$factory = new Factory; +$comparator = $factory->getComparatorFor($date1, $date2); + +try { + $comparator->assertEquals($date1, $date2); + print "Dates match"; +} catch (ComparisonFailure $failure) { + print "Dates don't match"; +} +``` diff --git a/vendor/sebastian/comparator/composer.json b/vendor/sebastian/comparator/composer.json new file mode 100644 index 000000000..b758e03c9 --- /dev/null +++ b/vendor/sebastian/comparator/composer.json @@ -0,0 +1,57 @@ +{ + "name": "sebastian/comparator", + "description": "Provides the functionality to compare PHP values for equality", + "keywords": ["comparator","compare","equality"], + "homepage": "https://github.com/sebastianbergmann/comparator", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]" + }, + { + "name": "Jeff Welch", + "email": "[email protected]" + }, + { + "name": "Volker Dusch", + "email": "[email protected]" + }, + { + "name": "Bernhard Schussek", + "email": "[email protected]" + } + ], + "prefer-stable": true, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "autoload-dev": { + "classmap": [ + "tests/_fixture" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + } +} + diff --git a/vendor/sebastian/comparator/src/ArrayComparator.php b/vendor/sebastian/comparator/src/ArrayComparator.php new file mode 100644 index 000000000..5d9fbce6e --- /dev/null +++ b/vendor/sebastian/comparator/src/ArrayComparator.php @@ -0,0 +1,141 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use function array_key_exists; +use function is_array; +use function sort; +use function sprintf; +use function str_replace; +use function trim; + +/** + * Compares arrays for equality. + * + * Arrays are equal if they contain the same key-value pairs. + * The order of the keys does not matter. + * The types of key-value pairs do not matter. + */ +class ArrayComparator extends Comparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + return is_array($expected) && is_array($actual); + } + + /** + * Asserts that two arrays are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * @param array $processed List of already processed elements (used to prevent infinite recursion) + * + * @throws ComparisonFailure + */ + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/ + { + if ($canonicalize) { + sort($expected); + sort($actual); + } + + $remaining = $actual; + $actualAsString = "Array (\n"; + $expectedAsString = "Array (\n"; + $equal = true; + + foreach ($expected as $key => $value) { + unset($remaining[$key]); + + if (!array_key_exists($key, $actual)) { + $expectedAsString .= sprintf( + " %s => %s\n", + $this->exporter->export($key), + $this->exporter->shortenedExport($value) + ); + + $equal = false; + + continue; + } + + try { + $comparator = $this->factory->getComparatorFor($value, $actual[$key]); + $comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed); + + $expectedAsString .= sprintf( + " %s => %s\n", + $this->exporter->export($key), + $this->exporter->shortenedExport($value) + ); + + $actualAsString .= sprintf( + " %s => %s\n", + $this->exporter->export($key), + $this->exporter->shortenedExport($actual[$key]) + ); + } catch (ComparisonFailure $e) { + $expectedAsString .= sprintf( + " %s => %s\n", + $this->exporter->export($key), + $e->getExpectedAsString() ? $this->indent($e->getExpectedAsString()) : $this->exporter->shortenedExport($e->getExpected()) + ); + + $actualAsString .= sprintf( + " %s => %s\n", + $this->exporter->export($key), + $e->getActualAsString() ? $this->indent($e->getActualAsString()) : $this->exporter->shortenedExport($e->getActual()) + ); + + $equal = false; + } + } + + foreach ($remaining as $key => $value) { + $actualAsString .= sprintf( + " %s => %s\n", + $this->exporter->export($key), + $this->exporter->shortenedExport($value) + ); + + $equal = false; + } + + $expectedAsString .= ')'; + $actualAsString .= ')'; + + if (!$equal) { + throw new ComparisonFailure( + $expected, + $actual, + $expectedAsString, + $actualAsString, + false, + 'Failed asserting that two arrays are equal.' + ); + } + } + + protected function indent($lines) + { + return trim(str_replace("\n", "\n ", $lines)); + } +} diff --git a/vendor/sebastian/comparator/src/Comparator.php b/vendor/sebastian/comparator/src/Comparator.php new file mode 100644 index 000000000..e1906c167 --- /dev/null +++ b/vendor/sebastian/comparator/src/Comparator.php @@ -0,0 +1,61 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use SebastianBergmann\Exporter\Exporter; + +/** + * Abstract base class for comparators which compare values for equality. + */ +abstract class Comparator +{ + /** + * @var Factory + */ + protected $factory; + + /** + * @var Exporter + */ + protected $exporter; + + public function __construct() + { + $this->exporter = new Exporter; + } + + public function setFactory(Factory $factory)/*: void*/ + { + $this->factory = $factory; + } + + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + abstract public function accepts($expected, $actual); + + /** + * Asserts that two values are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * + * @throws ComparisonFailure + */ + abstract public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false); +} diff --git a/vendor/sebastian/comparator/src/ComparisonFailure.php b/vendor/sebastian/comparator/src/ComparisonFailure.php new file mode 100644 index 000000000..857314daa --- /dev/null +++ b/vendor/sebastian/comparator/src/ComparisonFailure.php @@ -0,0 +1,129 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use RuntimeException; +use SebastianBergmann\Diff\Differ; +use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder; + +/** + * Thrown when an assertion for string equality failed. + */ +class ComparisonFailure extends RuntimeException +{ + /** + * Expected value of the retrieval which does not match $actual. + * + * @var mixed + */ + protected $expected; + + /** + * Actually retrieved value which does not match $expected. + * + * @var mixed + */ + protected $actual; + + /** + * The string representation of the expected value. + * + * @var string + */ + protected $expectedAsString; + + /** + * The string representation of the actual value. + * + * @var string + */ + protected $actualAsString; + + /** + * @var bool + */ + protected $identical; + + /** + * Optional message which is placed in front of the first line + * returned by toString(). + * + * @var string + */ + protected $message; + + /** + * Initialises with the expected value and the actual value. + * + * @param mixed $expected expected value retrieved + * @param mixed $actual actual value retrieved + * @param string $expectedAsString + * @param string $actualAsString + * @param bool $identical + * @param string $message a string which is prefixed on all returned lines + * in the difference output + */ + public function __construct($expected, $actual, $expectedAsString, $actualAsString, $identical = false, $message = '') + { + $this->expected = $expected; + $this->actual = $actual; + $this->expectedAsString = $expectedAsString; + $this->actualAsString = $actualAsString; + $this->message = $message; + } + + public function getActual() + { + return $this->actual; + } + + public function getExpected() + { + return $this->expected; + } + + /** + * @return string + */ + public function getActualAsString() + { + return $this->actualAsString; + } + + /** + * @return string + */ + public function getExpectedAsString() + { + return $this->expectedAsString; + } + + /** + * @return string + */ + public function getDiff() + { + if (!$this->actualAsString && !$this->expectedAsString) { + return ''; + } + + $differ = new Differ(new UnifiedDiffOutputBuilder("\n--- Expected\n+++ Actual\n")); + + return $differ->diff($this->expectedAsString, $this->actualAsString); + } + + /** + * @return string + */ + public function toString() + { + return $this->message . $this->getDiff(); + } +} diff --git a/vendor/sebastian/comparator/src/DOMNodeComparator.php b/vendor/sebastian/comparator/src/DOMNodeComparator.php new file mode 100644 index 000000000..5bf854eae --- /dev/null +++ b/vendor/sebastian/comparator/src/DOMNodeComparator.php @@ -0,0 +1,93 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use function sprintf; +use function strtolower; +use DOMDocument; +use DOMNode; +use ValueError; + +/** + * Compares DOMNode instances for equality. + */ +class DOMNodeComparator extends ObjectComparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + return $expected instanceof DOMNode && $actual instanceof DOMNode; + } + + /** + * Asserts that two values are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * @param array $processed List of already processed elements (used to prevent infinite recursion) + * + * @throws ComparisonFailure + */ + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/ + { + $expectedAsString = $this->nodeToText($expected, true, $ignoreCase); + $actualAsString = $this->nodeToText($actual, true, $ignoreCase); + + if ($expectedAsString !== $actualAsString) { + $type = $expected instanceof DOMDocument ? 'documents' : 'nodes'; + + throw new ComparisonFailure( + $expected, + $actual, + $expectedAsString, + $actualAsString, + false, + sprintf("Failed asserting that two DOM %s are equal.\n", $type) + ); + } + } + + /** + * Returns the normalized, whitespace-cleaned, and indented textual + * representation of a DOMNode. + */ + private function nodeToText(DOMNode $node, bool $canonicalize, bool $ignoreCase): string + { + if ($canonicalize) { + $document = new DOMDocument; + + try { + @$document->loadXML($node->C14N()); + } catch (ValueError $e) { + } + + $node = $document; + } + + $document = $node instanceof DOMDocument ? $node : $node->ownerDocument; + + $document->formatOutput = true; + $document->normalizeDocument(); + + $text = $node instanceof DOMDocument ? $node->saveXML() : $document->saveXML($node); + + return $ignoreCase ? strtolower($text) : $text; + } +} diff --git a/vendor/sebastian/comparator/src/DateTimeComparator.php b/vendor/sebastian/comparator/src/DateTimeComparator.php new file mode 100644 index 000000000..0a303b623 --- /dev/null +++ b/vendor/sebastian/comparator/src/DateTimeComparator.php @@ -0,0 +1,95 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use function abs; +use function floor; +use function sprintf; +use DateInterval; +use DateTime; +use DateTimeInterface; +use DateTimeZone; +use Exception; + +/** + * Compares DateTimeInterface instances for equality. + */ +class DateTimeComparator extends ObjectComparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + return ($expected instanceof DateTime || $expected instanceof DateTimeInterface) && + ($actual instanceof DateTime || $actual instanceof DateTimeInterface); + } + + /** + * Asserts that two values are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * @param array $processed List of already processed elements (used to prevent infinite recursion) + * + * @throws Exception + * @throws ComparisonFailure + */ + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/ + { + /** @var DateTimeInterface $expected */ + /** @var DateTimeInterface $actual */ + $absDelta = abs($delta); + $delta = new DateInterval(sprintf('PT%dS', $absDelta)); + $delta->f = $absDelta - floor($absDelta); + + $actualClone = (clone $actual) + ->setTimezone(new DateTimeZone('UTC')); + + $expectedLower = (clone $expected) + ->setTimezone(new DateTimeZone('UTC')) + ->sub($delta); + + $expectedUpper = (clone $expected) + ->setTimezone(new DateTimeZone('UTC')) + ->add($delta); + + if ($actualClone < $expectedLower || $actualClone > $expectedUpper) { + throw new ComparisonFailure( + $expected, + $actual, + $this->dateTimeToString($expected), + $this->dateTimeToString($actual), + false, + 'Failed asserting that two DateTime objects are equal.' + ); + } + } + + /** + * Returns an ISO 8601 formatted string representation of a datetime or + * 'Invalid DateTimeInterface object' if the provided DateTimeInterface was not properly + * initialized. + */ + private function dateTimeToString(DateTimeInterface $datetime): string + { + $string = $datetime->format('Y-m-d\TH:i:s.uO'); + + return $string ?: 'Invalid DateTimeInterface object'; + } +} diff --git a/vendor/sebastian/comparator/src/DoubleComparator.php b/vendor/sebastian/comparator/src/DoubleComparator.php new file mode 100644 index 000000000..d90b9e06b --- /dev/null +++ b/vendor/sebastian/comparator/src/DoubleComparator.php @@ -0,0 +1,59 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use function is_float; +use function is_numeric; + +/** + * Compares doubles for equality. + */ +class DoubleComparator extends NumericComparator +{ + /** + * Smallest value available in PHP. + * + * @var float + */ + public const EPSILON = 0.0000000001; + + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + return (is_float($expected) || is_float($actual)) && is_numeric($expected) && is_numeric($actual); + } + + /** + * Asserts that two values are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * + * @throws ComparisonFailure + */ + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/ + { + if ($delta == 0) { + $delta = self::EPSILON; + } + + parent::assertEquals($expected, $actual, $delta, $canonicalize, $ignoreCase); + } +} diff --git a/vendor/sebastian/comparator/src/ExceptionComparator.php b/vendor/sebastian/comparator/src/ExceptionComparator.php new file mode 100644 index 000000000..1fc0174ef --- /dev/null +++ b/vendor/sebastian/comparator/src/ExceptionComparator.php @@ -0,0 +1,54 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use Exception; + +/** + * Compares Exception instances for equality. + */ +class ExceptionComparator extends ObjectComparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + return $expected instanceof Exception && $actual instanceof Exception; + } + + /** + * Converts an object to an array containing all of its private, protected + * and public properties. + * + * @param object $object + * + * @return array + */ + protected function toArray($object) + { + $array = parent::toArray($object); + + unset( + $array['file'], + $array['line'], + $array['trace'], + $array['string'], + $array['xdebug_message'] + ); + + return $array; + } +} diff --git a/vendor/sebastian/comparator/src/Factory.php b/vendor/sebastian/comparator/src/Factory.php new file mode 100644 index 000000000..5b16366f0 --- /dev/null +++ b/vendor/sebastian/comparator/src/Factory.php @@ -0,0 +1,142 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use function array_unshift; + +/** + * Factory for comparators which compare values for equality. + */ +class Factory +{ + /** + * @var Factory + */ + private static $instance; + + /** + * @var Comparator[] + */ + private $customComparators = []; + + /** + * @var Comparator[] + */ + private $defaultComparators = []; + + /** + * @return Factory + */ + public static function getInstance() + { + if (self::$instance === null) { + self::$instance = new self; // @codeCoverageIgnore + } + + return self::$instance; + } + + /** + * Constructs a new factory. + */ + public function __construct() + { + $this->registerDefaultComparators(); + } + + /** + * Returns the correct comparator for comparing two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return Comparator + */ + public function getComparatorFor($expected, $actual) + { + foreach ($this->customComparators as $comparator) { + if ($comparator->accepts($expected, $actual)) { + return $comparator; + } + } + + foreach ($this->defaultComparators as $comparator) { + if ($comparator->accepts($expected, $actual)) { + return $comparator; + } + } + + throw new RuntimeException('No suitable Comparator implementation found'); + } + + /** + * Registers a new comparator. + * + * This comparator will be returned by getComparatorFor() if its accept() method + * returns TRUE for the compared values. It has higher priority than the + * existing comparators, meaning that its accept() method will be invoked + * before those of the other comparators. + * + * @param Comparator $comparator The comparator to be registered + */ + public function register(Comparator $comparator)/*: void*/ + { + array_unshift($this->customComparators, $comparator); + + $comparator->setFactory($this); + } + + /** + * Unregisters a comparator. + * + * This comparator will no longer be considered by getComparatorFor(). + * + * @param Comparator $comparator The comparator to be unregistered + */ + public function unregister(Comparator $comparator)/*: void*/ + { + foreach ($this->customComparators as $key => $_comparator) { + if ($comparator === $_comparator) { + unset($this->customComparators[$key]); + } + } + } + + /** + * Unregisters all non-default comparators. + */ + public function reset()/*: void*/ + { + $this->customComparators = []; + } + + private function registerDefaultComparators(): void + { + $this->registerDefaultComparator(new MockObjectComparator); + $this->registerDefaultComparator(new DateTimeComparator); + $this->registerDefaultComparator(new DOMNodeComparator); + $this->registerDefaultComparator(new SplObjectStorageComparator); + $this->registerDefaultComparator(new ExceptionComparator); + $this->registerDefaultComparator(new ObjectComparator); + $this->registerDefaultComparator(new ResourceComparator); + $this->registerDefaultComparator(new ArrayComparator); + $this->registerDefaultComparator(new DoubleComparator); + $this->registerDefaultComparator(new NumericComparator); + $this->registerDefaultComparator(new ScalarComparator); + $this->registerDefaultComparator(new TypeComparator); + } + + private function registerDefaultComparator(Comparator $comparator): void + { + $this->defaultComparators[] = $comparator; + + $comparator->setFactory($this); + } +} diff --git a/vendor/sebastian/comparator/src/MockObjectComparator.php b/vendor/sebastian/comparator/src/MockObjectComparator.php new file mode 100644 index 000000000..cb6703161 --- /dev/null +++ b/vendor/sebastian/comparator/src/MockObjectComparator.php @@ -0,0 +1,48 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use PHPUnit\Framework\MockObject\MockObject; + +/** + * Compares PHPUnit\Framework\MockObject\MockObject instances for equality. + */ +class MockObjectComparator extends ObjectComparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + return $expected instanceof MockObject && $actual instanceof MockObject; + } + + /** + * Converts an object to an array containing all of its private, protected + * and public properties. + * + * @param object $object + * + * @return array + */ + protected function toArray($object) + { + $array = parent::toArray($object); + + unset($array['__phpunit_invocationMocker']); + + return $array; + } +} diff --git a/vendor/sebastian/comparator/src/NumericComparator.php b/vendor/sebastian/comparator/src/NumericComparator.php new file mode 100644 index 000000000..12e6721d6 --- /dev/null +++ b/vendor/sebastian/comparator/src/NumericComparator.php @@ -0,0 +1,86 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use function abs; +use function is_float; +use function is_infinite; +use function is_nan; +use function is_numeric; +use function is_string; +use function sprintf; + +/** + * Compares numerical values for equality. + */ +class NumericComparator extends ScalarComparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + // all numerical values, but not if one of them is a double + // or both of them are strings + return is_numeric($expected) && is_numeric($actual) && + !(is_float($expected) || is_float($actual)) && + !(is_string($expected) && is_string($actual)); + } + + /** + * Asserts that two values are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * + * @throws ComparisonFailure + */ + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/ + { + if ($this->isInfinite($actual) && $this->isInfinite($expected)) { + return; + } + + if (($this->isInfinite($actual) xor $this->isInfinite($expected)) || + ($this->isNan($actual) || $this->isNan($expected)) || + abs($actual - $expected) > $delta) { + throw new ComparisonFailure( + $expected, + $actual, + '', + '', + false, + sprintf( + 'Failed asserting that %s matches expected %s.', + $this->exporter->export($actual), + $this->exporter->export($expected) + ) + ); + } + } + + private function isInfinite($value): bool + { + return is_float($value) && is_infinite($value); + } + + private function isNan($value): bool + { + return is_float($value) && is_nan($value); + } +} diff --git a/vendor/sebastian/comparator/src/ObjectComparator.php b/vendor/sebastian/comparator/src/ObjectComparator.php new file mode 100644 index 000000000..9380ba150 --- /dev/null +++ b/vendor/sebastian/comparator/src/ObjectComparator.php @@ -0,0 +1,112 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use function get_class; +use function in_array; +use function is_object; +use function sprintf; +use function substr_replace; + +/** + * Compares objects for equality. + */ +class ObjectComparator extends ArrayComparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + return is_object($expected) && is_object($actual); + } + + /** + * Asserts that two values are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * @param array $processed List of already processed elements (used to prevent infinite recursion) + * + * @throws ComparisonFailure + */ + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = [])/*: void*/ + { + if (get_class($actual) !== get_class($expected)) { + throw new ComparisonFailure( + $expected, + $actual, + $this->exporter->export($expected), + $this->exporter->export($actual), + false, + sprintf( + '%s is not instance of expected class "%s".', + $this->exporter->export($actual), + get_class($expected) + ) + ); + } + + // don't compare twice to allow for cyclic dependencies + if (in_array([$actual, $expected], $processed, true) || + in_array([$expected, $actual], $processed, true)) { + return; + } + + $processed[] = [$actual, $expected]; + + // don't compare objects if they are identical + // this helps to avoid the error "maximum function nesting level reached" + // CAUTION: this conditional clause is not tested + if ($actual !== $expected) { + try { + parent::assertEquals( + $this->toArray($expected), + $this->toArray($actual), + $delta, + $canonicalize, + $ignoreCase, + $processed + ); + } catch (ComparisonFailure $e) { + throw new ComparisonFailure( + $expected, + $actual, + // replace "Array" with "MyClass object" + substr_replace($e->getExpectedAsString(), get_class($expected) . ' Object', 0, 5), + substr_replace($e->getActualAsString(), get_class($actual) . ' Object', 0, 5), + false, + 'Failed asserting that two objects are equal.' + ); + } + } + } + + /** + * Converts an object to an array containing all of its private, protected + * and public properties. + * + * @param object $object + * + * @return array + */ + protected function toArray($object) + { + return $this->exporter->toArray($object); + } +} diff --git a/vendor/sebastian/comparator/src/ResourceComparator.php b/vendor/sebastian/comparator/src/ResourceComparator.php new file mode 100644 index 000000000..7822598b1 --- /dev/null +++ b/vendor/sebastian/comparator/src/ResourceComparator.php @@ -0,0 +1,54 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use function is_resource; + +/** + * Compares resources for equality. + */ +class ResourceComparator extends Comparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + return is_resource($expected) && is_resource($actual); + } + + /** + * Asserts that two values are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * + * @throws ComparisonFailure + */ + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/ + { + if ($actual != $expected) { + throw new ComparisonFailure( + $expected, + $actual, + $this->exporter->export($expected), + $this->exporter->export($actual) + ); + } + } +} diff --git a/vendor/sebastian/comparator/src/ScalarComparator.php b/vendor/sebastian/comparator/src/ScalarComparator.php new file mode 100644 index 000000000..08ded922b --- /dev/null +++ b/vendor/sebastian/comparator/src/ScalarComparator.php @@ -0,0 +1,98 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use function is_object; +use function is_scalar; +use function is_string; +use function method_exists; +use function sprintf; +use function strtolower; + +/** + * Compares scalar or NULL values for equality. + */ +class ScalarComparator extends Comparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + * + * @since Method available since Release 3.6.0 + */ + public function accepts($expected, $actual) + { + return ((is_scalar($expected) xor null === $expected) && + (is_scalar($actual) xor null === $actual)) + // allow comparison between strings and objects featuring __toString() + || (is_string($expected) && is_object($actual) && method_exists($actual, '__toString')) + || (is_object($expected) && method_exists($expected, '__toString') && is_string($actual)); + } + + /** + * Asserts that two values are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * + * @throws ComparisonFailure + */ + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/ + { + $expectedToCompare = $expected; + $actualToCompare = $actual; + + // always compare as strings to avoid strange behaviour + // otherwise 0 == 'Foobar' + if (is_string($expected) || is_string($actual)) { + $expectedToCompare = (string) $expectedToCompare; + $actualToCompare = (string) $actualToCompare; + + if ($ignoreCase) { + $expectedToCompare = strtolower($expectedToCompare); + $actualToCompare = strtolower($actualToCompare); + } + } + + if ($expectedToCompare !== $actualToCompare && is_string($expected) && is_string($actual)) { + throw new ComparisonFailure( + $expected, + $actual, + $this->exporter->export($expected), + $this->exporter->export($actual), + false, + 'Failed asserting that two strings are equal.' + ); + } + + if ($expectedToCompare != $actualToCompare) { + throw new ComparisonFailure( + $expected, + $actual, + // no diff is required + '', + '', + false, + sprintf( + 'Failed asserting that %s matches expected %s.', + $this->exporter->export($actual), + $this->exporter->export($expected) + ) + ); + } + } +} diff --git a/vendor/sebastian/comparator/src/SplObjectStorageComparator.php b/vendor/sebastian/comparator/src/SplObjectStorageComparator.php new file mode 100644 index 000000000..d9b6f541a --- /dev/null +++ b/vendor/sebastian/comparator/src/SplObjectStorageComparator.php @@ -0,0 +1,71 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use SplObjectStorage; + +/** + * Compares \SplObjectStorage instances for equality. + */ +class SplObjectStorageComparator extends Comparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + return $expected instanceof SplObjectStorage && $actual instanceof SplObjectStorage; + } + + /** + * Asserts that two values are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * + * @throws ComparisonFailure + */ + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/ + { + foreach ($actual as $object) { + if (!$expected->contains($object)) { + throw new ComparisonFailure( + $expected, + $actual, + $this->exporter->export($expected), + $this->exporter->export($actual), + false, + 'Failed asserting that two objects are equal.' + ); + } + } + + foreach ($expected as $object) { + if (!$actual->contains($object)) { + throw new ComparisonFailure( + $expected, + $actual, + $this->exporter->export($expected), + $this->exporter->export($actual), + false, + 'Failed asserting that two objects are equal.' + ); + } + } + } +} diff --git a/vendor/sebastian/comparator/src/TypeComparator.php b/vendor/sebastian/comparator/src/TypeComparator.php new file mode 100644 index 000000000..b0d38d72e --- /dev/null +++ b/vendor/sebastian/comparator/src/TypeComparator.php @@ -0,0 +1,62 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use function gettype; +use function sprintf; + +/** + * Compares values for type equality. + */ +class TypeComparator extends Comparator +{ + /** + * Returns whether the comparator can compare two values. + * + * @param mixed $expected The first value to compare + * @param mixed $actual The second value to compare + * + * @return bool + */ + public function accepts($expected, $actual) + { + return true; + } + + /** + * Asserts that two values are equal. + * + * @param mixed $expected First value to compare + * @param mixed $actual Second value to compare + * @param float $delta Allowed numerical distance between two values to consider them equal + * @param bool $canonicalize Arrays are sorted before comparison when set to true + * @param bool $ignoreCase Case is ignored when set to true + * + * @throws ComparisonFailure + */ + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)/*: void*/ + { + if (gettype($expected) != gettype($actual)) { + throw new ComparisonFailure( + $expected, + $actual, + // we don't need a diff + '', + '', + false, + sprintf( + '%s does not match expected type "%s".', + $this->exporter->shortenedExport($actual), + gettype($expected) + ) + ); + } + } +} diff --git a/vendor/sebastian/comparator/src/exceptions/Exception.php b/vendor/sebastian/comparator/src/exceptions/Exception.php new file mode 100644 index 000000000..8975aaf1b --- /dev/null +++ b/vendor/sebastian/comparator/src/exceptions/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/comparator/src/exceptions/RuntimeException.php b/vendor/sebastian/comparator/src/exceptions/RuntimeException.php new file mode 100644 index 000000000..ca726084a --- /dev/null +++ b/vendor/sebastian/comparator/src/exceptions/RuntimeException.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/comparator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Comparator; + +final class RuntimeException extends \RuntimeException implements Exception +{ +} diff --git a/vendor/sebastian/complexity/.psalm/baseline.xml b/vendor/sebastian/complexity/.psalm/baseline.xml new file mode 100644 index 000000000..77e688e07 --- /dev/null +++ b/vendor/sebastian/complexity/.psalm/baseline.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44"/> diff --git a/vendor/sebastian/complexity/.psalm/config.xml b/vendor/sebastian/complexity/.psalm/config.xml new file mode 100644 index 000000000..8172fe15a --- /dev/null +++ b/vendor/sebastian/complexity/.psalm/config.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<psalm + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="https://getpsalm.org/schema/config" + xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" + resolveFromConfigFile="false" + errorBaseline=".psalm/baseline.xml" + totallyTyped="true" +> + <projectFiles> + <directory name="src" /> + <ignoreFiles> + <directory name="vendor" /> + </ignoreFiles> + </projectFiles> +</psalm> diff --git a/vendor/sebastian/complexity/ChangeLog.md b/vendor/sebastian/complexity/ChangeLog.md new file mode 100644 index 000000000..cb93ff620 --- /dev/null +++ b/vendor/sebastian/complexity/ChangeLog.md @@ -0,0 +1,30 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. + +## [2.0.2] - 2020-10-26 + +### Fixed + +* `SebastianBergmann\Complexity\Exception` now correctly extends `\Throwable` + +## [2.0.1] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [2.0.0] - 2020-07-25 + +### Removed + +* The `ParentConnectingVisitor` has been removed (it should have been marked as `@internal`) + +## [1.0.0] - 2020-07-22 + +* Initial release + +[2.0.2]: https://github.com/sebastianbergmann/complexity/compare/2.0.1...2.0.2 +[2.0.1]: https://github.com/sebastianbergmann/complexity/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/sebastianbergmann/complexity/compare/1.0.0...2.0.0 +[1.0.0]: https://github.com/sebastianbergmann/complexity/compare/70ee0ad32d9e2be3f85beffa3e2eb474193f2487...1.0.0 diff --git a/vendor/sebastian/complexity/LICENSE b/vendor/sebastian/complexity/LICENSE new file mode 100644 index 000000000..5f818df69 --- /dev/null +++ b/vendor/sebastian/complexity/LICENSE @@ -0,0 +1,33 @@ +sebastian/complexity + +Copyright (c) 2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/complexity/README.md b/vendor/sebastian/complexity/README.md new file mode 100644 index 000000000..5f53b0b5d --- /dev/null +++ b/vendor/sebastian/complexity/README.md @@ -0,0 +1,22 @@ +# sebastian/complexity + +Library for calculating the complexity of PHP code units. + +[![Latest Stable Version](https://img.shields.io/packagist/v/sebastian/complexity.svg?style=flat-square)](https://packagist.org/packages/sebastian/complexity) +[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.3-8892BF.svg?style=flat-square)](https://php.net/) +[![CI Status](https://github.com/sebastianbergmann/complexity/workflows/CI/badge.svg?branch=master&event=push)](https://phpunit.de/build-status.html) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/complexity/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/complexity) + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/complexity +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/complexity +``` diff --git a/vendor/sebastian/complexity/composer.json b/vendor/sebastian/complexity/composer.json new file mode 100644 index 000000000..7aa38314e --- /dev/null +++ b/vendor/sebastian/complexity/composer.json @@ -0,0 +1,41 @@ +{ + "name": "sebastian/complexity", + "description": "Library for calculating the complexity of PHP code units", + "type": "library", + "homepage": "https://github.com/sebastianbergmann/complexity", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues" + }, + "require": { + "php": ">=7.3", + "nikic/php-parser": "^4.7" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + } +} diff --git a/vendor/sebastian/complexity/src/Calculator.php b/vendor/sebastian/complexity/src/Calculator.php new file mode 100644 index 000000000..9abdcd169 --- /dev/null +++ b/vendor/sebastian/complexity/src/Calculator.php @@ -0,0 +1,88 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/complexity. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Complexity; + +use PhpParser\Error; +use PhpParser\Lexer; +use PhpParser\Node; +use PhpParser\NodeTraverser; +use PhpParser\NodeVisitor\NameResolver; +use PhpParser\NodeVisitor\ParentConnectingVisitor; +use PhpParser\Parser; +use PhpParser\ParserFactory; + +final class Calculator +{ + /** + * @throws RuntimeException + */ + public function calculateForSourceFile(string $sourceFile): ComplexityCollection + { + return $this->calculateForSourceString(file_get_contents($sourceFile)); + } + + /** + * @throws RuntimeException + */ + public function calculateForSourceString(string $source): ComplexityCollection + { + try { + $nodes = $this->parser()->parse($source); + + assert($nodes !== null); + + return $this->calculateForAbstractSyntaxTree($nodes); + + // @codeCoverageIgnoreStart + } catch (Error $error) { + throw new RuntimeException( + $error->getMessage(), + (int) $error->getCode(), + $error + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @param Node[] $nodes + * + * @throws RuntimeException + */ + public function calculateForAbstractSyntaxTree(array $nodes): ComplexityCollection + { + $traverser = new NodeTraverser; + $complexityCalculatingVisitor = new ComplexityCalculatingVisitor(true); + + $traverser->addVisitor(new NameResolver); + $traverser->addVisitor(new ParentConnectingVisitor); + $traverser->addVisitor($complexityCalculatingVisitor); + + try { + /* @noinspection UnusedFunctionResultInspection */ + $traverser->traverse($nodes); + // @codeCoverageIgnoreStart + } catch (Error $error) { + throw new RuntimeException( + $error->getMessage(), + (int) $error->getCode(), + $error + ); + } + // @codeCoverageIgnoreEnd + + return $complexityCalculatingVisitor->result(); + } + + private function parser(): Parser + { + return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer); + } +} diff --git a/vendor/sebastian/complexity/src/Complexity/Complexity.php b/vendor/sebastian/complexity/src/Complexity/Complexity.php new file mode 100644 index 000000000..dc6708dde --- /dev/null +++ b/vendor/sebastian/complexity/src/Complexity/Complexity.php @@ -0,0 +1,42 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/complexity. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Complexity; + +/** + * @psalm-immutable + */ +final class Complexity +{ + /** + * @var string + */ + private $name; + + /** + * @var int + */ + private $cyclomaticComplexity; + + public function __construct(string $name, int $cyclomaticComplexity) + { + $this->name = $name; + $this->cyclomaticComplexity = $cyclomaticComplexity; + } + + public function name(): string + { + return $this->name; + } + + public function cyclomaticComplexity(): int + { + return $this->cyclomaticComplexity; + } +} diff --git a/vendor/sebastian/complexity/src/Complexity/ComplexityCollection.php b/vendor/sebastian/complexity/src/Complexity/ComplexityCollection.php new file mode 100644 index 000000000..ccbddbf77 --- /dev/null +++ b/vendor/sebastian/complexity/src/Complexity/ComplexityCollection.php @@ -0,0 +1,72 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/complexity. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Complexity; + +use function count; +use Countable; +use IteratorAggregate; + +/** + * @psalm-immutable + */ +final class ComplexityCollection implements Countable, IteratorAggregate +{ + /** + * @psalm-var list<Complexity> + */ + private $items = []; + + public static function fromList(Complexity ...$items): self + { + return new self($items); + } + + /** + * @psalm-param list<Complexity> $items + */ + private function __construct(array $items) + { + $this->items = $items; + } + + /** + * @psalm-return list<Complexity> + */ + public function asArray(): array + { + return $this->items; + } + + public function getIterator(): ComplexityCollectionIterator + { + return new ComplexityCollectionIterator($this); + } + + public function count(): int + { + return count($this->items); + } + + public function isEmpty(): bool + { + return empty($this->items); + } + + public function cyclomaticComplexity(): int + { + $cyclomaticComplexity = 0; + + foreach ($this as $item) { + $cyclomaticComplexity += $item->cyclomaticComplexity(); + } + + return $cyclomaticComplexity; + } +} diff --git a/vendor/sebastian/complexity/src/Complexity/ComplexityCollectionIterator.php b/vendor/sebastian/complexity/src/Complexity/ComplexityCollectionIterator.php new file mode 100644 index 000000000..ec39e199f --- /dev/null +++ b/vendor/sebastian/complexity/src/Complexity/ComplexityCollectionIterator.php @@ -0,0 +1,55 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/complexity. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Complexity; + +use Iterator; + +final class ComplexityCollectionIterator implements Iterator +{ + /** + * @psalm-var list<Complexity> + */ + private $items; + + /** + * @var int + */ + private $position = 0; + + public function __construct(ComplexityCollection $items) + { + $this->items = $items->asArray(); + } + + public function rewind(): void + { + $this->position = 0; + } + + public function valid(): bool + { + return isset($this->items[$this->position]); + } + + public function key(): int + { + return $this->position; + } + + public function current(): Complexity + { + return $this->items[$this->position]; + } + + public function next(): void + { + $this->position++; + } +} diff --git a/vendor/sebastian/complexity/src/Exception/Exception.php b/vendor/sebastian/complexity/src/Exception/Exception.php new file mode 100644 index 000000000..897ecdcf7 --- /dev/null +++ b/vendor/sebastian/complexity/src/Exception/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/complexity. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Complexity; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/complexity/src/Exception/RuntimeException.php b/vendor/sebastian/complexity/src/Exception/RuntimeException.php new file mode 100644 index 000000000..6c68a6f0f --- /dev/null +++ b/vendor/sebastian/complexity/src/Exception/RuntimeException.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/complexity. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Complexity; + +final class RuntimeException extends \RuntimeException implements Exception +{ +} diff --git a/vendor/sebastian/complexity/src/Visitor/ComplexityCalculatingVisitor.php b/vendor/sebastian/complexity/src/Visitor/ComplexityCalculatingVisitor.php new file mode 100644 index 000000000..b69f2b09f --- /dev/null +++ b/vendor/sebastian/complexity/src/Visitor/ComplexityCalculatingVisitor.php @@ -0,0 +1,109 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/complexity. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Complexity; + +use function assert; +use function is_array; +use PhpParser\Node; +use PhpParser\Node\Name; +use PhpParser\Node\Stmt; +use PhpParser\Node\Stmt\Class_; +use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\Stmt\Function_; +use PhpParser\Node\Stmt\Trait_; +use PhpParser\NodeTraverser; +use PhpParser\NodeVisitorAbstract; + +final class ComplexityCalculatingVisitor extends NodeVisitorAbstract +{ + /** + * @psalm-var list<Complexity> + */ + private $result = []; + + /** + * @var bool + */ + private $shortCircuitTraversal; + + public function __construct(bool $shortCircuitTraversal) + { + $this->shortCircuitTraversal = $shortCircuitTraversal; + } + + public function enterNode(Node $node): ?int + { + if (!$node instanceof ClassMethod && !$node instanceof Function_) { + return null; + } + + if ($node instanceof ClassMethod) { + $name = $this->classMethodName($node); + } else { + $name = $this->functionName($node); + } + + $statements = $node->getStmts(); + + assert(is_array($statements)); + + $this->result[] = new Complexity( + $name, + $this->cyclomaticComplexity($statements) + ); + + if ($this->shortCircuitTraversal) { + return NodeTraverser::DONT_TRAVERSE_CHILDREN; + } + + return null; + } + + public function result(): ComplexityCollection + { + return ComplexityCollection::fromList(...$this->result); + } + + /** + * @param Stmt[] $statements + */ + private function cyclomaticComplexity(array $statements): int + { + $traverser = new NodeTraverser; + + $cyclomaticComplexityCalculatingVisitor = new CyclomaticComplexityCalculatingVisitor; + + $traverser->addVisitor($cyclomaticComplexityCalculatingVisitor); + + /* @noinspection UnusedFunctionResultInspection */ + $traverser->traverse($statements); + + return $cyclomaticComplexityCalculatingVisitor->cyclomaticComplexity(); + } + + private function classMethodName(ClassMethod $node): string + { + $parent = $node->getAttribute('parent'); + + assert($parent instanceof Class_ || $parent instanceof Trait_); + assert(isset($parent->namespacedName)); + assert($parent->namespacedName instanceof Name); + + return $parent->namespacedName->toString() . '::' . $node->name->toString(); + } + + private function functionName(Function_ $node): string + { + assert(isset($node->namespacedName)); + assert($node->namespacedName instanceof Name); + + return $node->namespacedName->toString(); + } +} diff --git a/vendor/sebastian/complexity/src/Visitor/CyclomaticComplexityCalculatingVisitor.php b/vendor/sebastian/complexity/src/Visitor/CyclomaticComplexityCalculatingVisitor.php new file mode 100644 index 000000000..d4430876d --- /dev/null +++ b/vendor/sebastian/complexity/src/Visitor/CyclomaticComplexityCalculatingVisitor.php @@ -0,0 +1,59 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/complexity. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Complexity; + +use function get_class; +use PhpParser\Node; +use PhpParser\Node\Expr\BinaryOp\BooleanAnd; +use PhpParser\Node\Expr\BinaryOp\BooleanOr; +use PhpParser\Node\Expr\BinaryOp\LogicalAnd; +use PhpParser\Node\Expr\BinaryOp\LogicalOr; +use PhpParser\Node\Expr\Ternary; +use PhpParser\Node\Stmt\Case_; +use PhpParser\Node\Stmt\Catch_; +use PhpParser\Node\Stmt\ElseIf_; +use PhpParser\Node\Stmt\For_; +use PhpParser\Node\Stmt\Foreach_; +use PhpParser\Node\Stmt\If_; +use PhpParser\Node\Stmt\While_; +use PhpParser\NodeVisitorAbstract; + +final class CyclomaticComplexityCalculatingVisitor extends NodeVisitorAbstract +{ + /** + * @var int + */ + private $cyclomaticComplexity = 1; + + public function enterNode(Node $node): void + { + /* @noinspection GetClassMissUseInspection */ + switch (get_class($node)) { + case BooleanAnd::class: + case BooleanOr::class: + case Case_::class: + case Catch_::class: + case ElseIf_::class: + case For_::class: + case Foreach_::class: + case If_::class: + case LogicalAnd::class: + case LogicalOr::class: + case Ternary::class: + case While_::class: + $this->cyclomaticComplexity++; + } + } + + public function cyclomaticComplexity(): int + { + return $this->cyclomaticComplexity; + } +} diff --git a/vendor/sebastian/diff/ChangeLog.md b/vendor/sebastian/diff/ChangeLog.md new file mode 100644 index 000000000..9bdcc5b6d --- /dev/null +++ b/vendor/sebastian/diff/ChangeLog.md @@ -0,0 +1,88 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.0.4] - 2020-10-26 + +### Fixed + +* `SebastianBergmann\Diff\Exception` now correctly extends `\Throwable` + +## [4.0.3] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [4.0.2] - 2020-06-30 + +### Added + +* This component is now supported on PHP 8 + +## [4.0.1] - 2020-05-08 + +### Fixed + +* [#99](https://github.com/sebastianbergmann/diff/pull/99): Regression in unified diff output of identical strings + +## [4.0.0] - 2020-02-07 + +### Removed + +* Removed support for PHP 7.1 and PHP 7.2 + +## [3.0.2] - 2019-02-04 + +### Changed + +* `Chunk::setLines()` now ensures that the `$lines` array only contains `Line` objects + +## [3.0.1] - 2018-06-10 + +### Fixed + +* Removed `"minimum-stability": "dev",` from `composer.json` + +## [3.0.0] - 2018-02-01 + +* The `StrictUnifiedDiffOutputBuilder` implementation of the `DiffOutputBuilderInterface` was added + +### Changed + +* The default `DiffOutputBuilderInterface` implementation now generates context lines (unchanged lines) + +### Removed + +* Removed support for PHP 7.0 + +### Fixed + +* [#70](https://github.com/sebastianbergmann/diff/issues/70): Diffing of arrays no longer works + +## [2.0.1] - 2017-08-03 + +### Fixed + +* [#66](https://github.com/sebastianbergmann/diff/pull/66): Restored backwards compatibility for PHPUnit 6.1.4, 6.2.0, 6.2.1, 6.2.2, and 6.2.3 + +## [2.0.0] - 2017-07-11 [YANKED] + +### Added + +* [#64](https://github.com/sebastianbergmann/diff/pull/64): Show line numbers for chunks of a diff + +### Removed + +* This component is no longer supported on PHP 5.6 + +[4.0.4]: https://github.com/sebastianbergmann/diff/compare/4.0.3...4.0.4 +[4.0.3]: https://github.com/sebastianbergmann/diff/compare/4.0.2...4.0.3 +[4.0.2]: https://github.com/sebastianbergmann/diff/compare/4.0.1...4.0.2 +[4.0.1]: https://github.com/sebastianbergmann/diff/compare/4.0.0...4.0.1 +[4.0.0]: https://github.com/sebastianbergmann/diff/compare/3.0.2...4.0.0 +[3.0.2]: https://github.com/sebastianbergmann/diff/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/sebastianbergmann/diff/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/sebastianbergmann/diff/compare/2.0...3.0.0 +[2.0.1]: https://github.com/sebastianbergmann/diff/compare/c341c98ce083db77f896a0aa64f5ee7652915970...2.0.1 +[2.0.0]: https://github.com/sebastianbergmann/diff/compare/1.4...c341c98ce083db77f896a0aa64f5ee7652915970 diff --git a/vendor/sebastian/diff/LICENSE b/vendor/sebastian/diff/LICENSE new file mode 100644 index 000000000..f22f31cf0 --- /dev/null +++ b/vendor/sebastian/diff/LICENSE @@ -0,0 +1,33 @@ +sebastian/diff + +Copyright (c) 2002-2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/diff/README.md b/vendor/sebastian/diff/README.md new file mode 100644 index 000000000..734b852de --- /dev/null +++ b/vendor/sebastian/diff/README.md @@ -0,0 +1,202 @@ +# sebastian/diff + +[![CI Status](https://github.com/sebastianbergmann/diff/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/diff/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/diff/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/diff) + +Diff implementation for PHP, factored out of PHPUnit into a stand-alone component. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/diff +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/diff +``` + +### Usage + +#### Generating diff + +The `Differ` class can be used to generate a textual representation of the difference between two strings: + +```php +<?php +use SebastianBergmann\Diff\Differ; + +$differ = new Differ; +print $differ->diff('foo', 'bar'); +``` + +The code above yields the output below: +```diff +--- Original ++++ New +@@ @@ +-foo ++bar +``` + +There are three output builders available in this package: + +#### UnifiedDiffOutputBuilder + +This is default builder, which generates the output close to udiff and is used by PHPUnit. + +```php +<?php + +use SebastianBergmann\Diff\Differ; +use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder; + +$builder = new UnifiedDiffOutputBuilder( + "--- Original\n+++ New\n", // custom header + false // do not add line numbers to the diff +); + +$differ = new Differ($builder); +print $differ->diff('foo', 'bar'); +``` + +#### StrictUnifiedDiffOutputBuilder + +Generates (strict) Unified diff's (unidiffs) with hunks, +similar to `diff -u` and compatible with `patch` and `git apply`. + +```php +<?php + +use SebastianBergmann\Diff\Differ; +use SebastianBergmann\Diff\Output\StrictUnifiedDiffOutputBuilder; + +$builder = new StrictUnifiedDiffOutputBuilder([ + 'collapseRanges' => true, // ranges of length one are rendered with the trailing `,1` + 'commonLineThreshold' => 6, // number of same lines before ending a new hunk and creating a new one (if needed) + 'contextLines' => 3, // like `diff: -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3 + 'fromFile' => null, + 'fromFileDate' => null, + 'toFile' => null, + 'toFileDate' => null, +]); + +$differ = new Differ($builder); +print $differ->diff('foo', 'bar'); +``` + +#### DiffOnlyOutputBuilder + +Output only the lines that differ. + +```php +<?php + +use SebastianBergmann\Diff\Differ; +use SebastianBergmann\Diff\Output\DiffOnlyOutputBuilder; + +$builder = new DiffOnlyOutputBuilder( + "--- Original\n+++ New\n" +); + +$differ = new Differ($builder); +print $differ->diff('foo', 'bar'); +``` + +#### DiffOutputBuilderInterface + +You can pass any output builder to the `Differ` class as longs as it implements the `DiffOutputBuilderInterface`. + +#### Parsing diff + +The `Parser` class can be used to parse a unified diff into an object graph: + +```php +use SebastianBergmann\Diff\Parser; +use SebastianBergmann\Git; + +$git = new Git('/usr/local/src/money'); + +$diff = $git->getDiff( + '948a1a07768d8edd10dcefa8315c1cbeffb31833', + 'c07a373d2399f3e686234c4f7f088d635eb9641b' +); + +$parser = new Parser; + +print_r($parser->parse($diff)); +``` + +The code above yields the output below: + + Array + ( + [0] => SebastianBergmann\Diff\Diff Object + ( + [from:SebastianBergmann\Diff\Diff:private] => a/tests/MoneyTest.php + [to:SebastianBergmann\Diff\Diff:private] => b/tests/MoneyTest.php + [chunks:SebastianBergmann\Diff\Diff:private] => Array + ( + [0] => SebastianBergmann\Diff\Chunk Object + ( + [start:SebastianBergmann\Diff\Chunk:private] => 87 + [startRange:SebastianBergmann\Diff\Chunk:private] => 7 + [end:SebastianBergmann\Diff\Chunk:private] => 87 + [endRange:SebastianBergmann\Diff\Chunk:private] => 7 + [lines:SebastianBergmann\Diff\Chunk:private] => Array + ( + [0] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::add + ) + + [1] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::newMoney + ) + + [2] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => */ + ) + + [3] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 2 + [content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyWithSameCurrencyObjectCanBeAdded() + ) + + [4] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 1 + [content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyObjectWithSameCurrencyCanBeAdded() + ) + + [5] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => { + ) + + [6] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => $a = new Money(1, new Currency('EUR')); + ) + + [7] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => $b = new Money(2, new Currency('EUR')); + ) + ) + ) + ) + ) + ) diff --git a/vendor/sebastian/diff/composer.json b/vendor/sebastian/diff/composer.json new file mode 100644 index 000000000..cf92202ba --- /dev/null +++ b/vendor/sebastian/diff/composer.json @@ -0,0 +1,47 @@ +{ + "name": "sebastian/diff", + "description": "Diff implementation", + "keywords": ["diff", "udiff", "unidiff", "unified diff"], + "homepage": "https://github.com/sebastianbergmann/diff", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]" + }, + { + "name": "Kore Nordmann", + "email": "[email protected]" + } + ], + "prefer-stable": true, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "autoload-dev": { + "classmap": [ + "tests/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + } +} diff --git a/vendor/sebastian/diff/src/Chunk.php b/vendor/sebastian/diff/src/Chunk.php new file mode 100644 index 000000000..16ae34f41 --- /dev/null +++ b/vendor/sebastian/diff/src/Chunk.php @@ -0,0 +1,89 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +final class Chunk +{ + /** + * @var int + */ + private $start; + + /** + * @var int + */ + private $startRange; + + /** + * @var int + */ + private $end; + + /** + * @var int + */ + private $endRange; + + /** + * @var Line[] + */ + private $lines; + + public function __construct(int $start = 0, int $startRange = 1, int $end = 0, int $endRange = 1, array $lines = []) + { + $this->start = $start; + $this->startRange = $startRange; + $this->end = $end; + $this->endRange = $endRange; + $this->lines = $lines; + } + + public function getStart(): int + { + return $this->start; + } + + public function getStartRange(): int + { + return $this->startRange; + } + + public function getEnd(): int + { + return $this->end; + } + + public function getEndRange(): int + { + return $this->endRange; + } + + /** + * @return Line[] + */ + public function getLines(): array + { + return $this->lines; + } + + /** + * @param Line[] $lines + */ + public function setLines(array $lines): void + { + foreach ($lines as $line) { + if (!$line instanceof Line) { + throw new InvalidArgumentException; + } + } + + $this->lines = $lines; + } +} diff --git a/vendor/sebastian/diff/src/Diff.php b/vendor/sebastian/diff/src/Diff.php new file mode 100644 index 000000000..17b2084f9 --- /dev/null +++ b/vendor/sebastian/diff/src/Diff.php @@ -0,0 +1,64 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +final class Diff +{ + /** + * @var string + */ + private $from; + + /** + * @var string + */ + private $to; + + /** + * @var Chunk[] + */ + private $chunks; + + /** + * @param Chunk[] $chunks + */ + public function __construct(string $from, string $to, array $chunks = []) + { + $this->from = $from; + $this->to = $to; + $this->chunks = $chunks; + } + + public function getFrom(): string + { + return $this->from; + } + + public function getTo(): string + { + return $this->to; + } + + /** + * @return Chunk[] + */ + public function getChunks(): array + { + return $this->chunks; + } + + /** + * @param Chunk[] $chunks + */ + public function setChunks(array $chunks): void + { + $this->chunks = $chunks; + } +} diff --git a/vendor/sebastian/diff/src/Differ.php b/vendor/sebastian/diff/src/Differ.php new file mode 100644 index 000000000..5a4d9d102 --- /dev/null +++ b/vendor/sebastian/diff/src/Differ.php @@ -0,0 +1,327 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +use const PHP_INT_SIZE; +use const PREG_SPLIT_DELIM_CAPTURE; +use const PREG_SPLIT_NO_EMPTY; +use function array_shift; +use function array_unshift; +use function array_values; +use function count; +use function current; +use function end; +use function get_class; +use function gettype; +use function is_array; +use function is_object; +use function is_string; +use function key; +use function min; +use function preg_split; +use function prev; +use function reset; +use function sprintf; +use function substr; +use SebastianBergmann\Diff\Output\DiffOutputBuilderInterface; +use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder; + +final class Differ +{ + public const OLD = 0; + + public const ADDED = 1; + + public const REMOVED = 2; + + public const DIFF_LINE_END_WARNING = 3; + + public const NO_LINE_END_EOF_WARNING = 4; + + /** + * @var DiffOutputBuilderInterface + */ + private $outputBuilder; + + /** + * @param DiffOutputBuilderInterface $outputBuilder + * + * @throws InvalidArgumentException + */ + public function __construct($outputBuilder = null) + { + if ($outputBuilder instanceof DiffOutputBuilderInterface) { + $this->outputBuilder = $outputBuilder; + } elseif (null === $outputBuilder) { + $this->outputBuilder = new UnifiedDiffOutputBuilder; + } elseif (is_string($outputBuilder)) { + // PHPUnit 6.1.4, 6.2.0, 6.2.1, 6.2.2, and 6.2.3 support + // @see https://github.com/sebastianbergmann/phpunit/issues/2734#issuecomment-314514056 + // @deprecated + $this->outputBuilder = new UnifiedDiffOutputBuilder($outputBuilder); + } else { + throw new InvalidArgumentException( + sprintf( + 'Expected builder to be an instance of DiffOutputBuilderInterface, <null> or a string, got %s.', + is_object($outputBuilder) ? 'instance of "' . get_class($outputBuilder) . '"' : gettype($outputBuilder) . ' "' . $outputBuilder . '"' + ) + ); + } + } + + /** + * Returns the diff between two arrays or strings as string. + * + * @param array|string $from + * @param array|string $to + */ + public function diff($from, $to, LongestCommonSubsequenceCalculator $lcs = null): string + { + $diff = $this->diffToArray( + $this->normalizeDiffInput($from), + $this->normalizeDiffInput($to), + $lcs + ); + + return $this->outputBuilder->getDiff($diff); + } + + /** + * Returns the diff between two arrays or strings as array. + * + * Each array element contains two elements: + * - [0] => mixed $token + * - [1] => 2|1|0 + * + * - 2: REMOVED: $token was removed from $from + * - 1: ADDED: $token was added to $from + * - 0: OLD: $token is not changed in $to + * + * @param array|string $from + * @param array|string $to + * @param LongestCommonSubsequenceCalculator $lcs + */ + public function diffToArray($from, $to, LongestCommonSubsequenceCalculator $lcs = null): array + { + if (is_string($from)) { + $from = $this->splitStringByLines($from); + } elseif (!is_array($from)) { + throw new InvalidArgumentException('"from" must be an array or string.'); + } + + if (is_string($to)) { + $to = $this->splitStringByLines($to); + } elseif (!is_array($to)) { + throw new InvalidArgumentException('"to" must be an array or string.'); + } + + [$from, $to, $start, $end] = self::getArrayDiffParted($from, $to); + + if ($lcs === null) { + $lcs = $this->selectLcsImplementation($from, $to); + } + + $common = $lcs->calculate(array_values($from), array_values($to)); + $diff = []; + + foreach ($start as $token) { + $diff[] = [$token, self::OLD]; + } + + reset($from); + reset($to); + + foreach ($common as $token) { + while (($fromToken = reset($from)) !== $token) { + $diff[] = [array_shift($from), self::REMOVED]; + } + + while (($toToken = reset($to)) !== $token) { + $diff[] = [array_shift($to), self::ADDED]; + } + + $diff[] = [$token, self::OLD]; + + array_shift($from); + array_shift($to); + } + + while (($token = array_shift($from)) !== null) { + $diff[] = [$token, self::REMOVED]; + } + + while (($token = array_shift($to)) !== null) { + $diff[] = [$token, self::ADDED]; + } + + foreach ($end as $token) { + $diff[] = [$token, self::OLD]; + } + + if ($this->detectUnmatchedLineEndings($diff)) { + array_unshift($diff, ["#Warning: Strings contain different line endings!\n", self::DIFF_LINE_END_WARNING]); + } + + return $diff; + } + + /** + * Casts variable to string if it is not a string or array. + * + * @return array|string + */ + private function normalizeDiffInput($input) + { + if (!is_array($input) && !is_string($input)) { + return (string) $input; + } + + return $input; + } + + /** + * Checks if input is string, if so it will split it line-by-line. + */ + private function splitStringByLines(string $input): array + { + return preg_split('/(.*\R)/', $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + } + + private function selectLcsImplementation(array $from, array $to): LongestCommonSubsequenceCalculator + { + // We do not want to use the time-efficient implementation if its memory + // footprint will probably exceed this value. Note that the footprint + // calculation is only an estimation for the matrix and the LCS method + // will typically allocate a bit more memory than this. + $memoryLimit = 100 * 1024 * 1024; + + if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) { + return new MemoryEfficientLongestCommonSubsequenceCalculator; + } + + return new TimeEfficientLongestCommonSubsequenceCalculator; + } + + /** + * Calculates the estimated memory footprint for the DP-based method. + * + * @return float|int + */ + private function calculateEstimatedFootprint(array $from, array $to) + { + $itemSize = PHP_INT_SIZE === 4 ? 76 : 144; + + return $itemSize * min(count($from), count($to)) ** 2; + } + + /** + * Returns true if line ends don't match in a diff. + */ + private function detectUnmatchedLineEndings(array $diff): bool + { + $newLineBreaks = ['' => true]; + $oldLineBreaks = ['' => true]; + + foreach ($diff as $entry) { + if (self::OLD === $entry[1]) { + $ln = $this->getLinebreak($entry[0]); + $oldLineBreaks[$ln] = true; + $newLineBreaks[$ln] = true; + } elseif (self::ADDED === $entry[1]) { + $newLineBreaks[$this->getLinebreak($entry[0])] = true; + } elseif (self::REMOVED === $entry[1]) { + $oldLineBreaks[$this->getLinebreak($entry[0])] = true; + } + } + + // if either input or output is a single line without breaks than no warning should be raised + if (['' => true] === $newLineBreaks || ['' => true] === $oldLineBreaks) { + return false; + } + + // two way compare + foreach ($newLineBreaks as $break => $set) { + if (!isset($oldLineBreaks[$break])) { + return true; + } + } + + foreach ($oldLineBreaks as $break => $set) { + if (!isset($newLineBreaks[$break])) { + return true; + } + } + + return false; + } + + private function getLinebreak($line): string + { + if (!is_string($line)) { + return ''; + } + + $lc = substr($line, -1); + + if ("\r" === $lc) { + return "\r"; + } + + if ("\n" !== $lc) { + return ''; + } + + if ("\r\n" === substr($line, -2)) { + return "\r\n"; + } + + return "\n"; + } + + private static function getArrayDiffParted(array &$from, array &$to): array + { + $start = []; + $end = []; + + reset($to); + + foreach ($from as $k => $v) { + $toK = key($to); + + if ($toK === $k && $v === $to[$k]) { + $start[$k] = $v; + + unset($from[$k], $to[$k]); + } else { + break; + } + } + + end($from); + end($to); + + do { + $fromK = key($from); + $toK = key($to); + + if (null === $fromK || null === $toK || current($from) !== current($to)) { + break; + } + + prev($from); + prev($to); + + $end = [$fromK => $from[$fromK]] + $end; + unset($from[$fromK], $to[$toK]); + } while (true); + + return [$from, $to, $start, $end]; + } +} diff --git a/vendor/sebastian/diff/src/Exception/ConfigurationException.php b/vendor/sebastian/diff/src/Exception/ConfigurationException.php new file mode 100644 index 000000000..b767b2194 --- /dev/null +++ b/vendor/sebastian/diff/src/Exception/ConfigurationException.php @@ -0,0 +1,38 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +use function get_class; +use function gettype; +use function is_object; +use function sprintf; +use Exception; + +final class ConfigurationException extends InvalidArgumentException +{ + public function __construct( + string $option, + string $expected, + $value, + int $code = 0, + Exception $previous = null + ) { + parent::__construct( + sprintf( + 'Option "%s" must be %s, got "%s".', + $option, + $expected, + is_object($value) ? get_class($value) : (null === $value ? '<null>' : gettype($value) . '#' . $value) + ), + $code, + $previous + ); + } +} diff --git a/vendor/sebastian/diff/src/Exception/Exception.php b/vendor/sebastian/diff/src/Exception/Exception.php new file mode 100644 index 000000000..e20d32036 --- /dev/null +++ b/vendor/sebastian/diff/src/Exception/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/diff/src/Exception/InvalidArgumentException.php b/vendor/sebastian/diff/src/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..846ac3fbd --- /dev/null +++ b/vendor/sebastian/diff/src/Exception/InvalidArgumentException.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ +} diff --git a/vendor/sebastian/diff/src/Line.php b/vendor/sebastian/diff/src/Line.php new file mode 100644 index 000000000..3596ed264 --- /dev/null +++ b/vendor/sebastian/diff/src/Line.php @@ -0,0 +1,45 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +final class Line +{ + public const ADDED = 1; + + public const REMOVED = 2; + + public const UNCHANGED = 3; + + /** + * @var int + */ + private $type; + + /** + * @var string + */ + private $content; + + public function __construct(int $type = self::UNCHANGED, string $content = '') + { + $this->type = $type; + $this->content = $content; + } + + public function getContent(): string + { + return $this->content; + } + + public function getType(): int + { + return $this->type; + } +} diff --git a/vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php b/vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php new file mode 100644 index 000000000..dea8fe1cb --- /dev/null +++ b/vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php @@ -0,0 +1,18 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +interface LongestCommonSubsequenceCalculator +{ + /** + * Calculates the longest common subsequence of two arrays. + */ + public function calculate(array $from, array $to): array; +} diff --git a/vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php b/vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php new file mode 100644 index 000000000..0b626eaff --- /dev/null +++ b/vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php @@ -0,0 +1,88 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +use function array_fill; +use function array_merge; +use function array_reverse; +use function array_slice; +use function count; +use function in_array; +use function max; + +final class MemoryEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator +{ + /** + * {@inheritdoc} + */ + public function calculate(array $from, array $to): array + { + $cFrom = count($from); + $cTo = count($to); + + if ($cFrom === 0) { + return []; + } + + if ($cFrom === 1) { + if (in_array($from[0], $to, true)) { + return [$from[0]]; + } + + return []; + } + + $i = (int) ($cFrom / 2); + $fromStart = array_slice($from, 0, $i); + $fromEnd = array_slice($from, $i); + $llB = $this->length($fromStart, $to); + $llE = $this->length(array_reverse($fromEnd), array_reverse($to)); + $jMax = 0; + $max = 0; + + for ($j = 0; $j <= $cTo; $j++) { + $m = $llB[$j] + $llE[$cTo - $j]; + + if ($m >= $max) { + $max = $m; + $jMax = $j; + } + } + + $toStart = array_slice($to, 0, $jMax); + $toEnd = array_slice($to, $jMax); + + return array_merge( + $this->calculate($fromStart, $toStart), + $this->calculate($fromEnd, $toEnd) + ); + } + + private function length(array $from, array $to): array + { + $current = array_fill(0, count($to) + 1, 0); + $cFrom = count($from); + $cTo = count($to); + + for ($i = 0; $i < $cFrom; $i++) { + $prev = $current; + + for ($j = 0; $j < $cTo; $j++) { + if ($from[$i] === $to[$j]) { + $current[$j + 1] = $prev[$j] + 1; + } else { + $current[$j + 1] = max($current[$j], $prev[$j + 1]); + } + } + } + + return $current; + } +} diff --git a/vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php b/vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php new file mode 100644 index 000000000..e55757c38 --- /dev/null +++ b/vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php @@ -0,0 +1,52 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff\Output; + +use function count; + +abstract class AbstractChunkOutputBuilder implements DiffOutputBuilderInterface +{ + /** + * Takes input of the diff array and returns the common parts. + * Iterates through diff line by line. + */ + protected function getCommonChunks(array $diff, int $lineThreshold = 5): array + { + $diffSize = count($diff); + $capturing = false; + $chunkStart = 0; + $chunkSize = 0; + $commonChunks = []; + + for ($i = 0; $i < $diffSize; ++$i) { + if ($diff[$i][1] === 0 /* OLD */) { + if ($capturing === false) { + $capturing = true; + $chunkStart = $i; + $chunkSize = 0; + } else { + ++$chunkSize; + } + } elseif ($capturing !== false) { + if ($chunkSize >= $lineThreshold) { + $commonChunks[$chunkStart] = $chunkStart + $chunkSize; + } + + $capturing = false; + } + } + + if ($capturing !== false && $chunkSize >= $lineThreshold) { + $commonChunks[$chunkStart] = $chunkStart + $chunkSize; + } + + return $commonChunks; + } +} diff --git a/vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php b/vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php new file mode 100644 index 000000000..f79a935cb --- /dev/null +++ b/vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php @@ -0,0 +1,72 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff\Output; + +use function fclose; +use function fopen; +use function fwrite; +use function stream_get_contents; +use function substr; +use SebastianBergmann\Diff\Differ; + +/** + * Builds a diff string representation in a loose unified diff format + * listing only changes lines. Does not include line numbers. + */ +final class DiffOnlyOutputBuilder implements DiffOutputBuilderInterface +{ + /** + * @var string + */ + private $header; + + public function __construct(string $header = "--- Original\n+++ New\n") + { + $this->header = $header; + } + + public function getDiff(array $diff): string + { + $buffer = fopen('php://memory', 'r+b'); + + if ('' !== $this->header) { + fwrite($buffer, $this->header); + + if ("\n" !== substr($this->header, -1, 1)) { + fwrite($buffer, "\n"); + } + } + + foreach ($diff as $diffEntry) { + if ($diffEntry[1] === Differ::ADDED) { + fwrite($buffer, '+' . $diffEntry[0]); + } elseif ($diffEntry[1] === Differ::REMOVED) { + fwrite($buffer, '-' . $diffEntry[0]); + } elseif ($diffEntry[1] === Differ::DIFF_LINE_END_WARNING) { + fwrite($buffer, ' ' . $diffEntry[0]); + + continue; // Warnings should not be tested for line break, it will always be there + } else { /* Not changed (old) 0 */ + continue; // we didn't write the non changs line, so do not add a line break either + } + + $lc = substr($diffEntry[0], -1); + + if ($lc !== "\n" && $lc !== "\r") { + fwrite($buffer, "\n"); // \No newline at end of file + } + } + + $diff = stream_get_contents($buffer, -1, 0); + fclose($buffer); + + return $diff; + } +} diff --git a/vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php b/vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php new file mode 100644 index 000000000..0e18f9f2e --- /dev/null +++ b/vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php @@ -0,0 +1,19 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff\Output; + +/** + * Defines how an output builder should take a generated + * diff array and return a string representation of that diff. + */ +interface DiffOutputBuilderInterface +{ + public function getDiff(array $diff): string; +} diff --git a/vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php b/vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php new file mode 100644 index 000000000..9c55ab2aa --- /dev/null +++ b/vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php @@ -0,0 +1,338 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff\Output; + +use function array_merge; +use function array_splice; +use function count; +use function fclose; +use function fopen; +use function fwrite; +use function is_bool; +use function is_int; +use function is_string; +use function max; +use function min; +use function sprintf; +use function stream_get_contents; +use function substr; +use SebastianBergmann\Diff\ConfigurationException; +use SebastianBergmann\Diff\Differ; + +/** + * Strict Unified diff output builder. + * + * Generates (strict) Unified diff's (unidiffs) with hunks. + */ +final class StrictUnifiedDiffOutputBuilder implements DiffOutputBuilderInterface +{ + private static $default = [ + 'collapseRanges' => true, // ranges of length one are rendered with the trailing `,1` + 'commonLineThreshold' => 6, // number of same lines before ending a new hunk and creating a new one (if needed) + 'contextLines' => 3, // like `diff: -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3 + 'fromFile' => null, + 'fromFileDate' => null, + 'toFile' => null, + 'toFileDate' => null, + ]; + + /** + * @var bool + */ + private $changed; + + /** + * @var bool + */ + private $collapseRanges; + + /** + * @var int >= 0 + */ + private $commonLineThreshold; + + /** + * @var string + */ + private $header; + + /** + * @var int >= 0 + */ + private $contextLines; + + public function __construct(array $options = []) + { + $options = array_merge(self::$default, $options); + + if (!is_bool($options['collapseRanges'])) { + throw new ConfigurationException('collapseRanges', 'a bool', $options['collapseRanges']); + } + + if (!is_int($options['contextLines']) || $options['contextLines'] < 0) { + throw new ConfigurationException('contextLines', 'an int >= 0', $options['contextLines']); + } + + if (!is_int($options['commonLineThreshold']) || $options['commonLineThreshold'] <= 0) { + throw new ConfigurationException('commonLineThreshold', 'an int > 0', $options['commonLineThreshold']); + } + + $this->assertString($options, 'fromFile'); + $this->assertString($options, 'toFile'); + $this->assertStringOrNull($options, 'fromFileDate'); + $this->assertStringOrNull($options, 'toFileDate'); + + $this->header = sprintf( + "--- %s%s\n+++ %s%s\n", + $options['fromFile'], + null === $options['fromFileDate'] ? '' : "\t" . $options['fromFileDate'], + $options['toFile'], + null === $options['toFileDate'] ? '' : "\t" . $options['toFileDate'] + ); + + $this->collapseRanges = $options['collapseRanges']; + $this->commonLineThreshold = $options['commonLineThreshold']; + $this->contextLines = $options['contextLines']; + } + + public function getDiff(array $diff): string + { + if (0 === count($diff)) { + return ''; + } + + $this->changed = false; + + $buffer = fopen('php://memory', 'r+b'); + fwrite($buffer, $this->header); + + $this->writeDiffHunks($buffer, $diff); + + if (!$this->changed) { + fclose($buffer); + + return ''; + } + + $diff = stream_get_contents($buffer, -1, 0); + + fclose($buffer); + + // If the last char is not a linebreak: add it. + // This might happen when both the `from` and `to` do not have a trailing linebreak + $last = substr($diff, -1); + + return "\n" !== $last && "\r" !== $last + ? $diff . "\n" + : $diff; + } + + private function writeDiffHunks($output, array $diff): void + { + // detect "No newline at end of file" and insert into `$diff` if needed + + $upperLimit = count($diff); + + if (0 === $diff[$upperLimit - 1][1]) { + $lc = substr($diff[$upperLimit - 1][0], -1); + + if ("\n" !== $lc) { + array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]); + } + } else { + // search back for the last `+` and `-` line, + // check if has trailing linebreak, else add under it warning under it + $toFind = [1 => true, 2 => true]; + + for ($i = $upperLimit - 1; $i >= 0; --$i) { + if (isset($toFind[$diff[$i][1]])) { + unset($toFind[$diff[$i][1]]); + $lc = substr($diff[$i][0], -1); + + if ("\n" !== $lc) { + array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]); + } + + if (!count($toFind)) { + break; + } + } + } + } + + // write hunks to output buffer + + $cutOff = max($this->commonLineThreshold, $this->contextLines); + $hunkCapture = false; + $sameCount = $toRange = $fromRange = 0; + $toStart = $fromStart = 1; + $i = 0; + + /** @var int $i */ + foreach ($diff as $i => $entry) { + if (0 === $entry[1]) { // same + if (false === $hunkCapture) { + ++$fromStart; + ++$toStart; + + continue; + } + + ++$sameCount; + ++$toRange; + ++$fromRange; + + if ($sameCount === $cutOff) { + $contextStartOffset = ($hunkCapture - $this->contextLines) < 0 + ? $hunkCapture + : $this->contextLines; + + // note: $contextEndOffset = $this->contextLines; + // + // because we never go beyond the end of the diff. + // with the cutoff/contextlines here the follow is never true; + // + // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) { + // $contextEndOffset = count($diff) - 1; + // } + // + // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop + + $this->writeHunk( + $diff, + $hunkCapture - $contextStartOffset, + $i - $cutOff + $this->contextLines + 1, + $fromStart - $contextStartOffset, + $fromRange - $cutOff + $contextStartOffset + $this->contextLines, + $toStart - $contextStartOffset, + $toRange - $cutOff + $contextStartOffset + $this->contextLines, + $output + ); + + $fromStart += $fromRange; + $toStart += $toRange; + + $hunkCapture = false; + $sameCount = $toRange = $fromRange = 0; + } + + continue; + } + + $sameCount = 0; + + if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) { + continue; + } + + $this->changed = true; + + if (false === $hunkCapture) { + $hunkCapture = $i; + } + + if (Differ::ADDED === $entry[1]) { // added + ++$toRange; + } + + if (Differ::REMOVED === $entry[1]) { // removed + ++$fromRange; + } + } + + if (false === $hunkCapture) { + return; + } + + // we end here when cutoff (commonLineThreshold) was not reached, but we where capturing a hunk, + // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold + + $contextStartOffset = $hunkCapture - $this->contextLines < 0 + ? $hunkCapture + : $this->contextLines; + + // prevent trying to write out more common lines than there are in the diff _and_ + // do not write more than configured through the context lines + $contextEndOffset = min($sameCount, $this->contextLines); + + $fromRange -= $sameCount; + $toRange -= $sameCount; + + $this->writeHunk( + $diff, + $hunkCapture - $contextStartOffset, + $i - $sameCount + $contextEndOffset + 1, + $fromStart - $contextStartOffset, + $fromRange + $contextStartOffset + $contextEndOffset, + $toStart - $contextStartOffset, + $toRange + $contextStartOffset + $contextEndOffset, + $output + ); + } + + private function writeHunk( + array $diff, + int $diffStartIndex, + int $diffEndIndex, + int $fromStart, + int $fromRange, + int $toStart, + int $toRange, + $output + ): void { + fwrite($output, '@@ -' . $fromStart); + + if (!$this->collapseRanges || 1 !== $fromRange) { + fwrite($output, ',' . $fromRange); + } + + fwrite($output, ' +' . $toStart); + + if (!$this->collapseRanges || 1 !== $toRange) { + fwrite($output, ',' . $toRange); + } + + fwrite($output, " @@\n"); + + for ($i = $diffStartIndex; $i < $diffEndIndex; ++$i) { + if ($diff[$i][1] === Differ::ADDED) { + $this->changed = true; + fwrite($output, '+' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::REMOVED) { + $this->changed = true; + fwrite($output, '-' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::OLD) { + fwrite($output, ' ' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) { + $this->changed = true; + fwrite($output, $diff[$i][0]); + } + //} elseif ($diff[$i][1] === Differ::DIFF_LINE_END_WARNING) { // custom comment inserted by PHPUnit/diff package + // skip + //} else { + // unknown/invalid + //} + } + } + + private function assertString(array $options, string $option): void + { + if (!is_string($options[$option])) { + throw new ConfigurationException($option, 'a string', $options[$option]); + } + } + + private function assertStringOrNull(array $options, string $option): void + { + if (null !== $options[$option] && !is_string($options[$option])) { + throw new ConfigurationException($option, 'a string or <null>', $options[$option]); + } + } +} diff --git a/vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php b/vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php new file mode 100644 index 000000000..8aae64504 --- /dev/null +++ b/vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php @@ -0,0 +1,272 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff\Output; + +use function array_splice; +use function count; +use function fclose; +use function fopen; +use function fwrite; +use function max; +use function min; +use function stream_get_contents; +use function strlen; +use function substr; +use SebastianBergmann\Diff\Differ; + +/** + * Builds a diff string representation in unified diff format in chunks. + */ +final class UnifiedDiffOutputBuilder extends AbstractChunkOutputBuilder +{ + /** + * @var bool + */ + private $collapseRanges = true; + + /** + * @var int >= 0 + */ + private $commonLineThreshold = 6; + + /** + * @var int >= 0 + */ + private $contextLines = 3; + + /** + * @var string + */ + private $header; + + /** + * @var bool + */ + private $addLineNumbers; + + public function __construct(string $header = "--- Original\n+++ New\n", bool $addLineNumbers = false) + { + $this->header = $header; + $this->addLineNumbers = $addLineNumbers; + } + + public function getDiff(array $diff): string + { + $buffer = fopen('php://memory', 'r+b'); + + if ('' !== $this->header) { + fwrite($buffer, $this->header); + + if ("\n" !== substr($this->header, -1, 1)) { + fwrite($buffer, "\n"); + } + } + + if (0 !== count($diff)) { + $this->writeDiffHunks($buffer, $diff); + } + + $diff = stream_get_contents($buffer, -1, 0); + + fclose($buffer); + + // If the diff is non-empty and last char is not a linebreak: add it. + // This might happen when both the `from` and `to` do not have a trailing linebreak + $last = substr($diff, -1); + + return 0 !== strlen($diff) && "\n" !== $last && "\r" !== $last + ? $diff . "\n" + : $diff; + } + + private function writeDiffHunks($output, array $diff): void + { + // detect "No newline at end of file" and insert into `$diff` if needed + + $upperLimit = count($diff); + + if (0 === $diff[$upperLimit - 1][1]) { + $lc = substr($diff[$upperLimit - 1][0], -1); + + if ("\n" !== $lc) { + array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]); + } + } else { + // search back for the last `+` and `-` line, + // check if has trailing linebreak, else add under it warning under it + $toFind = [1 => true, 2 => true]; + + for ($i = $upperLimit - 1; $i >= 0; --$i) { + if (isset($toFind[$diff[$i][1]])) { + unset($toFind[$diff[$i][1]]); + $lc = substr($diff[$i][0], -1); + + if ("\n" !== $lc) { + array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]); + } + + if (!count($toFind)) { + break; + } + } + } + } + + // write hunks to output buffer + + $cutOff = max($this->commonLineThreshold, $this->contextLines); + $hunkCapture = false; + $sameCount = $toRange = $fromRange = 0; + $toStart = $fromStart = 1; + $i = 0; + + /** @var int $i */ + foreach ($diff as $i => $entry) { + if (0 === $entry[1]) { // same + if (false === $hunkCapture) { + ++$fromStart; + ++$toStart; + + continue; + } + + ++$sameCount; + ++$toRange; + ++$fromRange; + + if ($sameCount === $cutOff) { + $contextStartOffset = ($hunkCapture - $this->contextLines) < 0 + ? $hunkCapture + : $this->contextLines; + + // note: $contextEndOffset = $this->contextLines; + // + // because we never go beyond the end of the diff. + // with the cutoff/contextlines here the follow is never true; + // + // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) { + // $contextEndOffset = count($diff) - 1; + // } + // + // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop + + $this->writeHunk( + $diff, + $hunkCapture - $contextStartOffset, + $i - $cutOff + $this->contextLines + 1, + $fromStart - $contextStartOffset, + $fromRange - $cutOff + $contextStartOffset + $this->contextLines, + $toStart - $contextStartOffset, + $toRange - $cutOff + $contextStartOffset + $this->contextLines, + $output + ); + + $fromStart += $fromRange; + $toStart += $toRange; + + $hunkCapture = false; + $sameCount = $toRange = $fromRange = 0; + } + + continue; + } + + $sameCount = 0; + + if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) { + continue; + } + + if (false === $hunkCapture) { + $hunkCapture = $i; + } + + if (Differ::ADDED === $entry[1]) { + ++$toRange; + } + + if (Differ::REMOVED === $entry[1]) { + ++$fromRange; + } + } + + if (false === $hunkCapture) { + return; + } + + // we end here when cutoff (commonLineThreshold) was not reached, but we where capturing a hunk, + // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold + + $contextStartOffset = $hunkCapture - $this->contextLines < 0 + ? $hunkCapture + : $this->contextLines; + + // prevent trying to write out more common lines than there are in the diff _and_ + // do not write more than configured through the context lines + $contextEndOffset = min($sameCount, $this->contextLines); + + $fromRange -= $sameCount; + $toRange -= $sameCount; + + $this->writeHunk( + $diff, + $hunkCapture - $contextStartOffset, + $i - $sameCount + $contextEndOffset + 1, + $fromStart - $contextStartOffset, + $fromRange + $contextStartOffset + $contextEndOffset, + $toStart - $contextStartOffset, + $toRange + $contextStartOffset + $contextEndOffset, + $output + ); + } + + private function writeHunk( + array $diff, + int $diffStartIndex, + int $diffEndIndex, + int $fromStart, + int $fromRange, + int $toStart, + int $toRange, + $output + ): void { + if ($this->addLineNumbers) { + fwrite($output, '@@ -' . $fromStart); + + if (!$this->collapseRanges || 1 !== $fromRange) { + fwrite($output, ',' . $fromRange); + } + + fwrite($output, ' +' . $toStart); + + if (!$this->collapseRanges || 1 !== $toRange) { + fwrite($output, ',' . $toRange); + } + + fwrite($output, " @@\n"); + } else { + fwrite($output, "@@ @@\n"); + } + + for ($i = $diffStartIndex; $i < $diffEndIndex; ++$i) { + if ($diff[$i][1] === Differ::ADDED) { + fwrite($output, '+' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::REMOVED) { + fwrite($output, '-' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::OLD) { + fwrite($output, ' ' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) { + fwrite($output, "\n"); // $diff[$i][0] + } else { /* Not changed (old) Differ::OLD or Warning Differ::DIFF_LINE_END_WARNING */ + fwrite($output, ' ' . $diff[$i][0]); + } + } + } +} diff --git a/vendor/sebastian/diff/src/Parser.php b/vendor/sebastian/diff/src/Parser.php new file mode 100644 index 000000000..cc9e38871 --- /dev/null +++ b/vendor/sebastian/diff/src/Parser.php @@ -0,0 +1,110 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +use function array_pop; +use function count; +use function max; +use function preg_match; +use function preg_split; + +/** + * Unified diff parser. + */ +final class Parser +{ + /** + * @return Diff[] + */ + public function parse(string $string): array + { + $lines = preg_split('(\r\n|\r|\n)', $string); + + if (!empty($lines) && $lines[count($lines) - 1] === '') { + array_pop($lines); + } + + $lineCount = count($lines); + $diffs = []; + $diff = null; + $collected = []; + + for ($i = 0; $i < $lineCount; ++$i) { + if (preg_match('#^---\h+"?(?P<file>[^\\v\\t"]+)#', $lines[$i], $fromMatch) && + preg_match('#^\\+\\+\\+\\h+"?(?P<file>[^\\v\\t"]+)#', $lines[$i + 1], $toMatch)) { + if ($diff !== null) { + $this->parseFileDiff($diff, $collected); + + $diffs[] = $diff; + $collected = []; + } + + $diff = new Diff($fromMatch['file'], $toMatch['file']); + + ++$i; + } else { + if (preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) { + continue; + } + + $collected[] = $lines[$i]; + } + } + + if ($diff !== null && count($collected)) { + $this->parseFileDiff($diff, $collected); + + $diffs[] = $diff; + } + + return $diffs; + } + + private function parseFileDiff(Diff $diff, array $lines): void + { + $chunks = []; + $chunk = null; + $diffLines = []; + + foreach ($lines as $line) { + if (preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match)) { + $chunk = new Chunk( + (int) $match['start'], + isset($match['startrange']) ? max(1, (int) $match['startrange']) : 1, + (int) $match['end'], + isset($match['endrange']) ? max(1, (int) $match['endrange']) : 1 + ); + + $chunks[] = $chunk; + $diffLines = []; + + continue; + } + + if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) { + $type = Line::UNCHANGED; + + if ($match['type'] === '+') { + $type = Line::ADDED; + } elseif ($match['type'] === '-') { + $type = Line::REMOVED; + } + + $diffLines[] = new Line($type, $match['line']); + + if (null !== $chunk) { + $chunk->setLines($diffLines); + } + } + } + + $diff->setChunks($chunks); + } +} diff --git a/vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php b/vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php new file mode 100644 index 000000000..fd19cac76 --- /dev/null +++ b/vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php @@ -0,0 +1,70 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/diff. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Diff; + +use function array_reverse; +use function count; +use function max; +use SplFixedArray; + +final class TimeEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator +{ + /** + * {@inheritdoc} + */ + public function calculate(array $from, array $to): array + { + $common = []; + $fromLength = count($from); + $toLength = count($to); + $width = $fromLength + 1; + $matrix = new SplFixedArray($width * ($toLength + 1)); + + for ($i = 0; $i <= $fromLength; ++$i) { + $matrix[$i] = 0; + } + + for ($j = 0; $j <= $toLength; ++$j) { + $matrix[$j * $width] = 0; + } + + for ($i = 1; $i <= $fromLength; ++$i) { + for ($j = 1; $j <= $toLength; ++$j) { + $o = ($j * $width) + $i; + $matrix[$o] = max( + $matrix[$o - 1], + $matrix[$o - $width], + $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0 + ); + } + } + + $i = $fromLength; + $j = $toLength; + + while ($i > 0 && $j > 0) { + if ($from[$i - 1] === $to[$j - 1]) { + $common[] = $from[$i - 1]; + --$i; + --$j; + } else { + $o = ($j * $width) + $i; + + if ($matrix[$o - $width] > $matrix[$o - 1]) { + --$j; + } else { + --$i; + } + } + } + + return array_reverse($common); + } +} diff --git a/vendor/sebastian/environment/ChangeLog.md b/vendor/sebastian/environment/ChangeLog.md new file mode 100644 index 000000000..67daf0356 --- /dev/null +++ b/vendor/sebastian/environment/ChangeLog.md @@ -0,0 +1,169 @@ +# Changes in sebastianbergmann/environment + +All notable changes in `sebastianbergmann/environment` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [5.1.3] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [5.1.2] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [5.1.1] - 2020-06-15 + +### Changed + +* Tests etc. are now ignored for archive exports + +## [5.1.0] - 2020-04-14 + +### Added + +* `Runtime::performsJustInTimeCompilation()` returns `true` if PHP 8's JIT is active, `false` otherwise + +## [5.0.2] - 2020-03-31 + +### Fixed + +* [#55](https://github.com/sebastianbergmann/environment/issues/55): `stty` command is executed even if no tty is available + +## [5.0.1] - 2020-02-19 + +### Changed + +* `Runtime::getNameWithVersionAndCodeCoverageDriver()` now prioritizes PCOV over Xdebug when both extensions are loaded (just like php-code-coverage does) + +## [5.0.0] - 2020-02-07 + +### Removed + +* This component is no longer supported on PHP 7.1 and PHP 7.2 + +## [4.2.3] - 2019-11-20 + +### Changed + +* [#50](https://github.com/sebastianbergmann/environment/pull/50): Windows improvements to console capabilities + +### Fixed + +* [#49](https://github.com/sebastianbergmann/environment/issues/49): Detection how OpCache handles docblocks does not work correctly when PHPDBG is used + +## [4.2.2] - 2019-05-05 + +### Fixed + +* [#44](https://github.com/sebastianbergmann/environment/pull/44): `TypeError` in `Console::getNumberOfColumnsInteractive()` + +## [4.2.1] - 2019-04-25 + +### Fixed + +* Fixed an issue in `Runtime::getCurrentSettings()` + +## [4.2.0] - 2019-04-25 + +### Added + +* [#36](https://github.com/sebastianbergmann/environment/pull/36): `Runtime::getCurrentSettings()` + +## [4.1.0] - 2019-02-01 + +### Added + +* Implemented `Runtime::getNameWithVersionAndCodeCoverageDriver()` method +* [#34](https://github.com/sebastianbergmann/environment/pull/34): Support for PCOV extension + +## [4.0.2] - 2019-01-28 + +### Fixed + +* [#33](https://github.com/sebastianbergmann/environment/issues/33): `Runtime::discardsComments()` returns true too eagerly + +### Removed + +* Removed support for Zend Optimizer+ in `Runtime::discardsComments()` + +## [4.0.1] - 2018-11-25 + +### Fixed + +* [#31](https://github.com/sebastianbergmann/environment/issues/31): Regressions in `Console` class + +## [4.0.0] - 2018-10-23 [YANKED] + +### Fixed + +* [#25](https://github.com/sebastianbergmann/environment/pull/25): `Console::hasColorSupport()` does not work on Windows + +### Removed + +* This component is no longer supported on PHP 7.0 + +## [3.1.0] - 2017-07-01 + +### Added + +* [#21](https://github.com/sebastianbergmann/environment/issues/21): Equivalent of `PHP_OS_FAMILY` (for PHP < 7.2) + +## [3.0.4] - 2017-06-20 + +### Fixed + +* [#20](https://github.com/sebastianbergmann/environment/pull/20): PHP 7 mode of HHVM not forced + +## [3.0.3] - 2017-05-18 + +### Fixed + +* [#18](https://github.com/sebastianbergmann/environment/issues/18): `Uncaught TypeError: preg_match() expects parameter 2 to be string, null given` + +## [3.0.2] - 2017-04-21 + +### Fixed + +* [#17](https://github.com/sebastianbergmann/environment/issues/17): `Uncaught TypeError: trim() expects parameter 1 to be string, boolean given` + +## [3.0.1] - 2017-04-21 + +### Fixed + +* Fixed inverted logic in `Runtime::discardsComments()` + +## [3.0.0] - 2017-04-21 + +### Added + +* Implemented `Runtime::discardsComments()` for querying whether the PHP runtime discards annotations + +### Removed + +* This component is no longer supported on PHP 5.6 + +[5.1.3]: https://github.com/sebastianbergmann/environment/compare/5.1.2...5.1.3 +[5.1.2]: https://github.com/sebastianbergmann/environment/compare/5.1.1...5.1.2 +[5.1.1]: https://github.com/sebastianbergmann/environment/compare/5.1.0...5.1.1 +[5.1.0]: https://github.com/sebastianbergmann/environment/compare/5.0.2...5.1.0 +[5.0.2]: https://github.com/sebastianbergmann/environment/compare/5.0.1...5.0.2 +[5.0.1]: https://github.com/sebastianbergmann/environment/compare/5.0.0...5.0.1 +[5.0.0]: https://github.com/sebastianbergmann/environment/compare/4.2.3...5.0.0 +[4.2.3]: https://github.com/sebastianbergmann/environment/compare/4.2.2...4.2.3 +[4.2.2]: https://github.com/sebastianbergmann/environment/compare/4.2.1...4.2.2 +[4.2.1]: https://github.com/sebastianbergmann/environment/compare/4.2.0...4.2.1 +[4.2.0]: https://github.com/sebastianbergmann/environment/compare/4.1.0...4.2.0 +[4.1.0]: https://github.com/sebastianbergmann/environment/compare/4.0.2...4.1.0 +[4.0.2]: https://github.com/sebastianbergmann/environment/compare/4.0.1...4.0.2 +[4.0.1]: https://github.com/sebastianbergmann/environment/compare/66691f8e2dc4641909166b275a9a4f45c0e89092...4.0.1 +[4.0.0]: https://github.com/sebastianbergmann/environment/compare/3.1.0...66691f8e2dc4641909166b275a9a4f45c0e89092 +[3.1.0]: https://github.com/sebastianbergmann/environment/compare/3.0...3.1.0 +[3.0.4]: https://github.com/sebastianbergmann/environment/compare/3.0.3...3.0.4 +[3.0.3]: https://github.com/sebastianbergmann/environment/compare/3.0.2...3.0.3 +[3.0.2]: https://github.com/sebastianbergmann/environment/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/sebastianbergmann/environment/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/sebastianbergmann/environment/compare/2.0...3.0.0 + diff --git a/vendor/sebastian/environment/LICENSE b/vendor/sebastian/environment/LICENSE new file mode 100644 index 000000000..c58093991 --- /dev/null +++ b/vendor/sebastian/environment/LICENSE @@ -0,0 +1,33 @@ +sebastian/environment + +Copyright (c) 2014-2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/environment/README.md b/vendor/sebastian/environment/README.md new file mode 100644 index 000000000..24a9831e4 --- /dev/null +++ b/vendor/sebastian/environment/README.md @@ -0,0 +1,22 @@ +# sebastian/environment + +[![Latest Stable Version](https://img.shields.io/packagist/v/sebastian/environment.svg?style=flat-square)](https://packagist.org/packages/sebastian/environment) +[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square)](https://php.net/) +[![CI Status](https://github.com/sebastianbergmann/environment/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/environment/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/environment/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/environment) + +This component provides functionality that helps writing PHP code that has runtime-specific (PHP / HHVM) execution paths. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/environment +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/environment +``` diff --git a/vendor/sebastian/environment/composer.json b/vendor/sebastian/environment/composer.json new file mode 100644 index 000000000..d50dcfd78 --- /dev/null +++ b/vendor/sebastian/environment/composer.json @@ -0,0 +1,40 @@ +{ + "name": "sebastian/environment", + "description": "Provides functionality to handle HHVM/PHP environments", + "keywords": ["environment","hhvm","xdebug"], + "homepage": "http://www.github.com/sebastianbergmann/environment", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]" + } + ], + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "prefer-stable": true, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + } +} diff --git a/vendor/sebastian/environment/src/Console.php b/vendor/sebastian/environment/src/Console.php new file mode 100644 index 000000000..c4a2348f0 --- /dev/null +++ b/vendor/sebastian/environment/src/Console.php @@ -0,0 +1,189 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/environment. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Environment; + +use const DIRECTORY_SEPARATOR; +use const STDIN; +use const STDOUT; +use function defined; +use function fclose; +use function fstat; +use function function_exists; +use function getenv; +use function is_resource; +use function is_string; +use function posix_isatty; +use function preg_match; +use function proc_close; +use function proc_open; +use function sapi_windows_vt100_support; +use function shell_exec; +use function stream_get_contents; +use function stream_isatty; +use function trim; + +final class Console +{ + /** + * @var int + */ + public const STDIN = 0; + + /** + * @var int + */ + public const STDOUT = 1; + + /** + * @var int + */ + public const STDERR = 2; + + /** + * Returns true if STDOUT supports colorization. + * + * This code has been copied and adapted from + * Symfony\Component\Console\Output\StreamOutput. + */ + public function hasColorSupport(): bool + { + if ('Hyper' === getenv('TERM_PROGRAM')) { + return true; + } + + if ($this->isWindows()) { + // @codeCoverageIgnoreStart + return (defined('STDOUT') && function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT)) + || false !== getenv('ANSICON') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM'); + // @codeCoverageIgnoreEnd + } + + if (!defined('STDOUT')) { + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + return $this->isInteractive(STDOUT); + } + + /** + * Returns the number of columns of the terminal. + * + * @codeCoverageIgnore + */ + public function getNumberOfColumns(): int + { + if (!$this->isInteractive(defined('STDIN') ? STDIN : self::STDIN)) { + return 80; + } + + if ($this->isWindows()) { + return $this->getNumberOfColumnsWindows(); + } + + return $this->getNumberOfColumnsInteractive(); + } + + /** + * Returns if the file descriptor is an interactive terminal or not. + * + * Normally, we want to use a resource as a parameter, yet sadly it's not always awailable, + * eg when running code in interactive console (`php -a`), STDIN/STDOUT/STDERR constants are not defined. + * + * @param int|resource $fileDescriptor + */ + public function isInteractive($fileDescriptor = self::STDOUT): bool + { + if (is_resource($fileDescriptor)) { + // These functions require a descriptor that is a real resource, not a numeric ID of it + if (function_exists('stream_isatty') && @stream_isatty($fileDescriptor)) { + return true; + } + + // Check if formatted mode is S_IFCHR + if (function_exists('fstat') && @stream_isatty($fileDescriptor)) { + $stat = @fstat(STDOUT); + + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; + } + + return false; + } + + return function_exists('posix_isatty') && @posix_isatty($fileDescriptor); + } + + private function isWindows(): bool + { + return DIRECTORY_SEPARATOR === '\\'; + } + + /** + * @codeCoverageIgnore + */ + private function getNumberOfColumnsInteractive(): int + { + if (function_exists('shell_exec') && preg_match('#\d+ (\d+)#', shell_exec('stty size') ?: '', $match) === 1) { + if ((int) $match[1] > 0) { + return (int) $match[1]; + } + } + + if (function_exists('shell_exec') && preg_match('#columns = (\d+);#', shell_exec('stty') ?: '', $match) === 1) { + if ((int) $match[1] > 0) { + return (int) $match[1]; + } + } + + return 80; + } + + /** + * @codeCoverageIgnore + */ + private function getNumberOfColumnsWindows(): int + { + $ansicon = getenv('ANSICON'); + $columns = 80; + + if (is_string($ansicon) && preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim($ansicon), $matches)) { + $columns = (int) $matches[1]; + } elseif (function_exists('proc_open')) { + $process = proc_open( + 'mode CON', + [ + 1 => ['pipe', 'w'], + 2 => ['pipe', 'w'], + ], + $pipes, + null, + null, + ['suppress_errors' => true] + ); + + if (is_resource($process)) { + $info = stream_get_contents($pipes[1]); + + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($process); + + if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) { + $columns = (int) $matches[2]; + } + } + } + + return $columns - 1; + } +} diff --git a/vendor/sebastian/environment/src/OperatingSystem.php b/vendor/sebastian/environment/src/OperatingSystem.php new file mode 100644 index 000000000..1f3ebca7c --- /dev/null +++ b/vendor/sebastian/environment/src/OperatingSystem.php @@ -0,0 +1,53 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/environment. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Environment; + +use const DIRECTORY_SEPARATOR; +use const PHP_OS; +use const PHP_OS_FAMILY; +use function defined; + +final class OperatingSystem +{ + /** + * Returns PHP_OS_FAMILY (if defined (which it is on PHP >= 7.2)). + * Returns a string (compatible with PHP_OS_FAMILY) derived from PHP_OS otherwise. + */ + public function getFamily(): string + { + if (defined('PHP_OS_FAMILY')) { + return PHP_OS_FAMILY; + } + + if (DIRECTORY_SEPARATOR === '\\') { + return 'Windows'; + } + + switch (PHP_OS) { + case 'Darwin': + return 'Darwin'; + + case 'DragonFly': + case 'FreeBSD': + case 'NetBSD': + case 'OpenBSD': + return 'BSD'; + + case 'Linux': + return 'Linux'; + + case 'SunOS': + return 'Solaris'; + + default: + return 'Unknown'; + } + } +} diff --git a/vendor/sebastian/environment/src/Runtime.php b/vendor/sebastian/environment/src/Runtime.php new file mode 100644 index 000000000..311aefcb6 --- /dev/null +++ b/vendor/sebastian/environment/src/Runtime.php @@ -0,0 +1,317 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/environment. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Environment; + +use const PHP_BINARY; +use const PHP_BINDIR; +use const PHP_MAJOR_VERSION; +use const PHP_SAPI; +use const PHP_VERSION; +use function array_map; +use function array_merge; +use function defined; +use function escapeshellarg; +use function explode; +use function extension_loaded; +use function getenv; +use function ini_get; +use function is_readable; +use function parse_ini_file; +use function php_ini_loaded_file; +use function php_ini_scanned_files; +use function phpversion; +use function sprintf; +use function strpos; + +/** + * Utility class for HHVM/PHP environment handling. + */ +final class Runtime +{ + /** + * @var string + */ + private static $binary; + + /** + * Returns true when Xdebug or PCOV is available or + * the runtime used is PHPDBG. + */ + public function canCollectCodeCoverage(): bool + { + return $this->hasXdebug() || $this->hasPCOV() || $this->hasPHPDBGCodeCoverage(); + } + + /** + * Returns true when Zend OPcache is loaded, enabled, + * and is configured to discard comments. + */ + public function discardsComments(): bool + { + if (!$this->isOpcacheActive()) { + return false; + } + + if (ini_get('opcache.save_comments') !== '0') { + return false; + } + + return true; + } + + /** + * Returns true when Zend OPcache is loaded, enabled, + * and is configured to perform just-in-time compilation. + */ + public function performsJustInTimeCompilation(): bool + { + if (PHP_MAJOR_VERSION < 8) { + return false; + } + + if (!$this->isOpcacheActive()) { + return false; + } + + if (strpos(ini_get('opcache.jit'), '0') === 0) { + return false; + } + + return true; + } + + /** + * Returns the path to the binary of the current runtime. + * Appends ' --php' to the path when the runtime is HHVM. + */ + public function getBinary(): string + { + // HHVM + if (self::$binary === null && $this->isHHVM()) { + // @codeCoverageIgnoreStart + if ((self::$binary = getenv('PHP_BINARY')) === false) { + self::$binary = PHP_BINARY; + } + + self::$binary = escapeshellarg(self::$binary) . ' --php' . + ' -d hhvm.php7.all=1'; + // @codeCoverageIgnoreEnd + } + + if (self::$binary === null && PHP_BINARY !== '') { + self::$binary = escapeshellarg(PHP_BINARY); + } + + if (self::$binary === null) { + // @codeCoverageIgnoreStart + $possibleBinaryLocations = [ + PHP_BINDIR . '/php', + PHP_BINDIR . '/php-cli.exe', + PHP_BINDIR . '/php.exe', + ]; + + foreach ($possibleBinaryLocations as $binary) { + if (is_readable($binary)) { + self::$binary = escapeshellarg($binary); + + break; + } + } + // @codeCoverageIgnoreEnd + } + + if (self::$binary === null) { + // @codeCoverageIgnoreStart + self::$binary = 'php'; + // @codeCoverageIgnoreEnd + } + + return self::$binary; + } + + public function getNameWithVersion(): string + { + return $this->getName() . ' ' . $this->getVersion(); + } + + public function getNameWithVersionAndCodeCoverageDriver(): string + { + if (!$this->canCollectCodeCoverage() || $this->hasPHPDBGCodeCoverage()) { + return $this->getNameWithVersion(); + } + + if ($this->hasPCOV()) { + return sprintf( + '%s with PCOV %s', + $this->getNameWithVersion(), + phpversion('pcov') + ); + } + + if ($this->hasXdebug()) { + return sprintf( + '%s with Xdebug %s', + $this->getNameWithVersion(), + phpversion('xdebug') + ); + } + } + + public function getName(): string + { + if ($this->isHHVM()) { + // @codeCoverageIgnoreStart + return 'HHVM'; + // @codeCoverageIgnoreEnd + } + + if ($this->isPHPDBG()) { + // @codeCoverageIgnoreStart + return 'PHPDBG'; + // @codeCoverageIgnoreEnd + } + + return 'PHP'; + } + + public function getVendorUrl(): string + { + if ($this->isHHVM()) { + // @codeCoverageIgnoreStart + return 'http://hhvm.com/'; + // @codeCoverageIgnoreEnd + } + + return 'https://secure.php.net/'; + } + + public function getVersion(): string + { + if ($this->isHHVM()) { + // @codeCoverageIgnoreStart + return HHVM_VERSION; + // @codeCoverageIgnoreEnd + } + + return PHP_VERSION; + } + + /** + * Returns true when the runtime used is PHP and Xdebug is loaded. + */ + public function hasXdebug(): bool + { + return ($this->isPHP() || $this->isHHVM()) && extension_loaded('xdebug'); + } + + /** + * Returns true when the runtime used is HHVM. + */ + public function isHHVM(): bool + { + return defined('HHVM_VERSION'); + } + + /** + * Returns true when the runtime used is PHP without the PHPDBG SAPI. + */ + public function isPHP(): bool + { + return !$this->isHHVM() && !$this->isPHPDBG(); + } + + /** + * Returns true when the runtime used is PHP with the PHPDBG SAPI. + */ + public function isPHPDBG(): bool + { + return PHP_SAPI === 'phpdbg' && !$this->isHHVM(); + } + + /** + * Returns true when the runtime used is PHP with the PHPDBG SAPI + * and the phpdbg_*_oplog() functions are available (PHP >= 7.0). + */ + public function hasPHPDBGCodeCoverage(): bool + { + return $this->isPHPDBG(); + } + + /** + * Returns true when the runtime used is PHP with PCOV loaded and enabled. + */ + public function hasPCOV(): bool + { + return $this->isPHP() && extension_loaded('pcov') && ini_get('pcov.enabled'); + } + + /** + * Parses the loaded php.ini file (if any) as well as all + * additional php.ini files from the additional ini dir for + * a list of all configuration settings loaded from files + * at startup. Then checks for each php.ini setting passed + * via the `$values` parameter whether this setting has + * been changed at runtime. Returns an array of strings + * where each string has the format `key=value` denoting + * the name of a changed php.ini setting with its new value. + * + * @return string[] + */ + public function getCurrentSettings(array $values): array + { + $diff = []; + $files = []; + + if ($file = php_ini_loaded_file()) { + $files[] = $file; + } + + if ($scanned = php_ini_scanned_files()) { + $files = array_merge( + $files, + array_map( + 'trim', + explode(",\n", $scanned) + ) + ); + } + + foreach ($files as $ini) { + $config = parse_ini_file($ini, true); + + foreach ($values as $value) { + $set = ini_get($value); + + if (isset($config[$value]) && $set != $config[$value]) { + $diff[] = sprintf('%s=%s', $value, $set); + } + } + } + + return $diff; + } + + private function isOpcacheActive(): bool + { + if (!extension_loaded('Zend OPcache')) { + return false; + } + + if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && ini_get('opcache.enable_cli') === '1') { + return true; + } + + if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg' && ini_get('opcache.enable') === '1') { + return true; + } + + return false; + } +} diff --git a/vendor/sebastian/exporter/ChangeLog.md b/vendor/sebastian/exporter/ChangeLog.md new file mode 100644 index 000000000..c691e81ab --- /dev/null +++ b/vendor/sebastian/exporter/ChangeLog.md @@ -0,0 +1,64 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. + +## [4.0.4] - 2021-11-11 + +### Changed + +* [#37](https://github.com/sebastianbergmann/exporter/pull/37): Improve export of closed resources + +## [4.0.3] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [4.0.2] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [4.0.1] - 2020-06-15 + +### Changed + +* Tests etc. are now ignored for archive exports + +## [4.0.0] - 2020-02-07 + +### Removed + +* This component is no longer supported on PHP 7.0, PHP 7.1, and PHP 7.2 + +## [3.1.4] - 2021-11-11 + +### Changed + +* [#38](https://github.com/sebastianbergmann/exporter/pull/38): Improve export of closed resources + +## [3.1.3] - 2020-11-30 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.0` to `>=7.0` + +## [3.1.2] - 2019-09-14 + +### Fixed + +* [#29](https://github.com/sebastianbergmann/exporter/pull/29): Second parameter for `str_repeat()` must be an integer + +### Removed + +* Remove HHVM-specific code that is no longer needed + +[4.0.4]: https://github.com/sebastianbergmann/exporter/compare/4.0.3...4.0.4 +[4.0.3]: https://github.com/sebastianbergmann/exporter/compare/4.0.2...4.0.3 +[4.0.2]: https://github.com/sebastianbergmann/exporter/compare/4.0.1...4.0.2 +[4.0.1]: https://github.com/sebastianbergmann/exporter/compare/4.0.0...4.0.1 +[4.0.0]: https://github.com/sebastianbergmann/exporter/compare/3.1.2...4.0.0 +[3.1.4]: https://github.com/sebastianbergmann/exporter/compare/3.1.3...3.1.4 +[3.1.3]: https://github.com/sebastianbergmann/exporter/compare/3.1.2...3.1.3 +[3.1.2]: https://github.com/sebastianbergmann/exporter/compare/3.1.1...3.1.2 diff --git a/vendor/sebastian/exporter/LICENSE b/vendor/sebastian/exporter/LICENSE new file mode 100644 index 000000000..26dc7feca --- /dev/null +++ b/vendor/sebastian/exporter/LICENSE @@ -0,0 +1,33 @@ +Exporter + +Copyright (c) 2002-2021, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/exporter/README.md b/vendor/sebastian/exporter/README.md new file mode 100644 index 000000000..ed8719f56 --- /dev/null +++ b/vendor/sebastian/exporter/README.md @@ -0,0 +1,174 @@ +# sebastian/exporter + +[![CI Status](https://github.com/sebastianbergmann/exporter/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/exporter/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/exporter/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/exporter) + +This component provides the functionality to export PHP variables for visualization. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/exporter +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/exporter +``` + +## Usage + +Exporting: + +```php +<?php +use SebastianBergmann\Exporter\Exporter; + +$exporter = new Exporter; + +/* +Exception Object &0000000078de0f0d000000002003a261 ( + 'message' => '' + 'string' => '' + 'code' => 0 + 'file' => '/home/sebastianbergmann/test.php' + 'line' => 34 + 'previous' => null +) +*/ + +print $exporter->export(new Exception); +``` + +## Data Types + +Exporting simple types: + +```php +<?php +use SebastianBergmann\Exporter\Exporter; + +$exporter = new Exporter; + +// 46 +print $exporter->export(46); + +// 4.0 +print $exporter->export(4.0); + +// 'hello, world!' +print $exporter->export('hello, world!'); + +// false +print $exporter->export(false); + +// NAN +print $exporter->export(acos(8)); + +// -INF +print $exporter->export(log(0)); + +// null +print $exporter->export(null); + +// resource(13) of type (stream) +print $exporter->export(fopen('php://stderr', 'w')); + +// Binary String: 0x000102030405 +print $exporter->export(chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5)); +``` + +Exporting complex types: + +```php +<?php +use SebastianBergmann\Exporter\Exporter; + +$exporter = new Exporter; + +/* +Array &0 ( + 0 => Array &1 ( + 0 => 1 + 1 => 2 + 2 => 3 + ) + 1 => Array &2 ( + 0 => '' + 1 => 0 + 2 => false + ) +) +*/ + +print $exporter->export(array(array(1,2,3), array("",0,FALSE))); + +/* +Array &0 ( + 'self' => Array &1 ( + 'self' => Array &1 + ) +) +*/ + +$array = array(); +$array['self'] = &$array; +print $exporter->export($array); + +/* +stdClass Object &0000000003a66dcc0000000025e723e2 ( + 'self' => stdClass Object &0000000003a66dcc0000000025e723e2 +) +*/ + +$obj = new stdClass(); +$obj->self = $obj; +print $exporter->export($obj); +``` + +Compact exports: + +```php +<?php +use SebastianBergmann\Exporter\Exporter; + +$exporter = new Exporter; + +// Array () +print $exporter->shortenedExport(array()); + +// Array (...) +print $exporter->shortenedExport(array(1,2,3,4,5)); + +// stdClass Object () +print $exporter->shortenedExport(new stdClass); + +// Exception Object (...) +print $exporter->shortenedExport(new Exception); + +// this\nis\na\nsuper\nlong\nstring\nt...\nspace +print $exporter->shortenedExport( +<<<LONG_STRING +this +is +a +super +long +string +that +wraps +a +lot +and +eats +up +a +lot +of +space +LONG_STRING +); +``` diff --git a/vendor/sebastian/exporter/composer.json b/vendor/sebastian/exporter/composer.json new file mode 100644 index 000000000..baa958443 --- /dev/null +++ b/vendor/sebastian/exporter/composer.json @@ -0,0 +1,56 @@ +{ + "name": "sebastian/exporter", + "description": "Provides the functionality to export PHP variables for visualization", + "keywords": ["exporter","export"], + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]" + }, + { + "name": "Jeff Welch", + "email": "[email protected]" + }, + { + "name": "Volker Dusch", + "email": "[email protected]" + }, + { + "name": "Adam Harvey", + "email": "[email protected]" + }, + { + "name": "Bernhard Schussek", + "email": "[email protected]" + } + ], + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "prefer-stable": true, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "ext-mbstring": "*" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + } +} + diff --git a/vendor/sebastian/exporter/src/Exporter.php b/vendor/sebastian/exporter/src/Exporter.php new file mode 100644 index 000000000..692a0b21f --- /dev/null +++ b/vendor/sebastian/exporter/src/Exporter.php @@ -0,0 +1,330 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/exporter. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Exporter; + +use function bin2hex; +use function count; +use function function_exists; +use function get_class; +use function get_resource_type; +use function gettype; +use function implode; +use function is_array; +use function is_float; +use function is_object; +use function is_resource; +use function is_string; +use function mb_strlen; +use function mb_substr; +use function preg_match; +use function spl_object_hash; +use function sprintf; +use function str_repeat; +use function str_replace; +use function strlen; +use function substr; +use function var_export; +use SebastianBergmann\RecursionContext\Context; +use SplObjectStorage; + +/** + * A nifty utility for visualizing PHP variables. + * + * <code> + * <?php + * use SebastianBergmann\Exporter\Exporter; + * + * $exporter = new Exporter; + * print $exporter->export(new Exception); + * </code> + */ +class Exporter +{ + /** + * Exports a value as a string. + * + * The output of this method is similar to the output of print_r(), but + * improved in various aspects: + * + * - NULL is rendered as "null" (instead of "") + * - TRUE is rendered as "true" (instead of "1") + * - FALSE is rendered as "false" (instead of "") + * - Strings are always quoted with single quotes + * - Carriage returns and newlines are normalized to \n + * - Recursion and repeated rendering is treated properly + * + * @param int $indentation The indentation level of the 2nd+ line + * + * @return string + */ + public function export($value, $indentation = 0) + { + return $this->recursiveExport($value, $indentation); + } + + /** + * @param array<mixed> $data + * @param Context $context + * + * @return string + */ + public function shortenedRecursiveExport(&$data, Context $context = null) + { + $result = []; + $exporter = new self(); + + if (!$context) { + $context = new Context; + } + + $array = $data; + $context->add($data); + + foreach ($array as $key => $value) { + if (is_array($value)) { + if ($context->contains($data[$key]) !== false) { + $result[] = '*RECURSION*'; + } else { + $result[] = sprintf( + 'array(%s)', + $this->shortenedRecursiveExport($data[$key], $context) + ); + } + } else { + $result[] = $exporter->shortenedExport($value); + } + } + + return implode(', ', $result); + } + + /** + * Exports a value into a single-line string. + * + * The output of this method is similar to the output of + * SebastianBergmann\Exporter\Exporter::export(). + * + * Newlines are replaced by the visible string '\n'. + * Contents of arrays and objects (if any) are replaced by '...'. + * + * @return string + * + * @see SebastianBergmann\Exporter\Exporter::export + */ + public function shortenedExport($value) + { + if (is_string($value)) { + $string = str_replace("\n", '', $this->export($value)); + + if (function_exists('mb_strlen')) { + if (mb_strlen($string) > 40) { + $string = mb_substr($string, 0, 30) . '...' . mb_substr($string, -7); + } + } else { + if (strlen($string) > 40) { + $string = substr($string, 0, 30) . '...' . substr($string, -7); + } + } + + return $string; + } + + if (is_object($value)) { + return sprintf( + '%s Object (%s)', + get_class($value), + count($this->toArray($value)) > 0 ? '...' : '' + ); + } + + if (is_array($value)) { + return sprintf( + 'Array (%s)', + count($value) > 0 ? '...' : '' + ); + } + + return $this->export($value); + } + + /** + * Converts an object to an array containing all of its private, protected + * and public properties. + * + * @return array + */ + public function toArray($value) + { + if (!is_object($value)) { + return (array) $value; + } + + $array = []; + + foreach ((array) $value as $key => $val) { + // Exception traces commonly reference hundreds to thousands of + // objects currently loaded in memory. Including them in the result + // has a severe negative performance impact. + if ("\0Error\0trace" === $key || "\0Exception\0trace" === $key) { + continue; + } + + // properties are transformed to keys in the following way: + // private $property => "\0Classname\0property" + // protected $property => "\0*\0property" + // public $property => "property" + if (preg_match('/^\0.+\0(.+)$/', (string) $key, $matches)) { + $key = $matches[1]; + } + + // See https://github.com/php/php-src/commit/5721132 + if ($key === "\0gcdata") { + continue; + } + + $array[$key] = $val; + } + + // Some internal classes like SplObjectStorage don't work with the + // above (fast) mechanism nor with reflection in Zend. + // Format the output similarly to print_r() in this case + if ($value instanceof SplObjectStorage) { + foreach ($value as $key => $val) { + $array[spl_object_hash($val)] = [ + 'obj' => $val, + 'inf' => $value->getInfo(), + ]; + } + } + + return $array; + } + + /** + * Recursive implementation of export. + * + * @param mixed $value The value to export + * @param int $indentation The indentation level of the 2nd+ line + * @param \SebastianBergmann\RecursionContext\Context $processed Previously processed objects + * + * @return string + * + * @see SebastianBergmann\Exporter\Exporter::export + */ + protected function recursiveExport(&$value, $indentation, $processed = null) + { + if ($value === null) { + return 'null'; + } + + if ($value === true) { + return 'true'; + } + + if ($value === false) { + return 'false'; + } + + if (is_float($value) && (float) ((int) $value) === $value) { + return "{$value}.0"; + } + + if (gettype($value) === 'resource (closed)') { + return 'resource (closed)'; + } + + if (is_resource($value)) { + return sprintf( + 'resource(%d) of type (%s)', + $value, + get_resource_type($value) + ); + } + + if (is_string($value)) { + // Match for most non printable chars somewhat taking multibyte chars into account + if (preg_match('/[^\x09-\x0d\x1b\x20-\xff]/', $value)) { + return 'Binary String: 0x' . bin2hex($value); + } + + return "'" . + str_replace( + '<lf>', + "\n", + str_replace( + ["\r\n", "\n\r", "\r", "\n"], + ['\r\n<lf>', '\n\r<lf>', '\r<lf>', '\n<lf>'], + $value + ) + ) . + "'"; + } + + $whitespace = str_repeat(' ', 4 * $indentation); + + if (!$processed) { + $processed = new Context; + } + + if (is_array($value)) { + if (($key = $processed->contains($value)) !== false) { + return 'Array &' . $key; + } + + $array = $value; + $key = $processed->add($value); + $values = ''; + + if (count($array) > 0) { + foreach ($array as $k => $v) { + $values .= sprintf( + '%s %s => %s' . "\n", + $whitespace, + $this->recursiveExport($k, $indentation), + $this->recursiveExport($value[$k], $indentation + 1, $processed) + ); + } + + $values = "\n" . $values . $whitespace; + } + + return sprintf('Array &%s (%s)', $key, $values); + } + + if (is_object($value)) { + $class = get_class($value); + + if ($hash = $processed->contains($value)) { + return sprintf('%s Object &%s', $class, $hash); + } + + $hash = $processed->add($value); + $values = ''; + $array = $this->toArray($value); + + if (count($array) > 0) { + foreach ($array as $k => $v) { + $values .= sprintf( + '%s %s => %s' . "\n", + $whitespace, + $this->recursiveExport($k, $indentation), + $this->recursiveExport($v, $indentation + 1, $processed) + ); + } + + $values = "\n" . $values . $whitespace; + } + + return sprintf('%s Object &%s (%s)', $class, $hash, $values); + } + + return var_export($value, true); + } +} diff --git a/vendor/sebastian/global-state/ChangeLog.md b/vendor/sebastian/global-state/ChangeLog.md new file mode 100644 index 000000000..a27a5cf16 --- /dev/null +++ b/vendor/sebastian/global-state/ChangeLog.md @@ -0,0 +1,79 @@ +# Changes in sebastian/global-state + +All notable changes in `sebastian/global-state` are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. + +## [5.0.5] - 2022-02-14 + +### Fixed + +* [#34](https://github.com/sebastianbergmann/global-state/pull/34): Uninitialised typed static properties are not handled correctly + +## [5.0.4] - 2022-02-10 + +### Fixed + +* The `$includeTraits` parameter of `SebastianBergmann\GlobalState\Snapshot::__construct()` is not respected + +## [5.0.3] - 2021-06-11 + +### Changed + +* `SebastianBergmann\GlobalState\CodeExporter::globalVariables()` now generates code that is compatible with PHP 8.1 + +## [5.0.2] - 2020-10-26 + +### Fixed + +* `SebastianBergmann\GlobalState\Exception` now correctly extends `\Throwable` + +## [5.0.1] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [5.0.0] - 2020-08-07 + +### Changed + +* The `SebastianBergmann\GlobalState\Blacklist` class has been renamed to `SebastianBergmann\GlobalState\ExcludeList` + +## [4.0.0] - 2020-02-07 + +### Removed + +* This component is no longer supported on PHP 7.2 + +## [3.0.2] - 2022-02-10 + +### Fixed + +* The `$includeTraits` parameter of `SebastianBergmann\GlobalState\Snapshot::__construct()` is not respected + +## [3.0.1] - 2020-11-30 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.2` to `>=7.2` + +## [3.0.0] - 2019-02-01 + +### Changed + +* `Snapshot::canBeSerialized()` now recursively checks arrays and object graphs for variables that cannot be serialized + +### Removed + +* This component is no longer supported on PHP 7.0 and PHP 7.1 + +[5.0.5]: https://github.com/sebastianbergmann/global-state/compare/5.0.4...5.0.5 +[5.0.4]: https://github.com/sebastianbergmann/global-state/compare/5.0.3...5.0.4 +[5.0.3]: https://github.com/sebastianbergmann/global-state/compare/5.0.2...5.0.3 +[5.0.2]: https://github.com/sebastianbergmann/global-state/compare/5.0.1...5.0.2 +[5.0.1]: https://github.com/sebastianbergmann/global-state/compare/5.0.0...5.0.1 +[5.0.0]: https://github.com/sebastianbergmann/global-state/compare/4.0.0...5.0.0 +[4.0.0]: https://github.com/sebastianbergmann/global-state/compare/3.0.2...4.0.0 +[3.0.2]: https://github.com/sebastianbergmann/phpunit/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/sebastianbergmann/phpunit/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/sebastianbergmann/phpunit/compare/2.0.0...3.0.0 + diff --git a/vendor/sebastian/global-state/LICENSE b/vendor/sebastian/global-state/LICENSE new file mode 100644 index 000000000..240190bd3 --- /dev/null +++ b/vendor/sebastian/global-state/LICENSE @@ -0,0 +1,33 @@ +sebastian/global-state + +Copyright (c) 2001-2022, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/global-state/README.md b/vendor/sebastian/global-state/README.md new file mode 100644 index 000000000..af15bedde --- /dev/null +++ b/vendor/sebastian/global-state/README.md @@ -0,0 +1,20 @@ +# sebastian/global-state + +[![CI Status](https://github.com/sebastianbergmann/global-state/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/global-state/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/global-state/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/global-state) + +Snapshotting of global state, factored out of PHPUnit into a stand-alone component. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/global-state +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/global-state +``` diff --git a/vendor/sebastian/global-state/composer.json b/vendor/sebastian/global-state/composer.json new file mode 100644 index 000000000..0fef446a6 --- /dev/null +++ b/vendor/sebastian/global-state/composer.json @@ -0,0 +1,51 @@ +{ + "name": "sebastian/global-state", + "description": "Snapshotting of global state", + "keywords": ["global state"], + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]" + } + ], + "prefer-stable": true, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "autoload-dev": { + "classmap": [ + "tests/_fixture/" + ], + "files": [ + "tests/_fixture/SnapshotFunctions.php" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + } +} diff --git a/vendor/sebastian/global-state/src/CodeExporter.php b/vendor/sebastian/global-state/src/CodeExporter.php new file mode 100644 index 000000000..71cdbf504 --- /dev/null +++ b/vendor/sebastian/global-state/src/CodeExporter.php @@ -0,0 +1,109 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/global-state. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\GlobalState; + +use const PHP_EOL; +use function is_array; +use function is_scalar; +use function serialize; +use function sprintf; +use function var_export; + +/** + * Exports parts of a Snapshot as PHP code. + */ +final class CodeExporter +{ + public function constants(Snapshot $snapshot): string + { + $result = ''; + + foreach ($snapshot->constants() as $name => $value) { + $result .= sprintf( + 'if (!defined(\'%s\')) define(\'%s\', %s);' . "\n", + $name, + $name, + $this->exportVariable($value) + ); + } + + return $result; + } + + public function globalVariables(Snapshot $snapshot): string + { + $result = <<<'EOT' +call_user_func( + function () + { + foreach (array_keys($GLOBALS) as $key) { + unset($GLOBALS[$key]); + } + } +); + + +EOT; + + foreach ($snapshot->globalVariables() as $name => $value) { + $result .= sprintf( + '$GLOBALS[%s] = %s;' . PHP_EOL, + $this->exportVariable($name), + $this->exportVariable($value) + ); + } + + return $result; + } + + public function iniSettings(Snapshot $snapshot): string + { + $result = ''; + + foreach ($snapshot->iniSettings() as $key => $value) { + $result .= sprintf( + '@ini_set(%s, %s);' . "\n", + $this->exportVariable($key), + $this->exportVariable($value) + ); + } + + return $result; + } + + private function exportVariable($variable): string + { + if (is_scalar($variable) || null === $variable || + (is_array($variable) && $this->arrayOnlyContainsScalars($variable))) { + return var_export($variable, true); + } + + return 'unserialize(' . var_export(serialize($variable), true) . ')'; + } + + private function arrayOnlyContainsScalars(array $array): bool + { + $result = true; + + foreach ($array as $element) { + if (is_array($element)) { + $result = $this->arrayOnlyContainsScalars($element); + } elseif (!is_scalar($element) && null !== $element) { + $result = false; + } + + if ($result === false) { + break; + } + } + + return $result; + } +} diff --git a/vendor/sebastian/global-state/src/ExcludeList.php b/vendor/sebastian/global-state/src/ExcludeList.php new file mode 100644 index 000000000..5631f1186 --- /dev/null +++ b/vendor/sebastian/global-state/src/ExcludeList.php @@ -0,0 +1,119 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/global-state. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\GlobalState; + +use function in_array; +use function strpos; +use ReflectionClass; + +final class ExcludeList +{ + /** + * @var array + */ + private $globalVariables = []; + + /** + * @var string[] + */ + private $classes = []; + + /** + * @var string[] + */ + private $classNamePrefixes = []; + + /** + * @var string[] + */ + private $parentClasses = []; + + /** + * @var string[] + */ + private $interfaces = []; + + /** + * @var array + */ + private $staticAttributes = []; + + public function addGlobalVariable(string $variableName): void + { + $this->globalVariables[$variableName] = true; + } + + public function addClass(string $className): void + { + $this->classes[] = $className; + } + + public function addSubclassesOf(string $className): void + { + $this->parentClasses[] = $className; + } + + public function addImplementorsOf(string $interfaceName): void + { + $this->interfaces[] = $interfaceName; + } + + public function addClassNamePrefix(string $classNamePrefix): void + { + $this->classNamePrefixes[] = $classNamePrefix; + } + + public function addStaticAttribute(string $className, string $attributeName): void + { + if (!isset($this->staticAttributes[$className])) { + $this->staticAttributes[$className] = []; + } + + $this->staticAttributes[$className][$attributeName] = true; + } + + public function isGlobalVariableExcluded(string $variableName): bool + { + return isset($this->globalVariables[$variableName]); + } + + public function isStaticAttributeExcluded(string $className, string $attributeName): bool + { + if (in_array($className, $this->classes, true)) { + return true; + } + + foreach ($this->classNamePrefixes as $prefix) { + if (strpos($className, $prefix) === 0) { + return true; + } + } + + $class = new ReflectionClass($className); + + foreach ($this->parentClasses as $type) { + if ($class->isSubclassOf($type)) { + return true; + } + } + + foreach ($this->interfaces as $type) { + if ($class->implementsInterface($type)) { + return true; + } + } + + if (isset($this->staticAttributes[$className][$attributeName])) { + return true; + } + + return false; + } +} diff --git a/vendor/sebastian/global-state/src/Restorer.php b/vendor/sebastian/global-state/src/Restorer.php new file mode 100644 index 000000000..1633fcc11 --- /dev/null +++ b/vendor/sebastian/global-state/src/Restorer.php @@ -0,0 +1,143 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/global-state. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\GlobalState; + +use function array_diff; +use function array_key_exists; +use function array_keys; +use function array_merge; +use function function_exists; +use function get_defined_functions; +use function in_array; +use function is_array; +use ReflectionClass; +use ReflectionProperty; + +/** + * Restorer of snapshots of global state. + */ +class Restorer +{ + /** + * Deletes function definitions that are not defined in a snapshot. + * + * @throws RuntimeException when the uopz_delete() function is not available + * + * @see https://github.com/krakjoe/uopz + */ + public function restoreFunctions(Snapshot $snapshot): void + { + if (!function_exists('uopz_delete')) { + throw new RuntimeException('The uopz_delete() function is required for this operation'); + } + + $functions = get_defined_functions(); + + foreach (array_diff($functions['user'], $snapshot->functions()) as $function) { + uopz_delete($function); + } + } + + /** + * Restores all global and super-global variables from a snapshot. + */ + public function restoreGlobalVariables(Snapshot $snapshot): void + { + $superGlobalArrays = $snapshot->superGlobalArrays(); + + foreach ($superGlobalArrays as $superGlobalArray) { + $this->restoreSuperGlobalArray($snapshot, $superGlobalArray); + } + + $globalVariables = $snapshot->globalVariables(); + + foreach (array_keys($GLOBALS) as $key) { + if ($key !== 'GLOBALS' && + !in_array($key, $superGlobalArrays, true) && + !$snapshot->excludeList()->isGlobalVariableExcluded($key)) { + if (array_key_exists($key, $globalVariables)) { + $GLOBALS[$key] = $globalVariables[$key]; + } else { + unset($GLOBALS[$key]); + } + } + } + } + + /** + * Restores all static attributes in user-defined classes from this snapshot. + */ + public function restoreStaticAttributes(Snapshot $snapshot): void + { + $current = new Snapshot($snapshot->excludeList(), false, false, false, false, true, false, false, false, false); + $newClasses = array_diff($current->classes(), $snapshot->classes()); + + unset($current); + + foreach ($snapshot->staticAttributes() as $className => $staticAttributes) { + foreach ($staticAttributes as $name => $value) { + $reflector = new ReflectionProperty($className, $name); + $reflector->setAccessible(true); + $reflector->setValue($value); + } + } + + foreach ($newClasses as $className) { + $class = new ReflectionClass($className); + $defaults = $class->getDefaultProperties(); + + foreach ($class->getProperties() as $attribute) { + if (!$attribute->isStatic()) { + continue; + } + + $name = $attribute->getName(); + + if ($snapshot->excludeList()->isStaticAttributeExcluded($className, $name)) { + continue; + } + + if (!isset($defaults[$name])) { + continue; + } + + $attribute->setAccessible(true); + $attribute->setValue($defaults[$name]); + } + } + } + + /** + * Restores a super-global variable array from this snapshot. + */ + private function restoreSuperGlobalArray(Snapshot $snapshot, string $superGlobalArray): void + { + $superGlobalVariables = $snapshot->superGlobalVariables(); + + if (isset($GLOBALS[$superGlobalArray]) && + is_array($GLOBALS[$superGlobalArray]) && + isset($superGlobalVariables[$superGlobalArray])) { + $keys = array_keys( + array_merge( + $GLOBALS[$superGlobalArray], + $superGlobalVariables[$superGlobalArray] + ) + ); + + foreach ($keys as $key) { + if (isset($superGlobalVariables[$superGlobalArray][$key])) { + $GLOBALS[$superGlobalArray][$key] = $superGlobalVariables[$superGlobalArray][$key]; + } else { + unset($GLOBALS[$superGlobalArray][$key]); + } + } + } + } +} diff --git a/vendor/sebastian/global-state/src/Snapshot.php b/vendor/sebastian/global-state/src/Snapshot.php new file mode 100644 index 000000000..e33264eb0 --- /dev/null +++ b/vendor/sebastian/global-state/src/Snapshot.php @@ -0,0 +1,443 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/global-state. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\GlobalState; + +use const PHP_VERSION_ID; +use function array_keys; +use function array_merge; +use function array_reverse; +use function func_get_args; +use function get_declared_classes; +use function get_declared_interfaces; +use function get_declared_traits; +use function get_defined_constants; +use function get_defined_functions; +use function get_included_files; +use function in_array; +use function ini_get_all; +use function is_array; +use function is_object; +use function is_resource; +use function is_scalar; +use function serialize; +use function unserialize; +use ReflectionClass; +use SebastianBergmann\ObjectReflector\ObjectReflector; +use SebastianBergmann\RecursionContext\Context; +use Throwable; + +/** + * A snapshot of global state. + */ +class Snapshot +{ + /** + * @var ExcludeList + */ + private $excludeList; + + /** + * @var array + */ + private $globalVariables = []; + + /** + * @var array + */ + private $superGlobalArrays = []; + + /** + * @var array + */ + private $superGlobalVariables = []; + + /** + * @var array + */ + private $staticAttributes = []; + + /** + * @var array + */ + private $iniSettings = []; + + /** + * @var array + */ + private $includedFiles = []; + + /** + * @var array + */ + private $constants = []; + + /** + * @var array + */ + private $functions = []; + + /** + * @var array + */ + private $interfaces = []; + + /** + * @var array + */ + private $classes = []; + + /** + * @var array + */ + private $traits = []; + + /** + * Creates a snapshot of the current global state. + */ + public function __construct(ExcludeList $excludeList = null, bool $includeGlobalVariables = true, bool $includeStaticAttributes = true, bool $includeConstants = true, bool $includeFunctions = true, bool $includeClasses = true, bool $includeInterfaces = true, bool $includeTraits = true, bool $includeIniSettings = true, bool $includeIncludedFiles = true) + { + $this->excludeList = $excludeList ?: new ExcludeList; + + if ($includeConstants) { + $this->snapshotConstants(); + } + + if ($includeFunctions) { + $this->snapshotFunctions(); + } + + if ($includeClasses || $includeStaticAttributes) { + $this->snapshotClasses(); + } + + if ($includeInterfaces) { + $this->snapshotInterfaces(); + } + + if ($includeGlobalVariables) { + $this->setupSuperGlobalArrays(); + $this->snapshotGlobals(); + } + + if ($includeStaticAttributes) { + $this->snapshotStaticAttributes(); + } + + if ($includeIniSettings) { + $this->iniSettings = ini_get_all(null, false); + } + + if ($includeIncludedFiles) { + $this->includedFiles = get_included_files(); + } + + if ($includeTraits) { + $this->traits = get_declared_traits(); + } + } + + public function excludeList(): ExcludeList + { + return $this->excludeList; + } + + public function globalVariables(): array + { + return $this->globalVariables; + } + + public function superGlobalVariables(): array + { + return $this->superGlobalVariables; + } + + public function superGlobalArrays(): array + { + return $this->superGlobalArrays; + } + + public function staticAttributes(): array + { + return $this->staticAttributes; + } + + public function iniSettings(): array + { + return $this->iniSettings; + } + + public function includedFiles(): array + { + return $this->includedFiles; + } + + public function constants(): array + { + return $this->constants; + } + + public function functions(): array + { + return $this->functions; + } + + public function interfaces(): array + { + return $this->interfaces; + } + + public function classes(): array + { + return $this->classes; + } + + public function traits(): array + { + return $this->traits; + } + + /** + * Creates a snapshot user-defined constants. + */ + private function snapshotConstants(): void + { + $constants = get_defined_constants(true); + + if (isset($constants['user'])) { + $this->constants = $constants['user']; + } + } + + /** + * Creates a snapshot user-defined functions. + */ + private function snapshotFunctions(): void + { + $functions = get_defined_functions(); + + $this->functions = $functions['user']; + } + + /** + * Creates a snapshot user-defined classes. + */ + private function snapshotClasses(): void + { + foreach (array_reverse(get_declared_classes()) as $className) { + $class = new ReflectionClass($className); + + if (!$class->isUserDefined()) { + break; + } + + $this->classes[] = $className; + } + + $this->classes = array_reverse($this->classes); + } + + /** + * Creates a snapshot user-defined interfaces. + */ + private function snapshotInterfaces(): void + { + foreach (array_reverse(get_declared_interfaces()) as $interfaceName) { + $class = new ReflectionClass($interfaceName); + + if (!$class->isUserDefined()) { + break; + } + + $this->interfaces[] = $interfaceName; + } + + $this->interfaces = array_reverse($this->interfaces); + } + + /** + * Creates a snapshot of all global and super-global variables. + */ + private function snapshotGlobals(): void + { + $superGlobalArrays = $this->superGlobalArrays(); + + foreach ($superGlobalArrays as $superGlobalArray) { + $this->snapshotSuperGlobalArray($superGlobalArray); + } + + foreach (array_keys($GLOBALS) as $key) { + if ($key !== 'GLOBALS' && + !in_array($key, $superGlobalArrays, true) && + $this->canBeSerialized($GLOBALS[$key]) && + !$this->excludeList->isGlobalVariableExcluded($key)) { + /* @noinspection UnserializeExploitsInspection */ + $this->globalVariables[$key] = unserialize(serialize($GLOBALS[$key])); + } + } + } + + /** + * Creates a snapshot a super-global variable array. + */ + private function snapshotSuperGlobalArray(string $superGlobalArray): void + { + $this->superGlobalVariables[$superGlobalArray] = []; + + if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) { + foreach ($GLOBALS[$superGlobalArray] as $key => $value) { + /* @noinspection UnserializeExploitsInspection */ + $this->superGlobalVariables[$superGlobalArray][$key] = unserialize(serialize($value)); + } + } + } + + /** + * Creates a snapshot of all static attributes in user-defined classes. + */ + private function snapshotStaticAttributes(): void + { + foreach ($this->classes as $className) { + $class = new ReflectionClass($className); + $snapshot = []; + + foreach ($class->getProperties() as $attribute) { + if ($attribute->isStatic()) { + $name = $attribute->getName(); + + if ($this->excludeList->isStaticAttributeExcluded($className, $name)) { + continue; + } + + $attribute->setAccessible(true); + + if (PHP_VERSION_ID >= 70400 && !$attribute->isInitialized()) { + continue; + } + + $value = $attribute->getValue(); + + if ($this->canBeSerialized($value)) { + /* @noinspection UnserializeExploitsInspection */ + $snapshot[$name] = unserialize(serialize($value)); + } + } + } + + if (!empty($snapshot)) { + $this->staticAttributes[$className] = $snapshot; + } + } + } + + /** + * Returns a list of all super-global variable arrays. + */ + private function setupSuperGlobalArrays(): void + { + $this->superGlobalArrays = [ + '_ENV', + '_POST', + '_GET', + '_COOKIE', + '_SERVER', + '_FILES', + '_REQUEST', + ]; + } + + private function canBeSerialized($variable): bool + { + if (is_scalar($variable) || $variable === null) { + return true; + } + + if (is_resource($variable)) { + return false; + } + + foreach ($this->enumerateObjectsAndResources($variable) as $value) { + if (is_resource($value)) { + return false; + } + + if (is_object($value)) { + $class = new ReflectionClass($value); + + if ($class->isAnonymous()) { + return false; + } + + try { + @serialize($value); + } catch (Throwable $t) { + return false; + } + } + } + + return true; + } + + private function enumerateObjectsAndResources($variable): array + { + if (isset(func_get_args()[1])) { + $processed = func_get_args()[1]; + } else { + $processed = new Context; + } + + $result = []; + + if ($processed->contains($variable)) { + return $result; + } + + $array = $variable; + $processed->add($variable); + + if (is_array($variable)) { + foreach ($array as $element) { + if (!is_array($element) && !is_object($element) && !is_resource($element)) { + continue; + } + + if (!is_resource($element)) { + /** @noinspection SlowArrayOperationsInLoopInspection */ + $result = array_merge( + $result, + $this->enumerateObjectsAndResources($element, $processed) + ); + } else { + $result[] = $element; + } + } + } else { + $result[] = $variable; + + foreach ((new ObjectReflector)->getAttributes($variable) as $value) { + if (!is_array($value) && !is_object($value) && !is_resource($value)) { + continue; + } + + if (!is_resource($value)) { + /** @noinspection SlowArrayOperationsInLoopInspection */ + $result = array_merge( + $result, + $this->enumerateObjectsAndResources($value, $processed) + ); + } else { + $result[] = $value; + } + } + } + + return $result; + } +} diff --git a/vendor/sebastian/global-state/src/exceptions/Exception.php b/vendor/sebastian/global-state/src/exceptions/Exception.php new file mode 100644 index 000000000..94432008e --- /dev/null +++ b/vendor/sebastian/global-state/src/exceptions/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/global-state. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\GlobalState; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/global-state/src/exceptions/RuntimeException.php b/vendor/sebastian/global-state/src/exceptions/RuntimeException.php new file mode 100644 index 000000000..79f02a114 --- /dev/null +++ b/vendor/sebastian/global-state/src/exceptions/RuntimeException.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/global-state. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\GlobalState; + +final class RuntimeException extends \RuntimeException implements Exception +{ +} diff --git a/vendor/sebastian/lines-of-code/.psalm/baseline.xml b/vendor/sebastian/lines-of-code/.psalm/baseline.xml new file mode 100644 index 000000000..77e688e07 --- /dev/null +++ b/vendor/sebastian/lines-of-code/.psalm/baseline.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44"/> diff --git a/vendor/sebastian/lines-of-code/.psalm/config.xml b/vendor/sebastian/lines-of-code/.psalm/config.xml new file mode 100644 index 000000000..15abef058 --- /dev/null +++ b/vendor/sebastian/lines-of-code/.psalm/config.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<psalm + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="https://getpsalm.org/schema/config" + xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" + resolveFromConfigFile="false" + totallyTyped="true" + errorBaseline=".psalm/baseline.xml" +> + <projectFiles> + <directory name="src" /> + <ignoreFiles> + <directory name="vendor" /> + </ignoreFiles> + </projectFiles> +</psalm> diff --git a/vendor/sebastian/lines-of-code/ChangeLog.md b/vendor/sebastian/lines-of-code/ChangeLog.md new file mode 100644 index 000000000..39bcaad49 --- /dev/null +++ b/vendor/sebastian/lines-of-code/ChangeLog.md @@ -0,0 +1,34 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. + +## [1.0.3] - 2020-11-28 + +### Fixed + +* Files that do not contain a newline were not handled correctly + +### Changed + +* A line of code is no longer considered to be a Logical Line of Code if it does not contain an `Expr` node + +## [1.0.2] - 2020-10-26 + +### Fixed + +* `SebastianBergmann\LinesOfCode\Exception` now correctly extends `\Throwable` + +## [1.0.1] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [1.0.0] - 2020-07-22 + +* Initial release + +[1.0.3]: https://github.com/sebastianbergmann/lines-of-code/compare/1.0.2...1.0.3 +[1.0.2]: https://github.com/sebastianbergmann/lines-of-code/compare/1.0.1...1.0.2 +[1.0.1]: https://github.com/sebastianbergmann/lines-of-code/compare/1.0.0...1.0.1 +[1.0.0]: https://github.com/sebastianbergmann/lines-of-code/compare/f959e71f00e591288acc024afe9cb966c6cf9bd6...1.0.0 diff --git a/vendor/sebastian/lines-of-code/LICENSE b/vendor/sebastian/lines-of-code/LICENSE new file mode 100644 index 000000000..d170181fa --- /dev/null +++ b/vendor/sebastian/lines-of-code/LICENSE @@ -0,0 +1,33 @@ +sebastian/lines-of-code + +Copyright (c) 2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/lines-of-code/README.md b/vendor/sebastian/lines-of-code/README.md new file mode 100644 index 000000000..9457ef5a7 --- /dev/null +++ b/vendor/sebastian/lines-of-code/README.md @@ -0,0 +1,22 @@ +# sebastian/lines-of-code + +Library for counting the lines of code in PHP source code. + +[![Latest Stable Version](https://img.shields.io/packagist/v/sebastian/lines-of-code.svg?style=flat-square)](https://packagist.org/packages/sebastian/lines-of-code) +[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.3-8892BF.svg?style=flat-square)](https://php.net/) +[![CI Status](https://github.com/sebastianbergmann/lines-of-code/workflows/CI/badge.svg?branch=master&event=push)](https://phpunit.de/build-status.html) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/lines-of-code/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/lines-of-code) + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/lines-of-code +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/lines-of-code +``` diff --git a/vendor/sebastian/lines-of-code/composer.json b/vendor/sebastian/lines-of-code/composer.json new file mode 100644 index 000000000..95bb9e363 --- /dev/null +++ b/vendor/sebastian/lines-of-code/composer.json @@ -0,0 +1,42 @@ +{ + "name": "sebastian/lines-of-code", + "description": "Library for counting the lines of code in PHP source code", + "type": "library", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues" + }, + "prefer-stable": true, + "require": { + "php": ">=7.3", + "nikic/php-parser": "^4.6" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + } +} diff --git a/vendor/sebastian/lines-of-code/src/Counter.php b/vendor/sebastian/lines-of-code/src/Counter.php new file mode 100644 index 000000000..cfe5e20a7 --- /dev/null +++ b/vendor/sebastian/lines-of-code/src/Counter.php @@ -0,0 +1,91 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/lines-of-code. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\LinesOfCode; + +use function substr_count; +use PhpParser\Error; +use PhpParser\Lexer; +use PhpParser\Node; +use PhpParser\NodeTraverser; +use PhpParser\Parser; +use PhpParser\ParserFactory; + +final class Counter +{ + /** + * @throws RuntimeException + */ + public function countInSourceFile(string $sourceFile): LinesOfCode + { + return $this->countInSourceString(file_get_contents($sourceFile)); + } + + /** + * @throws RuntimeException + */ + public function countInSourceString(string $source): LinesOfCode + { + $linesOfCode = substr_count($source, "\n"); + + if ($linesOfCode === 0 && !empty($source)) { + $linesOfCode = 1; + } + + try { + $nodes = $this->parser()->parse($source); + + assert($nodes !== null); + + return $this->countInAbstractSyntaxTree($linesOfCode, $nodes); + + // @codeCoverageIgnoreStart + } catch (Error $error) { + throw new RuntimeException( + $error->getMessage(), + (int) $error->getCode(), + $error + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @param Node[] $nodes + * + * @throws RuntimeException + */ + public function countInAbstractSyntaxTree(int $linesOfCode, array $nodes): LinesOfCode + { + $traverser = new NodeTraverser; + $visitor = new LineCountingVisitor($linesOfCode); + + $traverser->addVisitor($visitor); + + try { + /* @noinspection UnusedFunctionResultInspection */ + $traverser->traverse($nodes); + // @codeCoverageIgnoreStart + } catch (Error $error) { + throw new RuntimeException( + $error->getMessage(), + (int) $error->getCode(), + $error + ); + } + // @codeCoverageIgnoreEnd + + return $visitor->result(); + } + + private function parser(): Parser + { + return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer); + } +} diff --git a/vendor/sebastian/lines-of-code/src/Exception/Exception.php b/vendor/sebastian/lines-of-code/src/Exception/Exception.php new file mode 100644 index 000000000..11d543aa7 --- /dev/null +++ b/vendor/sebastian/lines-of-code/src/Exception/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/lines-of-code. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\LinesOfCode; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php b/vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php new file mode 100644 index 000000000..46a5c1b1f --- /dev/null +++ b/vendor/sebastian/lines-of-code/src/Exception/IllogicalValuesException.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/lines-of-code. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\LinesOfCode; + +use LogicException; + +final class IllogicalValuesException extends LogicException implements Exception +{ +} diff --git a/vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php b/vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php new file mode 100644 index 000000000..40d27e1f0 --- /dev/null +++ b/vendor/sebastian/lines-of-code/src/Exception/NegativeValueException.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/lines-of-code. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\LinesOfCode; + +use InvalidArgumentException; + +final class NegativeValueException extends InvalidArgumentException implements Exception +{ +} diff --git a/vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php b/vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php new file mode 100644 index 000000000..4e6d66d0d --- /dev/null +++ b/vendor/sebastian/lines-of-code/src/Exception/RuntimeException.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/lines-of-code. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\LinesOfCode; + +final class RuntimeException extends \RuntimeException implements Exception +{ +} diff --git a/vendor/sebastian/lines-of-code/src/LineCountingVisitor.php b/vendor/sebastian/lines-of-code/src/LineCountingVisitor.php new file mode 100644 index 000000000..ff433b2fc --- /dev/null +++ b/vendor/sebastian/lines-of-code/src/LineCountingVisitor.php @@ -0,0 +1,82 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/lines-of-code. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\LinesOfCode; + +use function array_merge; +use function array_unique; +use function count; +use PhpParser\Comment; +use PhpParser\Node; +use PhpParser\Node\Expr; +use PhpParser\NodeVisitorAbstract; + +final class LineCountingVisitor extends NodeVisitorAbstract +{ + /** + * @var int + */ + private $linesOfCode; + + /** + * @var Comment[] + */ + private $comments = []; + + /** + * @var int[] + */ + private $linesWithStatements = []; + + public function __construct(int $linesOfCode) + { + $this->linesOfCode = $linesOfCode; + } + + public function enterNode(Node $node): void + { + $this->comments = array_merge($this->comments, $node->getComments()); + + if (!$node instanceof Expr) { + return; + } + + $this->linesWithStatements[] = $node->getStartLine(); + } + + public function result(): LinesOfCode + { + $commentLinesOfCode = 0; + + foreach ($this->comments() as $comment) { + $commentLinesOfCode += ($comment->getEndLine() - $comment->getStartLine() + 1); + } + + return new LinesOfCode( + $this->linesOfCode, + $commentLinesOfCode, + $this->linesOfCode - $commentLinesOfCode, + count(array_unique($this->linesWithStatements)) + ); + } + + /** + * @return Comment[] + */ + private function comments(): array + { + $comments = []; + + foreach ($this->comments as $comment) { + $comments[$comment->getStartLine() . '_' . $comment->getStartTokenPos() . '_' . $comment->getEndLine() . '_' . $comment->getEndTokenPos()] = $comment; + } + + return $comments; + } +} diff --git a/vendor/sebastian/lines-of-code/src/LinesOfCode.php b/vendor/sebastian/lines-of-code/src/LinesOfCode.php new file mode 100644 index 000000000..41829981a --- /dev/null +++ b/vendor/sebastian/lines-of-code/src/LinesOfCode.php @@ -0,0 +1,98 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/lines-of-code. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\LinesOfCode; + +/** + * @psalm-immutable + */ +final class LinesOfCode +{ + /** + * @var int + */ + private $linesOfCode; + + /** + * @var int + */ + private $commentLinesOfCode; + + /** + * @var int + */ + private $nonCommentLinesOfCode; + + /** + * @var int + */ + private $logicalLinesOfCode; + + /** + * @throws IllogicalValuesException + * @throws NegativeValueException + */ + public function __construct(int $linesOfCode, int $commentLinesOfCode, int $nonCommentLinesOfCode, int $logicalLinesOfCode) + { + if ($linesOfCode < 0) { + throw new NegativeValueException('$linesOfCode must not be negative'); + } + + if ($commentLinesOfCode < 0) { + throw new NegativeValueException('$commentLinesOfCode must not be negative'); + } + + if ($nonCommentLinesOfCode < 0) { + throw new NegativeValueException('$nonCommentLinesOfCode must not be negative'); + } + + if ($logicalLinesOfCode < 0) { + throw new NegativeValueException('$logicalLinesOfCode must not be negative'); + } + + if ($linesOfCode - $commentLinesOfCode !== $nonCommentLinesOfCode) { + throw new IllogicalValuesException('$linesOfCode !== $commentLinesOfCode + $nonCommentLinesOfCode'); + } + + $this->linesOfCode = $linesOfCode; + $this->commentLinesOfCode = $commentLinesOfCode; + $this->nonCommentLinesOfCode = $nonCommentLinesOfCode; + $this->logicalLinesOfCode = $logicalLinesOfCode; + } + + public function linesOfCode(): int + { + return $this->linesOfCode; + } + + public function commentLinesOfCode(): int + { + return $this->commentLinesOfCode; + } + + public function nonCommentLinesOfCode(): int + { + return $this->nonCommentLinesOfCode; + } + + public function logicalLinesOfCode(): int + { + return $this->logicalLinesOfCode; + } + + public function plus(self $other): self + { + return new self( + $this->linesOfCode() + $other->linesOfCode(), + $this->commentLinesOfCode() + $other->commentLinesOfCode(), + $this->nonCommentLinesOfCode() + $other->nonCommentLinesOfCode(), + $this->logicalLinesOfCode() + $other->logicalLinesOfCode(), + ); + } +} diff --git a/vendor/sebastian/object-enumerator/.psalm/baseline.xml b/vendor/sebastian/object-enumerator/.psalm/baseline.xml new file mode 100644 index 000000000..180b3f803 --- /dev/null +++ b/vendor/sebastian/object-enumerator/.psalm/baseline.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44"> + <file src="src/Enumerator.php"> + <DocblockTypeContradiction occurrences="2"> + <code>!is_array($variable) && !is_object($variable)</code> + <code>is_object($variable)</code> + </DocblockTypeContradiction> + </file> +</files> diff --git a/vendor/sebastian/object-enumerator/.psalm/config.xml b/vendor/sebastian/object-enumerator/.psalm/config.xml new file mode 100644 index 000000000..2a4b16f22 --- /dev/null +++ b/vendor/sebastian/object-enumerator/.psalm/config.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<psalm + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="https://getpsalm.org/schema/config" + xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" + resolveFromConfigFile="false" + totallyTyped="false" + errorBaseline=".psalm/baseline.xml" +> + <projectFiles> + <directory name="src" /> + <ignoreFiles> + <directory name="vendor" /> + </ignoreFiles> + </projectFiles> +</psalm> diff --git a/vendor/sebastian/object-enumerator/ChangeLog.md b/vendor/sebastian/object-enumerator/ChangeLog.md new file mode 100644 index 000000000..886554189 --- /dev/null +++ b/vendor/sebastian/object-enumerator/ChangeLog.md @@ -0,0 +1,88 @@ +# Change Log + +All notable changes to `sebastianbergmann/object-enumerator` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.0.4] - 2020-10-26 + +### Fixed + +* `SebastianBergmann\ObjectEnumerator\Exception` now correctly extends `\Throwable` + +## [4.0.3] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [4.0.2] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [4.0.1] - 2020-06-15 + +### Changed + +* Tests etc. are now ignored for archive exports + +## [4.0.0] - 2020-02-07 + +### Removed + +* This component is no longer supported on PHP 7.0, PHP 7.1, and PHP 7.2 + +## [3.0.3] - 2017-08-03 + +### Changed + +* Bumped required version of `sebastian/object-reflector` + +## [3.0.2] - 2017-03-12 + +### Changed + +* `sebastian/object-reflector` is now a dependency + +## [3.0.1] - 2017-03-12 + +### Fixed + +* Objects aggregated in inherited attributes are not enumerated + +## [3.0.0] - 2017-03-03 + +### Removed + +* This component is no longer supported on PHP 5.6 + +## [2.0.1] - 2017-02-18 + +### Fixed + +* Fixed [#2](https://github.com/sebastianbergmann/phpunit/pull/2): Exceptions in `ReflectionProperty::getValue()` are not handled + +## [2.0.0] - 2016-11-19 + +### Changed + +* This component is now compatible with `sebastian/recursion-context: ~1.0.4` + +## 1.0.0 - 2016-02-04 + +### Added + +* Initial release + +[4.0.4]: https://github.com/sebastianbergmann/object-enumerator/compare/4.0.3...4.0.4 +[4.0.3]: https://github.com/sebastianbergmann/object-enumerator/compare/4.0.2...4.0.3 +[4.0.2]: https://github.com/sebastianbergmann/object-enumerator/compare/4.0.1...4.0.2 +[4.0.1]: https://github.com/sebastianbergmann/object-enumerator/compare/4.0.0...4.0.1 +[4.0.0]: https://github.com/sebastianbergmann/object-enumerator/compare/3.0.3...4.0.0 +[3.0.3]: https://github.com/sebastianbergmann/object-enumerator/compare/3.0.2...3.0.3 +[3.0.2]: https://github.com/sebastianbergmann/object-enumerator/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/sebastianbergmann/object-enumerator/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/sebastianbergmann/object-enumerator/compare/2.0...3.0.0 +[2.0.1]: https://github.com/sebastianbergmann/object-enumerator/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/sebastianbergmann/object-enumerator/compare/1.0...2.0.0 + diff --git a/vendor/sebastian/object-enumerator/LICENSE b/vendor/sebastian/object-enumerator/LICENSE new file mode 100644 index 000000000..1389ad396 --- /dev/null +++ b/vendor/sebastian/object-enumerator/LICENSE @@ -0,0 +1,33 @@ +Object Enumerator + +Copyright (c) 2016-2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/object-enumerator/README.md b/vendor/sebastian/object-enumerator/README.md new file mode 100644 index 000000000..afca0177b --- /dev/null +++ b/vendor/sebastian/object-enumerator/README.md @@ -0,0 +1,20 @@ +# sebastian/object-enumerator + +[![CI Status](https://github.com/sebastianbergmann/object-enumerator/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/object-enumerator/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/object-enumerator/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/object-enumerator) + +Traverses array structures and object graphs to enumerate all referenced objects. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/object-enumerator +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/object-enumerator +``` diff --git a/vendor/sebastian/object-enumerator/composer.json b/vendor/sebastian/object-enumerator/composer.json new file mode 100644 index 000000000..d68a21330 --- /dev/null +++ b/vendor/sebastian/object-enumerator/composer.json @@ -0,0 +1,43 @@ +{ + "name": "sebastian/object-enumerator", + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]" + } + ], + "prefer-stable": true, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "autoload-dev": { + "classmap": [ + "tests/_fixture/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + } +} diff --git a/vendor/sebastian/object-enumerator/phpunit.xml b/vendor/sebastian/object-enumerator/phpunit.xml new file mode 100644 index 000000000..7be976b13 --- /dev/null +++ b/vendor/sebastian/object-enumerator/phpunit.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" + bootstrap="vendor/autoload.php" + executionOrder="depends,defects" + forceCoversAnnotation="true" + beStrictAboutCoversAnnotation="true" + beStrictAboutOutputDuringTests="true" + beStrictAboutTodoAnnotatedTests="true" + failOnRisky="true" + failOnWarning="true" + verbose="true"> + <testsuites> + <testsuite name="default"> + <directory suffix="Test.php">tests</directory> + </testsuite> + </testsuites> + + <coverage processUncoveredFiles="true"> + <include> + <directory suffix=".php">src</directory> + </include> + </coverage> +</phpunit> diff --git a/vendor/sebastian/object-enumerator/src/Enumerator.php b/vendor/sebastian/object-enumerator/src/Enumerator.php new file mode 100644 index 000000000..de75d17c5 --- /dev/null +++ b/vendor/sebastian/object-enumerator/src/Enumerator.php @@ -0,0 +1,88 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/object-enumerator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\ObjectEnumerator; + +use function array_merge; +use function func_get_args; +use function is_array; +use function is_object; +use SebastianBergmann\ObjectReflector\ObjectReflector; +use SebastianBergmann\RecursionContext\Context; + +/** + * Traverses array structures and object graphs + * to enumerate all referenced objects. + */ +class Enumerator +{ + /** + * Returns an array of all objects referenced either + * directly or indirectly by a variable. + * + * @param array|object $variable + * + * @return object[] + */ + public function enumerate($variable) + { + if (!is_array($variable) && !is_object($variable)) { + throw new InvalidArgumentException; + } + + if (isset(func_get_args()[1])) { + if (!func_get_args()[1] instanceof Context) { + throw new InvalidArgumentException; + } + + $processed = func_get_args()[1]; + } else { + $processed = new Context; + } + + $objects = []; + + if ($processed->contains($variable)) { + return $objects; + } + + $array = $variable; + $processed->add($variable); + + if (is_array($variable)) { + foreach ($array as $element) { + if (!is_array($element) && !is_object($element)) { + continue; + } + + $objects = array_merge( + $objects, + $this->enumerate($element, $processed) + ); + } + } else { + $objects[] = $variable; + + $reflector = new ObjectReflector; + + foreach ($reflector->getAttributes($variable) as $value) { + if (!is_array($value) && !is_object($value)) { + continue; + } + + $objects = array_merge( + $objects, + $this->enumerate($value, $processed) + ); + } + } + + return $objects; + } +} diff --git a/vendor/sebastian/object-enumerator/src/Exception.php b/vendor/sebastian/object-enumerator/src/Exception.php new file mode 100644 index 000000000..2f09d70aa --- /dev/null +++ b/vendor/sebastian/object-enumerator/src/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/object-enumerator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\ObjectEnumerator; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/object-enumerator/src/InvalidArgumentException.php b/vendor/sebastian/object-enumerator/src/InvalidArgumentException.php new file mode 100644 index 000000000..ce2037cdb --- /dev/null +++ b/vendor/sebastian/object-enumerator/src/InvalidArgumentException.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/object-enumerator. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\ObjectEnumerator; + +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ +} diff --git a/vendor/sebastian/object-reflector/.psalm/baseline.xml b/vendor/sebastian/object-reflector/.psalm/baseline.xml new file mode 100644 index 000000000..965c12757 --- /dev/null +++ b/vendor/sebastian/object-reflector/.psalm/baseline.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44"> + <file src="src/ObjectReflector.php"> + <DocblockTypeContradiction occurrences="1"> + <code>is_object($object)</code> + </DocblockTypeContradiction> + </file> +</files> diff --git a/vendor/sebastian/object-reflector/.psalm/config.xml b/vendor/sebastian/object-reflector/.psalm/config.xml new file mode 100644 index 000000000..2a4b16f22 --- /dev/null +++ b/vendor/sebastian/object-reflector/.psalm/config.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<psalm + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="https://getpsalm.org/schema/config" + xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" + resolveFromConfigFile="false" + totallyTyped="false" + errorBaseline=".psalm/baseline.xml" +> + <projectFiles> + <directory name="src" /> + <ignoreFiles> + <directory name="vendor" /> + </ignoreFiles> + </projectFiles> +</psalm> diff --git a/vendor/sebastian/object-reflector/ChangeLog.md b/vendor/sebastian/object-reflector/ChangeLog.md new file mode 100644 index 000000000..7fa62e90f --- /dev/null +++ b/vendor/sebastian/object-reflector/ChangeLog.md @@ -0,0 +1,55 @@ +# Change Log + +All notable changes to `sebastianbergmann/object-reflector` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [2.0.4] - 2020-10-26 + +### Fixed + +* `SebastianBergmann\ObjectReflector\Exception` now correctly extends `\Throwable` + +## [2.0.3] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [2.0.2] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [2.0.1] - 2020-06-15 + +### Changed + +* Tests etc. are now ignored for archive exports + +## [2.0.0] - 2020-02-07 + +### Removed + +* This component is no longer supported on PHP 7.0, PHP 7.1, and PHP 7.2 + +## [1.1.1] - 2017-03-29 + +* Fixed [#1](https://github.com/sebastianbergmann/object-reflector/issues/1): Attributes with non-string names are not handled correctly + +## [1.1.0] - 2017-03-16 + +### Changed + +* Changed implementation of `ObjectReflector::getattributes()` to use `(array)` cast instead of `ReflectionObject` + +## 1.0.0 - 2017-03-12 + +* Initial release + +[2.0.4]: https://github.com/sebastianbergmann/object-reflector/compare/2.0.3...2.0.4 +[2.0.3]: https://github.com/sebastianbergmann/object-reflector/compare/2.0.2...2.0.3 +[2.0.2]: https://github.com/sebastianbergmann/object-reflector/compare/2.0.1...2.0.2 +[2.0.1]: https://github.com/sebastianbergmann/object-reflector/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/sebastianbergmann/object-reflector/compare/1.1.1...2.0.0 +[1.1.1]: https://github.com/sebastianbergmann/object-reflector/compare/1.1.0...1.1.1 +[1.1.0]: https://github.com/sebastianbergmann/object-reflector/compare/1.0.0...1.1.0 diff --git a/vendor/sebastian/object-reflector/LICENSE b/vendor/sebastian/object-reflector/LICENSE new file mode 100644 index 000000000..a80c16192 --- /dev/null +++ b/vendor/sebastian/object-reflector/LICENSE @@ -0,0 +1,33 @@ +Object Reflector + +Copyright (c) 2017-2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/object-reflector/README.md b/vendor/sebastian/object-reflector/README.md new file mode 100644 index 000000000..b7d5ae95f --- /dev/null +++ b/vendor/sebastian/object-reflector/README.md @@ -0,0 +1,20 @@ +# sebastian/object-reflector + +[![CI Status](https://github.com/sebastianbergmann/object-reflector/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/object-reflector/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/object-reflector/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/object-reflector) + +Allows reflection of object attributes, including inherited and non-public ones. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/object-reflector +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/object-reflector +``` diff --git a/vendor/sebastian/object-reflector/composer.json b/vendor/sebastian/object-reflector/composer.json new file mode 100644 index 000000000..36a337885 --- /dev/null +++ b/vendor/sebastian/object-reflector/composer.json @@ -0,0 +1,41 @@ +{ + "name": "sebastian/object-reflector", + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]" + } + ], + "prefer-stable": true, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "autoload-dev": { + "classmap": [ + "tests/_fixture/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + } +} diff --git a/vendor/sebastian/object-reflector/src/Exception.php b/vendor/sebastian/object-reflector/src/Exception.php new file mode 100644 index 000000000..36f8efeca --- /dev/null +++ b/vendor/sebastian/object-reflector/src/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/object-reflector. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\ObjectReflector; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/object-reflector/src/InvalidArgumentException.php b/vendor/sebastian/object-reflector/src/InvalidArgumentException.php new file mode 100644 index 000000000..34b4cca19 --- /dev/null +++ b/vendor/sebastian/object-reflector/src/InvalidArgumentException.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/object-reflector. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\ObjectReflector; + +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ +} diff --git a/vendor/sebastian/object-reflector/src/ObjectReflector.php b/vendor/sebastian/object-reflector/src/ObjectReflector.php new file mode 100644 index 000000000..4abb5f55f --- /dev/null +++ b/vendor/sebastian/object-reflector/src/ObjectReflector.php @@ -0,0 +1,51 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/object-reflector. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\ObjectReflector; + +use function count; +use function explode; +use function get_class; +use function is_object; + +class ObjectReflector +{ + /** + * @param object $object + * + * @throws InvalidArgumentException + */ + public function getAttributes($object): array + { + if (!is_object($object)) { + throw new InvalidArgumentException; + } + + $attributes = []; + $className = get_class($object); + + foreach ((array) $object as $name => $value) { + $name = explode("\0", (string) $name); + + if (count($name) === 1) { + $name = $name[0]; + } else { + if ($name[1] !== $className) { + $name = $name[1] . '::' . $name[2]; + } else { + $name = $name[2]; + } + } + + $attributes[$name] = $value; + } + + return $attributes; + } +} diff --git a/vendor/sebastian/recursion-context/.psalm/baseline.xml b/vendor/sebastian/recursion-context/.psalm/baseline.xml new file mode 100644 index 000000000..b946db1a5 --- /dev/null +++ b/vendor/sebastian/recursion-context/.psalm/baseline.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<files psalm-version="4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44"> + <file src="src/Context.php"> + <RedundantConditionGivenDocblockType occurrences="1"> + <code>is_array($array)</code> + </RedundantConditionGivenDocblockType> + </file> +</files> diff --git a/vendor/sebastian/recursion-context/.psalm/config.xml b/vendor/sebastian/recursion-context/.psalm/config.xml new file mode 100644 index 000000000..2a4b16f22 --- /dev/null +++ b/vendor/sebastian/recursion-context/.psalm/config.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<psalm + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="https://getpsalm.org/schema/config" + xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" + resolveFromConfigFile="false" + totallyTyped="false" + errorBaseline=".psalm/baseline.xml" +> + <projectFiles> + <directory name="src" /> + <ignoreFiles> + <directory name="vendor" /> + </ignoreFiles> + </projectFiles> +</psalm> diff --git a/vendor/sebastian/recursion-context/ChangeLog.md b/vendor/sebastian/recursion-context/ChangeLog.md new file mode 100644 index 000000000..2fbacc2c3 --- /dev/null +++ b/vendor/sebastian/recursion-context/ChangeLog.md @@ -0,0 +1,33 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. + +## [4.0.4] - 2020-10-26 + +### Fixed + +* `SebastianBergmann\RecursionContext\Exception` now correctly extends `\Throwable` + +## [4.0.3] - 2020-09-28 + +### Changed + +* [#21](https://github.com/sebastianbergmann/recursion-context/pull/21): Add type annotations for in/out parameters +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [4.0.2] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [4.0.1] - 2020-06-15 + +### Changed + +* Tests etc. are now ignored for archive exports + +[4.0.4]: https://github.com/sebastianbergmann/recursion-context/compare/4.0.3...4.0.4 +[4.0.3]: https://github.com/sebastianbergmann/recursion-context/compare/4.0.2...4.0.3 +[4.0.2]: https://github.com/sebastianbergmann/recursion-context/compare/4.0.1...4.0.2 +[4.0.1]: https://github.com/sebastianbergmann/recursion-context/compare/4.0.0...4.0.1 diff --git a/vendor/sebastian/recursion-context/LICENSE b/vendor/sebastian/recursion-context/LICENSE new file mode 100644 index 000000000..0faffbbb2 --- /dev/null +++ b/vendor/sebastian/recursion-context/LICENSE @@ -0,0 +1,33 @@ +Recursion Context + +Copyright (c) 2002-2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/recursion-context/README.md b/vendor/sebastian/recursion-context/README.md new file mode 100644 index 000000000..8e4d2a084 --- /dev/null +++ b/vendor/sebastian/recursion-context/README.md @@ -0,0 +1,18 @@ +# sebastian/recursion-context + +[![CI Status](https://github.com/sebastianbergmann/recursion-context/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/recursion-context/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/recursion-context/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/recursion-context) + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/recursion-context +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/recursion-context +``` diff --git a/vendor/sebastian/recursion-context/composer.json b/vendor/sebastian/recursion-context/composer.json new file mode 100644 index 000000000..8a5408232 --- /dev/null +++ b/vendor/sebastian/recursion-context/composer.json @@ -0,0 +1,44 @@ +{ + "name": "sebastian/recursion-context", + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]" + }, + { + "name": "Jeff Welch", + "email": "[email protected]" + }, + { + "name": "Adam Harvey", + "email": "[email protected]" + } + ], + "prefer-stable": true, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + } +} diff --git a/vendor/sebastian/recursion-context/src/Context.php b/vendor/sebastian/recursion-context/src/Context.php new file mode 100644 index 000000000..87fe7b04f --- /dev/null +++ b/vendor/sebastian/recursion-context/src/Context.php @@ -0,0 +1,186 @@ +<?php declare(strict_types=1); +/* + * This file is part of the Recursion Context package. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\RecursionContext; + +use const PHP_INT_MAX; +use const PHP_INT_MIN; +use function array_pop; +use function array_slice; +use function count; +use function is_array; +use function is_object; +use function random_int; +use function spl_object_hash; +use SplObjectStorage; + +/** + * A context containing previously processed arrays and objects + * when recursively processing a value. + */ +final class Context +{ + /** + * @var array[] + */ + private $arrays; + + /** + * @var SplObjectStorage + */ + private $objects; + + /** + * Initialises the context. + */ + public function __construct() + { + $this->arrays = []; + $this->objects = new SplObjectStorage; + } + + /** + * @codeCoverageIgnore + */ + public function __destruct() + { + foreach ($this->arrays as &$array) { + if (is_array($array)) { + array_pop($array); + array_pop($array); + } + } + } + + /** + * Adds a value to the context. + * + * @param array|object $value the value to add + * + * @throws InvalidArgumentException Thrown if $value is not an array or object + * + * @return bool|int|string the ID of the stored value, either as a string or integer + * + * @psalm-template T + * @psalm-param T $value + * @param-out T $value + */ + public function add(&$value) + { + if (is_array($value)) { + return $this->addArray($value); + } + + if (is_object($value)) { + return $this->addObject($value); + } + + throw new InvalidArgumentException( + 'Only arrays and objects are supported' + ); + } + + /** + * Checks if the given value exists within the context. + * + * @param array|object $value the value to check + * + * @throws InvalidArgumentException Thrown if $value is not an array or object + * + * @return false|int|string the string or integer ID of the stored value if it has already been seen, or false if the value is not stored + * + * @psalm-template T + * @psalm-param T $value + * @param-out T $value + */ + public function contains(&$value) + { + if (is_array($value)) { + return $this->containsArray($value); + } + + if (is_object($value)) { + return $this->containsObject($value); + } + + throw new InvalidArgumentException( + 'Only arrays and objects are supported' + ); + } + + /** + * @return bool|int + */ + private function addArray(array &$array) + { + $key = $this->containsArray($array); + + if ($key !== false) { + return $key; + } + + $key = count($this->arrays); + $this->arrays[] = &$array; + + if (!isset($array[PHP_INT_MAX]) && !isset($array[PHP_INT_MAX - 1])) { + $array[] = $key; + $array[] = $this->objects; + } else { /* cover the improbable case too */ + do { + $key = random_int(PHP_INT_MIN, PHP_INT_MAX); + } while (isset($array[$key])); + + $array[$key] = $key; + + do { + $key = random_int(PHP_INT_MIN, PHP_INT_MAX); + } while (isset($array[$key])); + + $array[$key] = $this->objects; + } + + return $key; + } + + /** + * @param object $object + */ + private function addObject($object): string + { + if (!$this->objects->contains($object)) { + $this->objects->attach($object); + } + + return spl_object_hash($object); + } + + /** + * @return false|int + */ + private function containsArray(array &$array) + { + $end = array_slice($array, -2); + + return isset($end[1]) && $end[1] === $this->objects ? $end[0] : false; + } + + /** + * @param object $value + * + * @return false|string + */ + private function containsObject($value) + { + if ($this->objects->contains($value)) { + return spl_object_hash($value); + } + + return false; + } +} diff --git a/vendor/sebastian/recursion-context/src/Exception.php b/vendor/sebastian/recursion-context/src/Exception.php new file mode 100644 index 000000000..e3a9c017d --- /dev/null +++ b/vendor/sebastian/recursion-context/src/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of the Recursion Context package. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\RecursionContext; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/recursion-context/src/InvalidArgumentException.php b/vendor/sebastian/recursion-context/src/InvalidArgumentException.php new file mode 100644 index 000000000..627c8bdf4 --- /dev/null +++ b/vendor/sebastian/recursion-context/src/InvalidArgumentException.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); +/* + * This file is part of the Recursion Context package. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\RecursionContext; + +final class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ +} diff --git a/vendor/sebastian/resource-operations/.gitattributes b/vendor/sebastian/resource-operations/.gitattributes new file mode 100644 index 000000000..85e55ebca --- /dev/null +++ b/vendor/sebastian/resource-operations/.gitattributes @@ -0,0 +1,7 @@ +/.github export-ignore +/.php_cs.dist export-ignore +/build.xml export-ignore +/phpunit.xml export-ignore +/tests export-ignore + +*.php diff=php diff --git a/vendor/sebastian/resource-operations/.gitignore b/vendor/sebastian/resource-operations/.gitignore new file mode 100644 index 000000000..a086c7819 --- /dev/null +++ b/vendor/sebastian/resource-operations/.gitignore @@ -0,0 +1,6 @@ +/.idea +/.php_cs.cache +/build/FunctionSignatureMap.php +/composer.lock +/vendor +/.phpunit.result.cache diff --git a/vendor/sebastian/resource-operations/ChangeLog.md b/vendor/sebastian/resource-operations/ChangeLog.md new file mode 100644 index 000000000..e6dc73922 --- /dev/null +++ b/vendor/sebastian/resource-operations/ChangeLog.md @@ -0,0 +1,54 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. + +## [3.0.3] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [3.0.2] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [3.0.1] - 2020-06-15 + +### Changed + +* Tests etc. are now ignored for archive exports + +## [3.0.0] - 2020-02-07 + +### Removed + +* This component is no longer supported on PHP 7.1 and PHP 7.2 + +## [2.0.1] - 2018-10-04 + +### Fixed + +* Functions and methods with nullable parameters of type `resource` are now also considered + +## [2.0.0] - 2018-09-27 + +### Changed + +* [FunctionSignatureMap.php](https://raw.githubusercontent.com/phan/phan/master/src/Phan/Language/Internal/FunctionSignatureMap.php) from `phan/phan` is now used instead of [arginfo.php](https://raw.githubusercontent.com/rlerdorf/phan/master/includes/arginfo.php) from `rlerdorf/phan` + +### Removed + +* This component is no longer supported on PHP 5.6 and PHP 7.0 + +## 1.0.0 - 2015-07-28 + +* Initial release + +[3.0.3]: https://github.com/sebastianbergmann/comparator/resource-operations/3.0.2...3.0.3 +[3.0.2]: https://github.com/sebastianbergmann/comparator/resource-operations/3.0.1...3.0.2 +[3.0.1]: https://github.com/sebastianbergmann/comparator/resource-operations/3.0.0...3.0.1 +[3.0.0]: https://github.com/sebastianbergmann/comparator/resource-operations/2.0.1...3.0.0 +[2.0.1]: https://github.com/sebastianbergmann/comparator/resource-operations/2.0.0...2.0.1 +[2.0.0]: https://github.com/sebastianbergmann/comparator/resource-operations/1.0.0...2.0.0 diff --git a/vendor/sebastian/resource-operations/LICENSE b/vendor/sebastian/resource-operations/LICENSE new file mode 100644 index 000000000..dccd6b074 --- /dev/null +++ b/vendor/sebastian/resource-operations/LICENSE @@ -0,0 +1,33 @@ +Resource Operations + +Copyright (c) 2015-2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/resource-operations/README.md b/vendor/sebastian/resource-operations/README.md new file mode 100644 index 000000000..88b05ccb6 --- /dev/null +++ b/vendor/sebastian/resource-operations/README.md @@ -0,0 +1,14 @@ +# Resource Operations + +Provides a list of PHP built-in functions that operate on resources. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require sebastian/resource-operations + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + + composer require --dev sebastian/resource-operations + diff --git a/vendor/sebastian/resource-operations/build/generate.php b/vendor/sebastian/resource-operations/build/generate.php new file mode 100644 index 000000000..0354dc45f --- /dev/null +++ b/vendor/sebastian/resource-operations/build/generate.php @@ -0,0 +1,65 @@ +#!/usr/bin/env php +<?php declare(strict_types=1); +/* + * This file is part of resource-operations. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +$functions = require __DIR__ . '/FunctionSignatureMap.php'; +$resourceFunctions = []; + +foreach ($functions as $function => $arguments) { + foreach ($arguments as $argument) { + if (strpos($argument, '?') === 0) { + $argument = substr($argument, 1); + } + + if ($argument === 'resource') { + $resourceFunctions[] = explode('\'', $function)[0]; + } + } +} + +$resourceFunctions = array_unique($resourceFunctions); +sort($resourceFunctions); + +$buffer = <<<EOT +<?php declare(strict_types=1); +/* + * This file is part of resource-operations. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\ResourceOperations; + +final class ResourceOperations +{ + /** + * @return string[] + */ + public static function getFunctions(): array + { + return [ + +EOT; + +foreach ($resourceFunctions as $function) { + $buffer .= sprintf(" '%s',\n", $function); +} + +$buffer .= <<< EOT + ]; + } +} + +EOT; + +file_put_contents(__DIR__ . '/../src/ResourceOperations.php', $buffer); + diff --git a/vendor/sebastian/resource-operations/composer.json b/vendor/sebastian/resource-operations/composer.json new file mode 100644 index 000000000..870be3c12 --- /dev/null +++ b/vendor/sebastian/resource-operations/composer.json @@ -0,0 +1,37 @@ +{ + "name": "sebastian/resource-operations", + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]" + } + ], + "prefer-stable": true, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + } +} + diff --git a/vendor/sebastian/resource-operations/src/ResourceOperations.php b/vendor/sebastian/resource-operations/src/ResourceOperations.php new file mode 100644 index 000000000..f3911f36c --- /dev/null +++ b/vendor/sebastian/resource-operations/src/ResourceOperations.php @@ -0,0 +1,2232 @@ +<?php declare(strict_types=1); +/* + * This file is part of resource-operations. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\ResourceOperations; + +final class ResourceOperations +{ + /** + * @return string[] + */ + public static function getFunctions(): array + { + return [ + 'Directory::close', + 'Directory::read', + 'Directory::rewind', + 'DirectoryIterator::openFile', + 'FilesystemIterator::openFile', + 'Gmagick::readimagefile', + 'HttpResponse::getRequestBodyStream', + 'HttpResponse::getStream', + 'HttpResponse::setStream', + 'Imagick::pingImageFile', + 'Imagick::readImageFile', + 'Imagick::writeImageFile', + 'Imagick::writeImagesFile', + 'MongoGridFSCursor::__construct', + 'MongoGridFSFile::getResource', + 'MysqlndUhConnection::stmtInit', + 'MysqlndUhConnection::storeResult', + 'MysqlndUhConnection::useResult', + 'PDF_activate_item', + 'PDF_add_launchlink', + 'PDF_add_locallink', + 'PDF_add_nameddest', + 'PDF_add_note', + 'PDF_add_pdflink', + 'PDF_add_table_cell', + 'PDF_add_textflow', + 'PDF_add_thumbnail', + 'PDF_add_weblink', + 'PDF_arc', + 'PDF_arcn', + 'PDF_attach_file', + 'PDF_begin_document', + 'PDF_begin_font', + 'PDF_begin_glyph', + 'PDF_begin_item', + 'PDF_begin_layer', + 'PDF_begin_page', + 'PDF_begin_page_ext', + 'PDF_begin_pattern', + 'PDF_begin_template', + 'PDF_begin_template_ext', + 'PDF_circle', + 'PDF_clip', + 'PDF_close', + 'PDF_close_image', + 'PDF_close_pdi', + 'PDF_close_pdi_page', + 'PDF_closepath', + 'PDF_closepath_fill_stroke', + 'PDF_closepath_stroke', + 'PDF_concat', + 'PDF_continue_text', + 'PDF_create_3dview', + 'PDF_create_action', + 'PDF_create_annotation', + 'PDF_create_bookmark', + 'PDF_create_field', + 'PDF_create_fieldgroup', + 'PDF_create_gstate', + 'PDF_create_pvf', + 'PDF_create_textflow', + 'PDF_curveto', + 'PDF_define_layer', + 'PDF_delete', + 'PDF_delete_pvf', + 'PDF_delete_table', + 'PDF_delete_textflow', + 'PDF_encoding_set_char', + 'PDF_end_document', + 'PDF_end_font', + 'PDF_end_glyph', + 'PDF_end_item', + 'PDF_end_layer', + 'PDF_end_page', + 'PDF_end_page_ext', + 'PDF_end_pattern', + 'PDF_end_template', + 'PDF_endpath', + 'PDF_fill', + 'PDF_fill_imageblock', + 'PDF_fill_pdfblock', + 'PDF_fill_stroke', + 'PDF_fill_textblock', + 'PDF_findfont', + 'PDF_fit_image', + 'PDF_fit_pdi_page', + 'PDF_fit_table', + 'PDF_fit_textflow', + 'PDF_fit_textline', + 'PDF_get_apiname', + 'PDF_get_buffer', + 'PDF_get_errmsg', + 'PDF_get_errnum', + 'PDF_get_parameter', + 'PDF_get_pdi_parameter', + 'PDF_get_pdi_value', + 'PDF_get_value', + 'PDF_info_font', + 'PDF_info_matchbox', + 'PDF_info_table', + 'PDF_info_textflow', + 'PDF_info_textline', + 'PDF_initgraphics', + 'PDF_lineto', + 'PDF_load_3ddata', + 'PDF_load_font', + 'PDF_load_iccprofile', + 'PDF_load_image', + 'PDF_makespotcolor', + 'PDF_moveto', + 'PDF_new', + 'PDF_open_ccitt', + 'PDF_open_file', + 'PDF_open_image', + 'PDF_open_image_file', + 'PDF_open_memory_image', + 'PDF_open_pdi', + 'PDF_open_pdi_document', + 'PDF_open_pdi_page', + 'PDF_pcos_get_number', + 'PDF_pcos_get_stream', + 'PDF_pcos_get_string', + 'PDF_place_image', + 'PDF_place_pdi_page', + 'PDF_process_pdi', + 'PDF_rect', + 'PDF_restore', + 'PDF_resume_page', + 'PDF_rotate', + 'PDF_save', + 'PDF_scale', + 'PDF_set_border_color', + 'PDF_set_border_dash', + 'PDF_set_border_style', + 'PDF_set_gstate', + 'PDF_set_info', + 'PDF_set_layer_dependency', + 'PDF_set_parameter', + 'PDF_set_text_pos', + 'PDF_set_value', + 'PDF_setcolor', + 'PDF_setdash', + 'PDF_setdashpattern', + 'PDF_setflat', + 'PDF_setfont', + 'PDF_setgray', + 'PDF_setgray_fill', + 'PDF_setgray_stroke', + 'PDF_setlinecap', + 'PDF_setlinejoin', + 'PDF_setlinewidth', + 'PDF_setmatrix', + 'PDF_setmiterlimit', + 'PDF_setrgbcolor', + 'PDF_setrgbcolor_fill', + 'PDF_setrgbcolor_stroke', + 'PDF_shading', + 'PDF_shading_pattern', + 'PDF_shfill', + 'PDF_show', + 'PDF_show_boxed', + 'PDF_show_xy', + 'PDF_skew', + 'PDF_stringwidth', + 'PDF_stroke', + 'PDF_suspend_page', + 'PDF_translate', + 'PDF_utf16_to_utf8', + 'PDF_utf32_to_utf16', + 'PDF_utf8_to_utf16', + 'PDO::pgsqlLOBOpen', + 'RarEntry::getStream', + 'SQLite3::openBlob', + 'SWFMovie::saveToFile', + 'SplFileInfo::openFile', + 'SplFileObject::openFile', + 'SplTempFileObject::openFile', + 'V8Js::compileString', + 'V8Js::executeScript', + 'Vtiful\Kernel\Excel::setColumn', + 'Vtiful\Kernel\Excel::setRow', + 'Vtiful\Kernel\Format::align', + 'Vtiful\Kernel\Format::bold', + 'Vtiful\Kernel\Format::italic', + 'Vtiful\Kernel\Format::underline', + 'XMLWriter::openMemory', + 'XMLWriter::openURI', + 'ZipArchive::getStream', + 'Zookeeper::setLogStream', + 'apc_bin_dumpfile', + 'apc_bin_loadfile', + 'bbcode_add_element', + 'bbcode_add_smiley', + 'bbcode_create', + 'bbcode_destroy', + 'bbcode_parse', + 'bbcode_set_arg_parser', + 'bbcode_set_flags', + 'bcompiler_read', + 'bcompiler_write_class', + 'bcompiler_write_constant', + 'bcompiler_write_exe_footer', + 'bcompiler_write_file', + 'bcompiler_write_footer', + 'bcompiler_write_function', + 'bcompiler_write_functions_from_file', + 'bcompiler_write_header', + 'bcompiler_write_included_filename', + 'bzclose', + 'bzerrno', + 'bzerror', + 'bzerrstr', + 'bzflush', + 'bzopen', + 'bzread', + 'bzwrite', + 'cairo_surface_write_to_png', + 'closedir', + 'copy', + 'crack_closedict', + 'crack_opendict', + 'cubrid_bind', + 'cubrid_close_prepare', + 'cubrid_close_request', + 'cubrid_col_get', + 'cubrid_col_size', + 'cubrid_column_names', + 'cubrid_column_types', + 'cubrid_commit', + 'cubrid_connect', + 'cubrid_connect_with_url', + 'cubrid_current_oid', + 'cubrid_db_parameter', + 'cubrid_disconnect', + 'cubrid_drop', + 'cubrid_fetch', + 'cubrid_free_result', + 'cubrid_get', + 'cubrid_get_autocommit', + 'cubrid_get_charset', + 'cubrid_get_class_name', + 'cubrid_get_db_parameter', + 'cubrid_get_query_timeout', + 'cubrid_get_server_info', + 'cubrid_insert_id', + 'cubrid_is_instance', + 'cubrid_lob2_bind', + 'cubrid_lob2_close', + 'cubrid_lob2_export', + 'cubrid_lob2_import', + 'cubrid_lob2_new', + 'cubrid_lob2_read', + 'cubrid_lob2_seek', + 'cubrid_lob2_seek64', + 'cubrid_lob2_size', + 'cubrid_lob2_size64', + 'cubrid_lob2_tell', + 'cubrid_lob2_tell64', + 'cubrid_lob2_write', + 'cubrid_lob_export', + 'cubrid_lob_get', + 'cubrid_lob_send', + 'cubrid_lob_size', + 'cubrid_lock_read', + 'cubrid_lock_write', + 'cubrid_move_cursor', + 'cubrid_next_result', + 'cubrid_num_cols', + 'cubrid_num_rows', + 'cubrid_pconnect', + 'cubrid_pconnect_with_url', + 'cubrid_prepare', + 'cubrid_put', + 'cubrid_query', + 'cubrid_rollback', + 'cubrid_schema', + 'cubrid_seq_add', + 'cubrid_seq_drop', + 'cubrid_seq_insert', + 'cubrid_seq_put', + 'cubrid_set_add', + 'cubrid_set_autocommit', + 'cubrid_set_db_parameter', + 'cubrid_set_drop', + 'cubrid_set_query_timeout', + 'cubrid_unbuffered_query', + 'curl_close', + 'curl_copy_handle', + 'curl_errno', + 'curl_error', + 'curl_escape', + 'curl_exec', + 'curl_getinfo', + 'curl_multi_add_handle', + 'curl_multi_close', + 'curl_multi_errno', + 'curl_multi_exec', + 'curl_multi_getcontent', + 'curl_multi_info_read', + 'curl_multi_remove_handle', + 'curl_multi_select', + 'curl_multi_setopt', + 'curl_pause', + 'curl_reset', + 'curl_setopt', + 'curl_setopt_array', + 'curl_share_close', + 'curl_share_errno', + 'curl_share_init', + 'curl_share_setopt', + 'curl_unescape', + 'cyrus_authenticate', + 'cyrus_bind', + 'cyrus_close', + 'cyrus_connect', + 'cyrus_query', + 'cyrus_unbind', + 'db2_autocommit', + 'db2_bind_param', + 'db2_client_info', + 'db2_close', + 'db2_column_privileges', + 'db2_columns', + 'db2_commit', + 'db2_conn_error', + 'db2_conn_errormsg', + 'db2_connect', + 'db2_cursor_type', + 'db2_exec', + 'db2_execute', + 'db2_fetch_array', + 'db2_fetch_assoc', + 'db2_fetch_both', + 'db2_fetch_object', + 'db2_fetch_row', + 'db2_field_display_size', + 'db2_field_name', + 'db2_field_num', + 'db2_field_precision', + 'db2_field_scale', + 'db2_field_type', + 'db2_field_width', + 'db2_foreign_keys', + 'db2_free_result', + 'db2_free_stmt', + 'db2_get_option', + 'db2_last_insert_id', + 'db2_lob_read', + 'db2_next_result', + 'db2_num_fields', + 'db2_num_rows', + 'db2_pclose', + 'db2_pconnect', + 'db2_prepare', + 'db2_primary_keys', + 'db2_procedure_columns', + 'db2_procedures', + 'db2_result', + 'db2_rollback', + 'db2_server_info', + 'db2_set_option', + 'db2_special_columns', + 'db2_statistics', + 'db2_stmt_error', + 'db2_stmt_errormsg', + 'db2_table_privileges', + 'db2_tables', + 'dba_close', + 'dba_delete', + 'dba_exists', + 'dba_fetch', + 'dba_firstkey', + 'dba_insert', + 'dba_nextkey', + 'dba_open', + 'dba_optimize', + 'dba_popen', + 'dba_replace', + 'dba_sync', + 'dbplus_add', + 'dbplus_aql', + 'dbplus_close', + 'dbplus_curr', + 'dbplus_find', + 'dbplus_first', + 'dbplus_flush', + 'dbplus_freelock', + 'dbplus_freerlocks', + 'dbplus_getlock', + 'dbplus_getunique', + 'dbplus_info', + 'dbplus_last', + 'dbplus_lockrel', + 'dbplus_next', + 'dbplus_open', + 'dbplus_prev', + 'dbplus_rchperm', + 'dbplus_rcreate', + 'dbplus_rcrtexact', + 'dbplus_rcrtlike', + 'dbplus_restorepos', + 'dbplus_rkeys', + 'dbplus_ropen', + 'dbplus_rquery', + 'dbplus_rrename', + 'dbplus_rsecindex', + 'dbplus_runlink', + 'dbplus_rzap', + 'dbplus_savepos', + 'dbplus_setindex', + 'dbplus_setindexbynumber', + 'dbplus_sql', + 'dbplus_tremove', + 'dbplus_undo', + 'dbplus_undoprepare', + 'dbplus_unlockrel', + 'dbplus_unselect', + 'dbplus_update', + 'dbplus_xlockrel', + 'dbplus_xunlockrel', + 'deflate_add', + 'dio_close', + 'dio_fcntl', + 'dio_open', + 'dio_read', + 'dio_seek', + 'dio_stat', + 'dio_tcsetattr', + 'dio_truncate', + 'dio_write', + 'dir', + 'eio_busy', + 'eio_cancel', + 'eio_chmod', + 'eio_chown', + 'eio_close', + 'eio_custom', + 'eio_dup2', + 'eio_fallocate', + 'eio_fchmod', + 'eio_fchown', + 'eio_fdatasync', + 'eio_fstat', + 'eio_fstatvfs', + 'eio_fsync', + 'eio_ftruncate', + 'eio_futime', + 'eio_get_last_error', + 'eio_grp', + 'eio_grp_add', + 'eio_grp_cancel', + 'eio_grp_limit', + 'eio_link', + 'eio_lstat', + 'eio_mkdir', + 'eio_mknod', + 'eio_nop', + 'eio_open', + 'eio_read', + 'eio_readahead', + 'eio_readdir', + 'eio_readlink', + 'eio_realpath', + 'eio_rename', + 'eio_rmdir', + 'eio_seek', + 'eio_sendfile', + 'eio_stat', + 'eio_statvfs', + 'eio_symlink', + 'eio_sync', + 'eio_sync_file_range', + 'eio_syncfs', + 'eio_truncate', + 'eio_unlink', + 'eio_utime', + 'eio_write', + 'enchant_broker_describe', + 'enchant_broker_dict_exists', + 'enchant_broker_free', + 'enchant_broker_free_dict', + 'enchant_broker_get_dict_path', + 'enchant_broker_get_error', + 'enchant_broker_init', + 'enchant_broker_list_dicts', + 'enchant_broker_request_dict', + 'enchant_broker_request_pwl_dict', + 'enchant_broker_set_dict_path', + 'enchant_broker_set_ordering', + 'enchant_dict_add_to_personal', + 'enchant_dict_add_to_session', + 'enchant_dict_check', + 'enchant_dict_describe', + 'enchant_dict_get_error', + 'enchant_dict_is_in_session', + 'enchant_dict_quick_check', + 'enchant_dict_store_replacement', + 'enchant_dict_suggest', + 'event_add', + 'event_base_free', + 'event_base_loop', + 'event_base_loopbreak', + 'event_base_loopexit', + 'event_base_new', + 'event_base_priority_init', + 'event_base_reinit', + 'event_base_set', + 'event_buffer_base_set', + 'event_buffer_disable', + 'event_buffer_enable', + 'event_buffer_fd_set', + 'event_buffer_free', + 'event_buffer_new', + 'event_buffer_priority_set', + 'event_buffer_read', + 'event_buffer_set_callback', + 'event_buffer_timeout_set', + 'event_buffer_watermark_set', + 'event_buffer_write', + 'event_del', + 'event_free', + 'event_new', + 'event_priority_set', + 'event_set', + 'event_timer_add', + 'event_timer_del', + 'event_timer_pending', + 'event_timer_set', + 'expect_expectl', + 'expect_popen', + 'fam_cancel_monitor', + 'fam_close', + 'fam_monitor_collection', + 'fam_monitor_directory', + 'fam_monitor_file', + 'fam_next_event', + 'fam_open', + 'fam_pending', + 'fam_resume_monitor', + 'fam_suspend_monitor', + 'fann_cascadetrain_on_data', + 'fann_cascadetrain_on_file', + 'fann_clear_scaling_params', + 'fann_copy', + 'fann_create_from_file', + 'fann_create_shortcut_array', + 'fann_create_standard', + 'fann_create_standard_array', + 'fann_create_train', + 'fann_create_train_from_callback', + 'fann_descale_input', + 'fann_descale_output', + 'fann_descale_train', + 'fann_destroy', + 'fann_destroy_train', + 'fann_duplicate_train_data', + 'fann_get_MSE', + 'fann_get_activation_function', + 'fann_get_activation_steepness', + 'fann_get_bias_array', + 'fann_get_bit_fail', + 'fann_get_bit_fail_limit', + 'fann_get_cascade_activation_functions', + 'fann_get_cascade_activation_functions_count', + 'fann_get_cascade_activation_steepnesses', + 'fann_get_cascade_activation_steepnesses_count', + 'fann_get_cascade_candidate_change_fraction', + 'fann_get_cascade_candidate_limit', + 'fann_get_cascade_candidate_stagnation_epochs', + 'fann_get_cascade_max_cand_epochs', + 'fann_get_cascade_max_out_epochs', + 'fann_get_cascade_min_cand_epochs', + 'fann_get_cascade_min_out_epochs', + 'fann_get_cascade_num_candidate_groups', + 'fann_get_cascade_num_candidates', + 'fann_get_cascade_output_change_fraction', + 'fann_get_cascade_output_stagnation_epochs', + 'fann_get_cascade_weight_multiplier', + 'fann_get_connection_array', + 'fann_get_connection_rate', + 'fann_get_errno', + 'fann_get_errstr', + 'fann_get_layer_array', + 'fann_get_learning_momentum', + 'fann_get_learning_rate', + 'fann_get_network_type', + 'fann_get_num_input', + 'fann_get_num_layers', + 'fann_get_num_output', + 'fann_get_quickprop_decay', + 'fann_get_quickprop_mu', + 'fann_get_rprop_decrease_factor', + 'fann_get_rprop_delta_max', + 'fann_get_rprop_delta_min', + 'fann_get_rprop_delta_zero', + 'fann_get_rprop_increase_factor', + 'fann_get_sarprop_step_error_shift', + 'fann_get_sarprop_step_error_threshold_factor', + 'fann_get_sarprop_temperature', + 'fann_get_sarprop_weight_decay_shift', + 'fann_get_total_connections', + 'fann_get_total_neurons', + 'fann_get_train_error_function', + 'fann_get_train_stop_function', + 'fann_get_training_algorithm', + 'fann_init_weights', + 'fann_length_train_data', + 'fann_merge_train_data', + 'fann_num_input_train_data', + 'fann_num_output_train_data', + 'fann_randomize_weights', + 'fann_read_train_from_file', + 'fann_reset_errno', + 'fann_reset_errstr', + 'fann_run', + 'fann_save', + 'fann_save_train', + 'fann_scale_input', + 'fann_scale_input_train_data', + 'fann_scale_output', + 'fann_scale_output_train_data', + 'fann_scale_train', + 'fann_scale_train_data', + 'fann_set_activation_function', + 'fann_set_activation_function_hidden', + 'fann_set_activation_function_layer', + 'fann_set_activation_function_output', + 'fann_set_activation_steepness', + 'fann_set_activation_steepness_hidden', + 'fann_set_activation_steepness_layer', + 'fann_set_activation_steepness_output', + 'fann_set_bit_fail_limit', + 'fann_set_callback', + 'fann_set_cascade_activation_functions', + 'fann_set_cascade_activation_steepnesses', + 'fann_set_cascade_candidate_change_fraction', + 'fann_set_cascade_candidate_limit', + 'fann_set_cascade_candidate_stagnation_epochs', + 'fann_set_cascade_max_cand_epochs', + 'fann_set_cascade_max_out_epochs', + 'fann_set_cascade_min_cand_epochs', + 'fann_set_cascade_min_out_epochs', + 'fann_set_cascade_num_candidate_groups', + 'fann_set_cascade_output_change_fraction', + 'fann_set_cascade_output_stagnation_epochs', + 'fann_set_cascade_weight_multiplier', + 'fann_set_error_log', + 'fann_set_input_scaling_params', + 'fann_set_learning_momentum', + 'fann_set_learning_rate', + 'fann_set_output_scaling_params', + 'fann_set_quickprop_decay', + 'fann_set_quickprop_mu', + 'fann_set_rprop_decrease_factor', + 'fann_set_rprop_delta_max', + 'fann_set_rprop_delta_min', + 'fann_set_rprop_delta_zero', + 'fann_set_rprop_increase_factor', + 'fann_set_sarprop_step_error_shift', + 'fann_set_sarprop_step_error_threshold_factor', + 'fann_set_sarprop_temperature', + 'fann_set_sarprop_weight_decay_shift', + 'fann_set_scaling_params', + 'fann_set_train_error_function', + 'fann_set_train_stop_function', + 'fann_set_training_algorithm', + 'fann_set_weight', + 'fann_set_weight_array', + 'fann_shuffle_train_data', + 'fann_subset_train_data', + 'fann_test', + 'fann_test_data', + 'fann_train', + 'fann_train_epoch', + 'fann_train_on_data', + 'fann_train_on_file', + 'fbsql_affected_rows', + 'fbsql_autocommit', + 'fbsql_blob_size', + 'fbsql_change_user', + 'fbsql_clob_size', + 'fbsql_close', + 'fbsql_commit', + 'fbsql_connect', + 'fbsql_create_blob', + 'fbsql_create_clob', + 'fbsql_create_db', + 'fbsql_data_seek', + 'fbsql_database', + 'fbsql_database_password', + 'fbsql_db_query', + 'fbsql_db_status', + 'fbsql_drop_db', + 'fbsql_errno', + 'fbsql_error', + 'fbsql_fetch_array', + 'fbsql_fetch_assoc', + 'fbsql_fetch_field', + 'fbsql_fetch_lengths', + 'fbsql_fetch_object', + 'fbsql_fetch_row', + 'fbsql_field_flags', + 'fbsql_field_len', + 'fbsql_field_name', + 'fbsql_field_seek', + 'fbsql_field_table', + 'fbsql_field_type', + 'fbsql_free_result', + 'fbsql_get_autostart_info', + 'fbsql_hostname', + 'fbsql_insert_id', + 'fbsql_list_dbs', + 'fbsql_list_fields', + 'fbsql_list_tables', + 'fbsql_next_result', + 'fbsql_num_fields', + 'fbsql_num_rows', + 'fbsql_password', + 'fbsql_pconnect', + 'fbsql_query', + 'fbsql_read_blob', + 'fbsql_read_clob', + 'fbsql_result', + 'fbsql_rollback', + 'fbsql_rows_fetched', + 'fbsql_select_db', + 'fbsql_set_characterset', + 'fbsql_set_lob_mode', + 'fbsql_set_password', + 'fbsql_set_transaction', + 'fbsql_start_db', + 'fbsql_stop_db', + 'fbsql_table_name', + 'fbsql_username', + 'fclose', + 'fdf_add_doc_javascript', + 'fdf_add_template', + 'fdf_close', + 'fdf_create', + 'fdf_enum_values', + 'fdf_get_ap', + 'fdf_get_attachment', + 'fdf_get_encoding', + 'fdf_get_file', + 'fdf_get_flags', + 'fdf_get_opt', + 'fdf_get_status', + 'fdf_get_value', + 'fdf_get_version', + 'fdf_next_field_name', + 'fdf_open', + 'fdf_open_string', + 'fdf_remove_item', + 'fdf_save', + 'fdf_save_string', + 'fdf_set_ap', + 'fdf_set_encoding', + 'fdf_set_file', + 'fdf_set_flags', + 'fdf_set_javascript_action', + 'fdf_set_on_import_javascript', + 'fdf_set_opt', + 'fdf_set_status', + 'fdf_set_submit_form_action', + 'fdf_set_target_frame', + 'fdf_set_value', + 'fdf_set_version', + 'feof', + 'fflush', + 'ffmpeg_frame::__construct', + 'ffmpeg_frame::toGDImage', + 'fgetc', + 'fgetcsv', + 'fgets', + 'fgetss', + 'file', + 'file_get_contents', + 'file_put_contents', + 'finfo::buffer', + 'finfo::file', + 'finfo_buffer', + 'finfo_close', + 'finfo_file', + 'finfo_open', + 'finfo_set_flags', + 'flock', + 'fopen', + 'fpassthru', + 'fprintf', + 'fputcsv', + 'fputs', + 'fread', + 'fscanf', + 'fseek', + 'fstat', + 'ftell', + 'ftp_alloc', + 'ftp_append', + 'ftp_cdup', + 'ftp_chdir', + 'ftp_chmod', + 'ftp_close', + 'ftp_delete', + 'ftp_exec', + 'ftp_fget', + 'ftp_fput', + 'ftp_get', + 'ftp_get_option', + 'ftp_login', + 'ftp_mdtm', + 'ftp_mkdir', + 'ftp_mlsd', + 'ftp_nb_continue', + 'ftp_nb_fget', + 'ftp_nb_fput', + 'ftp_nb_get', + 'ftp_nb_put', + 'ftp_nlist', + 'ftp_pasv', + 'ftp_put', + 'ftp_pwd', + 'ftp_quit', + 'ftp_raw', + 'ftp_rawlist', + 'ftp_rename', + 'ftp_rmdir', + 'ftp_set_option', + 'ftp_site', + 'ftp_size', + 'ftp_systype', + 'ftruncate', + 'fwrite', + 'get_resource_type', + 'gmp_div', + 'gnupg::init', + 'gnupg_adddecryptkey', + 'gnupg_addencryptkey', + 'gnupg_addsignkey', + 'gnupg_cleardecryptkeys', + 'gnupg_clearencryptkeys', + 'gnupg_clearsignkeys', + 'gnupg_decrypt', + 'gnupg_decryptverify', + 'gnupg_encrypt', + 'gnupg_encryptsign', + 'gnupg_export', + 'gnupg_geterror', + 'gnupg_getprotocol', + 'gnupg_import', + 'gnupg_init', + 'gnupg_keyinfo', + 'gnupg_setarmor', + 'gnupg_seterrormode', + 'gnupg_setsignmode', + 'gnupg_sign', + 'gnupg_verify', + 'gupnp_context_get_host_ip', + 'gupnp_context_get_port', + 'gupnp_context_get_subscription_timeout', + 'gupnp_context_host_path', + 'gupnp_context_new', + 'gupnp_context_set_subscription_timeout', + 'gupnp_context_timeout_add', + 'gupnp_context_unhost_path', + 'gupnp_control_point_browse_start', + 'gupnp_control_point_browse_stop', + 'gupnp_control_point_callback_set', + 'gupnp_control_point_new', + 'gupnp_device_action_callback_set', + 'gupnp_device_info_get', + 'gupnp_device_info_get_service', + 'gupnp_root_device_get_available', + 'gupnp_root_device_get_relative_location', + 'gupnp_root_device_new', + 'gupnp_root_device_set_available', + 'gupnp_root_device_start', + 'gupnp_root_device_stop', + 'gupnp_service_action_get', + 'gupnp_service_action_return', + 'gupnp_service_action_return_error', + 'gupnp_service_action_set', + 'gupnp_service_freeze_notify', + 'gupnp_service_info_get', + 'gupnp_service_info_get_introspection', + 'gupnp_service_introspection_get_state_variable', + 'gupnp_service_notify', + 'gupnp_service_proxy_action_get', + 'gupnp_service_proxy_action_set', + 'gupnp_service_proxy_add_notify', + 'gupnp_service_proxy_callback_set', + 'gupnp_service_proxy_get_subscribed', + 'gupnp_service_proxy_remove_notify', + 'gupnp_service_proxy_send_action', + 'gupnp_service_proxy_set_subscribed', + 'gupnp_service_thaw_notify', + 'gzclose', + 'gzeof', + 'gzgetc', + 'gzgets', + 'gzgetss', + 'gzpassthru', + 'gzputs', + 'gzread', + 'gzrewind', + 'gzseek', + 'gztell', + 'gzwrite', + 'hash_update_stream', + 'http\Env\Response::send', + 'http_get_request_body_stream', + 'ibase_add_user', + 'ibase_affected_rows', + 'ibase_backup', + 'ibase_blob_add', + 'ibase_blob_cancel', + 'ibase_blob_close', + 'ibase_blob_create', + 'ibase_blob_get', + 'ibase_blob_open', + 'ibase_close', + 'ibase_commit', + 'ibase_commit_ret', + 'ibase_connect', + 'ibase_db_info', + 'ibase_delete_user', + 'ibase_drop_db', + 'ibase_execute', + 'ibase_fetch_assoc', + 'ibase_fetch_object', + 'ibase_fetch_row', + 'ibase_field_info', + 'ibase_free_event_handler', + 'ibase_free_query', + 'ibase_free_result', + 'ibase_gen_id', + 'ibase_maintain_db', + 'ibase_modify_user', + 'ibase_name_result', + 'ibase_num_fields', + 'ibase_num_params', + 'ibase_param_info', + 'ibase_pconnect', + 'ibase_prepare', + 'ibase_query', + 'ibase_restore', + 'ibase_rollback', + 'ibase_rollback_ret', + 'ibase_server_info', + 'ibase_service_attach', + 'ibase_service_detach', + 'ibase_set_event_handler', + 'ibase_trans', + 'ifx_affected_rows', + 'ifx_close', + 'ifx_connect', + 'ifx_do', + 'ifx_error', + 'ifx_fetch_row', + 'ifx_fieldproperties', + 'ifx_fieldtypes', + 'ifx_free_result', + 'ifx_getsqlca', + 'ifx_htmltbl_result', + 'ifx_num_fields', + 'ifx_num_rows', + 'ifx_pconnect', + 'ifx_prepare', + 'ifx_query', + 'image2wbmp', + 'imageaffine', + 'imagealphablending', + 'imageantialias', + 'imagearc', + 'imagebmp', + 'imagechar', + 'imagecharup', + 'imagecolorallocate', + 'imagecolorallocatealpha', + 'imagecolorat', + 'imagecolorclosest', + 'imagecolorclosestalpha', + 'imagecolorclosesthwb', + 'imagecolordeallocate', + 'imagecolorexact', + 'imagecolorexactalpha', + 'imagecolormatch', + 'imagecolorresolve', + 'imagecolorresolvealpha', + 'imagecolorset', + 'imagecolorsforindex', + 'imagecolorstotal', + 'imagecolortransparent', + 'imageconvolution', + 'imagecopy', + 'imagecopymerge', + 'imagecopymergegray', + 'imagecopyresampled', + 'imagecopyresized', + 'imagecrop', + 'imagecropauto', + 'imagedashedline', + 'imagedestroy', + 'imageellipse', + 'imagefill', + 'imagefilledarc', + 'imagefilledellipse', + 'imagefilledpolygon', + 'imagefilledrectangle', + 'imagefilltoborder', + 'imagefilter', + 'imageflip', + 'imagefttext', + 'imagegammacorrect', + 'imagegd', + 'imagegd2', + 'imagegetclip', + 'imagegif', + 'imagegrabscreen', + 'imagegrabwindow', + 'imageinterlace', + 'imageistruecolor', + 'imagejpeg', + 'imagelayereffect', + 'imageline', + 'imageopenpolygon', + 'imagepalettecopy', + 'imagepalettetotruecolor', + 'imagepng', + 'imagepolygon', + 'imagepsencodefont', + 'imagepsextendfont', + 'imagepsfreefont', + 'imagepsloadfont', + 'imagepsslantfont', + 'imagepstext', + 'imagerectangle', + 'imageresolution', + 'imagerotate', + 'imagesavealpha', + 'imagescale', + 'imagesetbrush', + 'imagesetclip', + 'imagesetinterpolation', + 'imagesetpixel', + 'imagesetstyle', + 'imagesetthickness', + 'imagesettile', + 'imagestring', + 'imagestringup', + 'imagesx', + 'imagesy', + 'imagetruecolortopalette', + 'imagettftext', + 'imagewbmp', + 'imagewebp', + 'imagexbm', + 'imap_append', + 'imap_body', + 'imap_bodystruct', + 'imap_check', + 'imap_clearflag_full', + 'imap_close', + 'imap_create', + 'imap_createmailbox', + 'imap_delete', + 'imap_deletemailbox', + 'imap_expunge', + 'imap_fetch_overview', + 'imap_fetchbody', + 'imap_fetchheader', + 'imap_fetchmime', + 'imap_fetchstructure', + 'imap_fetchtext', + 'imap_gc', + 'imap_get_quota', + 'imap_get_quotaroot', + 'imap_getacl', + 'imap_getmailboxes', + 'imap_getsubscribed', + 'imap_header', + 'imap_headerinfo', + 'imap_headers', + 'imap_list', + 'imap_listmailbox', + 'imap_listscan', + 'imap_listsubscribed', + 'imap_lsub', + 'imap_mail_copy', + 'imap_mail_move', + 'imap_mailboxmsginfo', + 'imap_msgno', + 'imap_num_msg', + 'imap_num_recent', + 'imap_ping', + 'imap_rename', + 'imap_renamemailbox', + 'imap_reopen', + 'imap_savebody', + 'imap_scan', + 'imap_scanmailbox', + 'imap_search', + 'imap_set_quota', + 'imap_setacl', + 'imap_setflag_full', + 'imap_sort', + 'imap_status', + 'imap_subscribe', + 'imap_thread', + 'imap_uid', + 'imap_undelete', + 'imap_unsubscribe', + 'inflate_add', + 'inflate_get_read_len', + 'inflate_get_status', + 'ingres_autocommit', + 'ingres_autocommit_state', + 'ingres_charset', + 'ingres_close', + 'ingres_commit', + 'ingres_connect', + 'ingres_cursor', + 'ingres_errno', + 'ingres_error', + 'ingres_errsqlstate', + 'ingres_escape_string', + 'ingres_execute', + 'ingres_fetch_array', + 'ingres_fetch_assoc', + 'ingres_fetch_object', + 'ingres_fetch_proc_return', + 'ingres_fetch_row', + 'ingres_field_length', + 'ingres_field_name', + 'ingres_field_nullable', + 'ingres_field_precision', + 'ingres_field_scale', + 'ingres_field_type', + 'ingres_free_result', + 'ingres_next_error', + 'ingres_num_fields', + 'ingres_num_rows', + 'ingres_pconnect', + 'ingres_prepare', + 'ingres_query', + 'ingres_result_seek', + 'ingres_rollback', + 'ingres_set_environment', + 'ingres_unbuffered_query', + 'inotify_add_watch', + 'inotify_init', + 'inotify_queue_len', + 'inotify_read', + 'inotify_rm_watch', + 'kadm5_chpass_principal', + 'kadm5_create_principal', + 'kadm5_delete_principal', + 'kadm5_destroy', + 'kadm5_flush', + 'kadm5_get_policies', + 'kadm5_get_principal', + 'kadm5_get_principals', + 'kadm5_init_with_password', + 'kadm5_modify_principal', + 'ldap_add', + 'ldap_bind', + 'ldap_close', + 'ldap_compare', + 'ldap_control_paged_result', + 'ldap_control_paged_result_response', + 'ldap_count_entries', + 'ldap_delete', + 'ldap_errno', + 'ldap_error', + 'ldap_exop', + 'ldap_exop_passwd', + 'ldap_exop_refresh', + 'ldap_exop_whoami', + 'ldap_first_attribute', + 'ldap_first_entry', + 'ldap_first_reference', + 'ldap_free_result', + 'ldap_get_attributes', + 'ldap_get_dn', + 'ldap_get_entries', + 'ldap_get_option', + 'ldap_get_values', + 'ldap_get_values_len', + 'ldap_mod_add', + 'ldap_mod_del', + 'ldap_mod_replace', + 'ldap_modify', + 'ldap_modify_batch', + 'ldap_next_attribute', + 'ldap_next_entry', + 'ldap_next_reference', + 'ldap_parse_exop', + 'ldap_parse_reference', + 'ldap_parse_result', + 'ldap_rename', + 'ldap_sasl_bind', + 'ldap_set_option', + 'ldap_set_rebind_proc', + 'ldap_sort', + 'ldap_start_tls', + 'ldap_unbind', + 'libxml_set_streams_context', + 'm_checkstatus', + 'm_completeauthorizations', + 'm_connect', + 'm_connectionerror', + 'm_deletetrans', + 'm_destroyconn', + 'm_getcell', + 'm_getcellbynum', + 'm_getcommadelimited', + 'm_getheader', + 'm_initconn', + 'm_iscommadelimited', + 'm_maxconntimeout', + 'm_monitor', + 'm_numcolumns', + 'm_numrows', + 'm_parsecommadelimited', + 'm_responsekeys', + 'm_responseparam', + 'm_returnstatus', + 'm_setblocking', + 'm_setdropfile', + 'm_setip', + 'm_setssl', + 'm_setssl_cafile', + 'm_setssl_files', + 'm_settimeout', + 'm_transactionssent', + 'm_transinqueue', + 'm_transkeyval', + 'm_transnew', + 'm_transsend', + 'm_validateidentifier', + 'm_verifyconnection', + 'm_verifysslcert', + 'mailparse_determine_best_xfer_encoding', + 'mailparse_msg_create', + 'mailparse_msg_extract_part', + 'mailparse_msg_extract_part_file', + 'mailparse_msg_extract_whole_part_file', + 'mailparse_msg_free', + 'mailparse_msg_get_part', + 'mailparse_msg_get_part_data', + 'mailparse_msg_get_structure', + 'mailparse_msg_parse', + 'mailparse_msg_parse_file', + 'mailparse_stream_encode', + 'mailparse_uudecode_all', + 'maxdb::use_result', + 'maxdb_affected_rows', + 'maxdb_connect', + 'maxdb_disable_rpl_parse', + 'maxdb_dump_debug_info', + 'maxdb_embedded_connect', + 'maxdb_enable_reads_from_master', + 'maxdb_enable_rpl_parse', + 'maxdb_errno', + 'maxdb_error', + 'maxdb_fetch_lengths', + 'maxdb_field_tell', + 'maxdb_get_host_info', + 'maxdb_get_proto_info', + 'maxdb_get_server_info', + 'maxdb_get_server_version', + 'maxdb_info', + 'maxdb_init', + 'maxdb_insert_id', + 'maxdb_master_query', + 'maxdb_more_results', + 'maxdb_next_result', + 'maxdb_num_fields', + 'maxdb_num_rows', + 'maxdb_rpl_parse_enabled', + 'maxdb_rpl_probe', + 'maxdb_select_db', + 'maxdb_sqlstate', + 'maxdb_stmt::result_metadata', + 'maxdb_stmt_affected_rows', + 'maxdb_stmt_errno', + 'maxdb_stmt_error', + 'maxdb_stmt_num_rows', + 'maxdb_stmt_param_count', + 'maxdb_stmt_result_metadata', + 'maxdb_stmt_sqlstate', + 'maxdb_thread_id', + 'maxdb_use_result', + 'maxdb_warning_count', + 'mcrypt_enc_get_algorithms_name', + 'mcrypt_enc_get_block_size', + 'mcrypt_enc_get_iv_size', + 'mcrypt_enc_get_key_size', + 'mcrypt_enc_get_modes_name', + 'mcrypt_enc_get_supported_key_sizes', + 'mcrypt_enc_is_block_algorithm', + 'mcrypt_enc_is_block_algorithm_mode', + 'mcrypt_enc_is_block_mode', + 'mcrypt_enc_self_test', + 'mcrypt_generic', + 'mcrypt_generic_deinit', + 'mcrypt_generic_end', + 'mcrypt_generic_init', + 'mcrypt_module_close', + 'mcrypt_module_open', + 'mdecrypt_generic', + 'mkdir', + 'mqseries_back', + 'mqseries_begin', + 'mqseries_close', + 'mqseries_cmit', + 'mqseries_conn', + 'mqseries_connx', + 'mqseries_disc', + 'mqseries_get', + 'mqseries_inq', + 'mqseries_open', + 'mqseries_put', + 'mqseries_put1', + 'mqseries_set', + 'msg_get_queue', + 'msg_receive', + 'msg_remove_queue', + 'msg_send', + 'msg_set_queue', + 'msg_stat_queue', + 'msql_affected_rows', + 'msql_close', + 'msql_connect', + 'msql_create_db', + 'msql_data_seek', + 'msql_db_query', + 'msql_drop_db', + 'msql_fetch_array', + 'msql_fetch_field', + 'msql_fetch_object', + 'msql_fetch_row', + 'msql_field_flags', + 'msql_field_len', + 'msql_field_name', + 'msql_field_seek', + 'msql_field_table', + 'msql_field_type', + 'msql_free_result', + 'msql_list_dbs', + 'msql_list_fields', + 'msql_list_tables', + 'msql_num_fields', + 'msql_num_rows', + 'msql_pconnect', + 'msql_query', + 'msql_result', + 'msql_select_db', + 'mssql_bind', + 'mssql_close', + 'mssql_connect', + 'mssql_data_seek', + 'mssql_execute', + 'mssql_fetch_array', + 'mssql_fetch_assoc', + 'mssql_fetch_batch', + 'mssql_fetch_field', + 'mssql_fetch_object', + 'mssql_fetch_row', + 'mssql_field_length', + 'mssql_field_name', + 'mssql_field_seek', + 'mssql_field_type', + 'mssql_free_result', + 'mssql_free_statement', + 'mssql_init', + 'mssql_next_result', + 'mssql_num_fields', + 'mssql_num_rows', + 'mssql_pconnect', + 'mssql_query', + 'mssql_result', + 'mssql_rows_affected', + 'mssql_select_db', + 'mysql_affected_rows', + 'mysql_client_encoding', + 'mysql_close', + 'mysql_connect', + 'mysql_create_db', + 'mysql_data_seek', + 'mysql_db_name', + 'mysql_db_query', + 'mysql_drop_db', + 'mysql_errno', + 'mysql_error', + 'mysql_fetch_array', + 'mysql_fetch_assoc', + 'mysql_fetch_field', + 'mysql_fetch_lengths', + 'mysql_fetch_object', + 'mysql_fetch_row', + 'mysql_field_flags', + 'mysql_field_len', + 'mysql_field_name', + 'mysql_field_seek', + 'mysql_field_table', + 'mysql_field_type', + 'mysql_free_result', + 'mysql_get_host_info', + 'mysql_get_proto_info', + 'mysql_get_server_info', + 'mysql_info', + 'mysql_insert_id', + 'mysql_list_dbs', + 'mysql_list_fields', + 'mysql_list_processes', + 'mysql_list_tables', + 'mysql_num_fields', + 'mysql_num_rows', + 'mysql_pconnect', + 'mysql_ping', + 'mysql_query', + 'mysql_real_escape_string', + 'mysql_result', + 'mysql_select_db', + 'mysql_set_charset', + 'mysql_stat', + 'mysql_tablename', + 'mysql_thread_id', + 'mysql_unbuffered_query', + 'mysqlnd_uh_convert_to_mysqlnd', + 'ncurses_bottom_panel', + 'ncurses_del_panel', + 'ncurses_delwin', + 'ncurses_getmaxyx', + 'ncurses_getyx', + 'ncurses_hide_panel', + 'ncurses_keypad', + 'ncurses_meta', + 'ncurses_move_panel', + 'ncurses_mvwaddstr', + 'ncurses_new_panel', + 'ncurses_newpad', + 'ncurses_newwin', + 'ncurses_panel_above', + 'ncurses_panel_below', + 'ncurses_panel_window', + 'ncurses_pnoutrefresh', + 'ncurses_prefresh', + 'ncurses_replace_panel', + 'ncurses_show_panel', + 'ncurses_top_panel', + 'ncurses_waddch', + 'ncurses_waddstr', + 'ncurses_wattroff', + 'ncurses_wattron', + 'ncurses_wattrset', + 'ncurses_wborder', + 'ncurses_wclear', + 'ncurses_wcolor_set', + 'ncurses_werase', + 'ncurses_wgetch', + 'ncurses_whline', + 'ncurses_wmouse_trafo', + 'ncurses_wmove', + 'ncurses_wnoutrefresh', + 'ncurses_wrefresh', + 'ncurses_wstandend', + 'ncurses_wstandout', + 'ncurses_wvline', + 'newt_button', + 'newt_button_bar', + 'newt_checkbox', + 'newt_checkbox_get_value', + 'newt_checkbox_set_flags', + 'newt_checkbox_set_value', + 'newt_checkbox_tree', + 'newt_checkbox_tree_add_item', + 'newt_checkbox_tree_find_item', + 'newt_checkbox_tree_get_current', + 'newt_checkbox_tree_get_entry_value', + 'newt_checkbox_tree_get_multi_selection', + 'newt_checkbox_tree_get_selection', + 'newt_checkbox_tree_multi', + 'newt_checkbox_tree_set_current', + 'newt_checkbox_tree_set_entry', + 'newt_checkbox_tree_set_entry_value', + 'newt_checkbox_tree_set_width', + 'newt_compact_button', + 'newt_component_add_callback', + 'newt_component_takes_focus', + 'newt_create_grid', + 'newt_draw_form', + 'newt_entry', + 'newt_entry_get_value', + 'newt_entry_set', + 'newt_entry_set_filter', + 'newt_entry_set_flags', + 'newt_form', + 'newt_form_add_component', + 'newt_form_add_components', + 'newt_form_add_hot_key', + 'newt_form_destroy', + 'newt_form_get_current', + 'newt_form_run', + 'newt_form_set_background', + 'newt_form_set_height', + 'newt_form_set_size', + 'newt_form_set_timer', + 'newt_form_set_width', + 'newt_form_watch_fd', + 'newt_grid_add_components_to_form', + 'newt_grid_basic_window', + 'newt_grid_free', + 'newt_grid_get_size', + 'newt_grid_h_close_stacked', + 'newt_grid_h_stacked', + 'newt_grid_place', + 'newt_grid_set_field', + 'newt_grid_simple_window', + 'newt_grid_v_close_stacked', + 'newt_grid_v_stacked', + 'newt_grid_wrapped_window', + 'newt_grid_wrapped_window_at', + 'newt_label', + 'newt_label_set_text', + 'newt_listbox', + 'newt_listbox_append_entry', + 'newt_listbox_clear', + 'newt_listbox_clear_selection', + 'newt_listbox_delete_entry', + 'newt_listbox_get_current', + 'newt_listbox_get_selection', + 'newt_listbox_insert_entry', + 'newt_listbox_item_count', + 'newt_listbox_select_item', + 'newt_listbox_set_current', + 'newt_listbox_set_current_by_key', + 'newt_listbox_set_data', + 'newt_listbox_set_entry', + 'newt_listbox_set_width', + 'newt_listitem', + 'newt_listitem_get_data', + 'newt_listitem_set', + 'newt_radio_get_current', + 'newt_radiobutton', + 'newt_run_form', + 'newt_scale', + 'newt_scale_set', + 'newt_scrollbar_set', + 'newt_textbox', + 'newt_textbox_get_num_lines', + 'newt_textbox_reflowed', + 'newt_textbox_set_height', + 'newt_textbox_set_text', + 'newt_vertical_scrollbar', + 'oci_bind_array_by_name', + 'oci_bind_by_name', + 'oci_cancel', + 'oci_close', + 'oci_commit', + 'oci_connect', + 'oci_define_by_name', + 'oci_error', + 'oci_execute', + 'oci_fetch', + 'oci_fetch_all', + 'oci_fetch_array', + 'oci_fetch_assoc', + 'oci_fetch_object', + 'oci_fetch_row', + 'oci_field_is_null', + 'oci_field_name', + 'oci_field_precision', + 'oci_field_scale', + 'oci_field_size', + 'oci_field_type', + 'oci_field_type_raw', + 'oci_free_cursor', + 'oci_free_statement', + 'oci_get_implicit_resultset', + 'oci_new_collection', + 'oci_new_connect', + 'oci_new_cursor', + 'oci_new_descriptor', + 'oci_num_fields', + 'oci_num_rows', + 'oci_parse', + 'oci_pconnect', + 'oci_register_taf_callback', + 'oci_result', + 'oci_rollback', + 'oci_server_version', + 'oci_set_action', + 'oci_set_client_identifier', + 'oci_set_client_info', + 'oci_set_module_name', + 'oci_set_prefetch', + 'oci_statement_type', + 'oci_unregister_taf_callback', + 'odbc_autocommit', + 'odbc_close', + 'odbc_columnprivileges', + 'odbc_columns', + 'odbc_commit', + 'odbc_connect', + 'odbc_cursor', + 'odbc_data_source', + 'odbc_do', + 'odbc_error', + 'odbc_errormsg', + 'odbc_exec', + 'odbc_execute', + 'odbc_fetch_array', + 'odbc_fetch_into', + 'odbc_fetch_row', + 'odbc_field_len', + 'odbc_field_name', + 'odbc_field_num', + 'odbc_field_precision', + 'odbc_field_scale', + 'odbc_field_type', + 'odbc_foreignkeys', + 'odbc_free_result', + 'odbc_gettypeinfo', + 'odbc_next_result', + 'odbc_num_fields', + 'odbc_num_rows', + 'odbc_pconnect', + 'odbc_prepare', + 'odbc_primarykeys', + 'odbc_procedurecolumns', + 'odbc_procedures', + 'odbc_result', + 'odbc_result_all', + 'odbc_rollback', + 'odbc_setoption', + 'odbc_specialcolumns', + 'odbc_statistics', + 'odbc_tableprivileges', + 'odbc_tables', + 'openal_buffer_create', + 'openal_buffer_data', + 'openal_buffer_destroy', + 'openal_buffer_get', + 'openal_buffer_loadwav', + 'openal_context_create', + 'openal_context_current', + 'openal_context_destroy', + 'openal_context_process', + 'openal_context_suspend', + 'openal_device_close', + 'openal_device_open', + 'openal_source_create', + 'openal_source_destroy', + 'openal_source_get', + 'openal_source_pause', + 'openal_source_play', + 'openal_source_rewind', + 'openal_source_set', + 'openal_source_stop', + 'openal_stream', + 'opendir', + 'openssl_csr_new', + 'openssl_dh_compute_key', + 'openssl_free_key', + 'openssl_pkey_export', + 'openssl_pkey_free', + 'openssl_pkey_get_details', + 'openssl_spki_new', + 'openssl_x509_free', + 'pclose', + 'pfsockopen', + 'pg_affected_rows', + 'pg_cancel_query', + 'pg_client_encoding', + 'pg_close', + 'pg_connect_poll', + 'pg_connection_busy', + 'pg_connection_reset', + 'pg_connection_status', + 'pg_consume_input', + 'pg_convert', + 'pg_copy_from', + 'pg_copy_to', + 'pg_dbname', + 'pg_delete', + 'pg_end_copy', + 'pg_escape_bytea', + 'pg_escape_identifier', + 'pg_escape_literal', + 'pg_escape_string', + 'pg_execute', + 'pg_fetch_all', + 'pg_fetch_all_columns', + 'pg_fetch_array', + 'pg_fetch_assoc', + 'pg_fetch_row', + 'pg_field_name', + 'pg_field_num', + 'pg_field_size', + 'pg_field_table', + 'pg_field_type', + 'pg_field_type_oid', + 'pg_flush', + 'pg_free_result', + 'pg_get_notify', + 'pg_get_pid', + 'pg_get_result', + 'pg_host', + 'pg_insert', + 'pg_last_error', + 'pg_last_notice', + 'pg_last_oid', + 'pg_lo_close', + 'pg_lo_create', + 'pg_lo_export', + 'pg_lo_import', + 'pg_lo_open', + 'pg_lo_read', + 'pg_lo_read_all', + 'pg_lo_seek', + 'pg_lo_tell', + 'pg_lo_truncate', + 'pg_lo_unlink', + 'pg_lo_write', + 'pg_meta_data', + 'pg_num_fields', + 'pg_num_rows', + 'pg_options', + 'pg_parameter_status', + 'pg_ping', + 'pg_port', + 'pg_prepare', + 'pg_put_line', + 'pg_query', + 'pg_query_params', + 'pg_result_error', + 'pg_result_error_field', + 'pg_result_seek', + 'pg_result_status', + 'pg_select', + 'pg_send_execute', + 'pg_send_prepare', + 'pg_send_query', + 'pg_send_query_params', + 'pg_set_client_encoding', + 'pg_set_error_verbosity', + 'pg_socket', + 'pg_trace', + 'pg_transaction_status', + 'pg_tty', + 'pg_untrace', + 'pg_update', + 'pg_version', + 'php_user_filter::filter', + 'proc_close', + 'proc_get_status', + 'proc_terminate', + 'ps_add_bookmark', + 'ps_add_launchlink', + 'ps_add_locallink', + 'ps_add_note', + 'ps_add_pdflink', + 'ps_add_weblink', + 'ps_arc', + 'ps_arcn', + 'ps_begin_page', + 'ps_begin_pattern', + 'ps_begin_template', + 'ps_circle', + 'ps_clip', + 'ps_close', + 'ps_close_image', + 'ps_closepath', + 'ps_closepath_stroke', + 'ps_continue_text', + 'ps_curveto', + 'ps_delete', + 'ps_end_page', + 'ps_end_pattern', + 'ps_end_template', + 'ps_fill', + 'ps_fill_stroke', + 'ps_findfont', + 'ps_get_buffer', + 'ps_get_parameter', + 'ps_get_value', + 'ps_hyphenate', + 'ps_include_file', + 'ps_lineto', + 'ps_makespotcolor', + 'ps_moveto', + 'ps_new', + 'ps_open_file', + 'ps_open_image', + 'ps_open_image_file', + 'ps_open_memory_image', + 'ps_place_image', + 'ps_rect', + 'ps_restore', + 'ps_rotate', + 'ps_save', + 'ps_scale', + 'ps_set_border_color', + 'ps_set_border_dash', + 'ps_set_border_style', + 'ps_set_info', + 'ps_set_parameter', + 'ps_set_text_pos', + 'ps_set_value', + 'ps_setcolor', + 'ps_setdash', + 'ps_setflat', + 'ps_setfont', + 'ps_setgray', + 'ps_setlinecap', + 'ps_setlinejoin', + 'ps_setlinewidth', + 'ps_setmiterlimit', + 'ps_setoverprintmode', + 'ps_setpolydash', + 'ps_shading', + 'ps_shading_pattern', + 'ps_shfill', + 'ps_show', + 'ps_show2', + 'ps_show_boxed', + 'ps_show_xy', + 'ps_show_xy2', + 'ps_string_geometry', + 'ps_stringwidth', + 'ps_stroke', + 'ps_symbol', + 'ps_symbol_name', + 'ps_symbol_width', + 'ps_translate', + 'px_close', + 'px_create_fp', + 'px_date2string', + 'px_delete', + 'px_delete_record', + 'px_get_field', + 'px_get_info', + 'px_get_parameter', + 'px_get_record', + 'px_get_schema', + 'px_get_value', + 'px_insert_record', + 'px_new', + 'px_numfields', + 'px_numrecords', + 'px_open_fp', + 'px_put_record', + 'px_retrieve_record', + 'px_set_blob_file', + 'px_set_parameter', + 'px_set_tablename', + 'px_set_targetencoding', + 'px_set_value', + 'px_timestamp2string', + 'px_update_record', + 'radius_acct_open', + 'radius_add_server', + 'radius_auth_open', + 'radius_close', + 'radius_config', + 'radius_create_request', + 'radius_demangle', + 'radius_demangle_mppe_key', + 'radius_get_attr', + 'radius_put_addr', + 'radius_put_attr', + 'radius_put_int', + 'radius_put_string', + 'radius_put_vendor_addr', + 'radius_put_vendor_attr', + 'radius_put_vendor_int', + 'radius_put_vendor_string', + 'radius_request_authenticator', + 'radius_salt_encrypt_attr', + 'radius_send_request', + 'radius_server_secret', + 'radius_strerror', + 'readdir', + 'readfile', + 'recode_file', + 'rename', + 'rewind', + 'rewinddir', + 'rmdir', + 'rpm_close', + 'rpm_get_tag', + 'rpm_open', + 'sapi_windows_vt100_support', + 'scandir', + 'sem_acquire', + 'sem_get', + 'sem_release', + 'sem_remove', + 'set_file_buffer', + 'shm_attach', + 'shm_detach', + 'shm_get_var', + 'shm_has_var', + 'shm_put_var', + 'shm_remove', + 'shm_remove_var', + 'shmop_close', + 'shmop_delete', + 'shmop_open', + 'shmop_read', + 'shmop_size', + 'shmop_write', + 'socket_accept', + 'socket_addrinfo_bind', + 'socket_addrinfo_connect', + 'socket_addrinfo_explain', + 'socket_bind', + 'socket_clear_error', + 'socket_close', + 'socket_connect', + 'socket_export_stream', + 'socket_get_option', + 'socket_get_status', + 'socket_getopt', + 'socket_getpeername', + 'socket_getsockname', + 'socket_import_stream', + 'socket_last_error', + 'socket_listen', + 'socket_read', + 'socket_recv', + 'socket_recvfrom', + 'socket_recvmsg', + 'socket_send', + 'socket_sendmsg', + 'socket_sendto', + 'socket_set_block', + 'socket_set_blocking', + 'socket_set_nonblock', + 'socket_set_option', + 'socket_set_timeout', + 'socket_shutdown', + 'socket_write', + 'sqlite_close', + 'sqlite_fetch_string', + 'sqlite_has_more', + 'sqlite_open', + 'sqlite_popen', + 'sqlsrv_begin_transaction', + 'sqlsrv_cancel', + 'sqlsrv_client_info', + 'sqlsrv_close', + 'sqlsrv_commit', + 'sqlsrv_connect', + 'sqlsrv_execute', + 'sqlsrv_fetch', + 'sqlsrv_fetch_array', + 'sqlsrv_fetch_object', + 'sqlsrv_field_metadata', + 'sqlsrv_free_stmt', + 'sqlsrv_get_field', + 'sqlsrv_has_rows', + 'sqlsrv_next_result', + 'sqlsrv_num_fields', + 'sqlsrv_num_rows', + 'sqlsrv_prepare', + 'sqlsrv_query', + 'sqlsrv_rollback', + 'sqlsrv_rows_affected', + 'sqlsrv_send_stream_data', + 'sqlsrv_server_info', + 'ssh2_auth_agent', + 'ssh2_auth_hostbased_file', + 'ssh2_auth_none', + 'ssh2_auth_password', + 'ssh2_auth_pubkey_file', + 'ssh2_disconnect', + 'ssh2_exec', + 'ssh2_fetch_stream', + 'ssh2_fingerprint', + 'ssh2_methods_negotiated', + 'ssh2_publickey_add', + 'ssh2_publickey_init', + 'ssh2_publickey_list', + 'ssh2_publickey_remove', + 'ssh2_scp_recv', + 'ssh2_scp_send', + 'ssh2_sftp', + 'ssh2_sftp_chmod', + 'ssh2_sftp_lstat', + 'ssh2_sftp_mkdir', + 'ssh2_sftp_readlink', + 'ssh2_sftp_realpath', + 'ssh2_sftp_rename', + 'ssh2_sftp_rmdir', + 'ssh2_sftp_stat', + 'ssh2_sftp_symlink', + 'ssh2_sftp_unlink', + 'ssh2_shell', + 'ssh2_tunnel', + 'stomp_connect', + 'streamWrapper::stream_cast', + 'stream_bucket_append', + 'stream_bucket_make_writeable', + 'stream_bucket_new', + 'stream_bucket_prepend', + 'stream_context_create', + 'stream_context_get_default', + 'stream_context_get_options', + 'stream_context_get_params', + 'stream_context_set_default', + 'stream_context_set_params', + 'stream_copy_to_stream', + 'stream_encoding', + 'stream_filter_append', + 'stream_filter_prepend', + 'stream_filter_remove', + 'stream_get_contents', + 'stream_get_line', + 'stream_get_meta_data', + 'stream_isatty', + 'stream_set_blocking', + 'stream_set_chunk_size', + 'stream_set_read_buffer', + 'stream_set_timeout', + 'stream_set_write_buffer', + 'stream_socket_accept', + 'stream_socket_client', + 'stream_socket_enable_crypto', + 'stream_socket_get_name', + 'stream_socket_recvfrom', + 'stream_socket_sendto', + 'stream_socket_server', + 'stream_socket_shutdown', + 'stream_supports_lock', + 'svn_fs_abort_txn', + 'svn_fs_apply_text', + 'svn_fs_begin_txn2', + 'svn_fs_change_node_prop', + 'svn_fs_check_path', + 'svn_fs_contents_changed', + 'svn_fs_copy', + 'svn_fs_delete', + 'svn_fs_dir_entries', + 'svn_fs_file_contents', + 'svn_fs_file_length', + 'svn_fs_is_dir', + 'svn_fs_is_file', + 'svn_fs_make_dir', + 'svn_fs_make_file', + 'svn_fs_node_created_rev', + 'svn_fs_node_prop', + 'svn_fs_props_changed', + 'svn_fs_revision_prop', + 'svn_fs_revision_root', + 'svn_fs_txn_root', + 'svn_fs_youngest_rev', + 'svn_repos_create', + 'svn_repos_fs', + 'svn_repos_fs_begin_txn_for_commit', + 'svn_repos_fs_commit_txn', + 'svn_repos_open', + 'sybase_affected_rows', + 'sybase_close', + 'sybase_connect', + 'sybase_data_seek', + 'sybase_fetch_array', + 'sybase_fetch_assoc', + 'sybase_fetch_field', + 'sybase_fetch_object', + 'sybase_fetch_row', + 'sybase_field_seek', + 'sybase_free_result', + 'sybase_num_fields', + 'sybase_num_rows', + 'sybase_pconnect', + 'sybase_query', + 'sybase_result', + 'sybase_select_db', + 'sybase_set_message_handler', + 'sybase_unbuffered_query', + 'tmpfile', + 'udm_add_search_limit', + 'udm_alloc_agent', + 'udm_alloc_agent_array', + 'udm_cat_list', + 'udm_cat_path', + 'udm_check_charset', + 'udm_clear_search_limits', + 'udm_crc32', + 'udm_errno', + 'udm_error', + 'udm_find', + 'udm_free_agent', + 'udm_free_res', + 'udm_get_doc_count', + 'udm_get_res_field', + 'udm_get_res_param', + 'udm_hash32', + 'udm_load_ispell_data', + 'udm_set_agent_param', + 'unlink', + 'vfprintf', + 'w32api_init_dtype', + 'wddx_add_vars', + 'wddx_packet_end', + 'wddx_packet_start', + 'xml_get_current_byte_index', + 'xml_get_current_column_number', + 'xml_get_current_line_number', + 'xml_get_error_code', + 'xml_parse', + 'xml_parse_into_struct', + 'xml_parser_create', + 'xml_parser_create_ns', + 'xml_parser_free', + 'xml_parser_get_option', + 'xml_parser_set_option', + 'xml_set_character_data_handler', + 'xml_set_default_handler', + 'xml_set_element_handler', + 'xml_set_end_namespace_decl_handler', + 'xml_set_external_entity_ref_handler', + 'xml_set_notation_decl_handler', + 'xml_set_object', + 'xml_set_processing_instruction_handler', + 'xml_set_start_namespace_decl_handler', + 'xml_set_unparsed_entity_decl_handler', + 'xmlrpc_server_add_introspection_data', + 'xmlrpc_server_call_method', + 'xmlrpc_server_create', + 'xmlrpc_server_destroy', + 'xmlrpc_server_register_introspection_callback', + 'xmlrpc_server_register_method', + 'xmlwriter_end_attribute', + 'xmlwriter_end_cdata', + 'xmlwriter_end_comment', + 'xmlwriter_end_document', + 'xmlwriter_end_dtd', + 'xmlwriter_end_dtd_attlist', + 'xmlwriter_end_dtd_element', + 'xmlwriter_end_dtd_entity', + 'xmlwriter_end_element', + 'xmlwriter_end_pi', + 'xmlwriter_flush', + 'xmlwriter_full_end_element', + 'xmlwriter_open_memory', + 'xmlwriter_open_uri', + 'xmlwriter_output_memory', + 'xmlwriter_set_indent', + 'xmlwriter_set_indent_string', + 'xmlwriter_start_attribute', + 'xmlwriter_start_attribute_ns', + 'xmlwriter_start_cdata', + 'xmlwriter_start_comment', + 'xmlwriter_start_document', + 'xmlwriter_start_dtd', + 'xmlwriter_start_dtd_attlist', + 'xmlwriter_start_dtd_element', + 'xmlwriter_start_dtd_entity', + 'xmlwriter_start_element', + 'xmlwriter_start_element_ns', + 'xmlwriter_start_pi', + 'xmlwriter_text', + 'xmlwriter_write_attribute', + 'xmlwriter_write_attribute_ns', + 'xmlwriter_write_cdata', + 'xmlwriter_write_comment', + 'xmlwriter_write_dtd', + 'xmlwriter_write_dtd_attlist', + 'xmlwriter_write_dtd_element', + 'xmlwriter_write_dtd_entity', + 'xmlwriter_write_element', + 'xmlwriter_write_element_ns', + 'xmlwriter_write_pi', + 'xmlwriter_write_raw', + 'xslt_create', + 'yaz_addinfo', + 'yaz_ccl_conf', + 'yaz_ccl_parse', + 'yaz_close', + 'yaz_database', + 'yaz_element', + 'yaz_errno', + 'yaz_error', + 'yaz_es', + 'yaz_es_result', + 'yaz_get_option', + 'yaz_hits', + 'yaz_itemorder', + 'yaz_present', + 'yaz_range', + 'yaz_record', + 'yaz_scan', + 'yaz_scan_result', + 'yaz_schema', + 'yaz_search', + 'yaz_sort', + 'yaz_syntax', + 'zip_close', + 'zip_entry_close', + 'zip_entry_compressedsize', + 'zip_entry_compressionmethod', + 'zip_entry_filesize', + 'zip_entry_name', + 'zip_entry_open', + 'zip_entry_read', + 'zip_open', + 'zip_read', + ]; + } +} diff --git a/vendor/sebastian/type/ChangeLog.md b/vendor/sebastian/type/ChangeLog.md new file mode 100644 index 000000000..73837bde5 --- /dev/null +++ b/vendor/sebastian/type/ChangeLog.md @@ -0,0 +1,123 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [2.3.4] - 2021-06-15 + +* Fixed regression introduced in 2.3.3 + +## [2.3.3] - 2021-06-15 [YANKED] + +### Fixed + +* [#15](https://github.com/sebastianbergmann/type/issues/15): "false" pseudo type is not handled properly + +## [2.3.2] - 2021-06-04 + +### Fixed + +* Fixed handling of tentatively declared return types + +## [2.3.1] - 2020-10-26 + +### Fixed + +* `SebastianBergmann\Type\Exception` now correctly extends `\Throwable` + +## [2.3.0] - 2020-10-06 + +### Added + +* [#14](https://github.com/sebastianbergmann/type/issues/14): Support for `static` return type that is introduced in PHP 8 + +## [2.2.2] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [2.2.1] - 2020-07-05 + +### Fixed + +* Fixed handling of `mixed` type in `ReflectionMapper::fromMethodReturnType()` + +## [2.2.0] - 2020-07-05 + +### Added + +* Added `MixedType` object for representing PHP 8's `mixed` type + +## [2.1.1] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [2.1.0] - 2020-06-01 + +### Added + +* Added `UnionType` object for representing PHP 8's Union Types +* Added `ReflectionMapper::fromMethodReturnType()` for mapping `\ReflectionMethod::getReturnType()` to a `Type` object +* Added `Type::name()` for retrieving the name of a type +* Added `Type::asString()` for retrieving a textual representation of a type + +### Changed + +* Deprecated `Type::getReturnTypeDeclaration()` (use `Type::asString()` instead and prefix its result with `': '`) +* Deprecated `TypeName::getNamespaceName()` (use `TypeName::namespaceName()` instead) +* Deprecated `TypeName::getSimpleName()` (use `TypeName::simpleName()` instead) +* Deprecated `TypeName::getQualifiedName()` (use `TypeName::qualifiedName()` instead) + +## [2.0.0] - 2020-02-07 + +### Removed + +* This component is no longer supported on PHP 7.2 + +## [1.1.3] - 2019-07-02 + +### Fixed + +* Fixed class name comparison in `ObjectType` to be case-insensitive + +## [1.1.2] - 2019-06-19 + +### Fixed + +* Fixed handling of `object` type + +## [1.1.1] - 2019-06-08 + +### Fixed + +* Fixed autoloading of `callback_function.php` fixture file + +## [1.1.0] - 2019-06-07 + +### Added + +* Added support for `callable` type +* Added support for `iterable` type + +## [1.0.0] - 2019-06-06 + +* Initial release based on [code contributed by Michel Hartmann to PHPUnit](https://github.com/sebastianbergmann/phpunit/pull/3673) + +[2.3.4]: https://github.com/sebastianbergmann/type/compare/ca39369c41313ed12c071ed38ecda8fcdb248859...2.3.4 +[2.3.3]: https://github.com/sebastianbergmann/type/compare/2.3.2...ca39369c41313ed12c071ed38ecda8fcdb248859 +[2.3.2]: https://github.com/sebastianbergmann/type/compare/2.3.1...2.3.2 +[2.3.1]: https://github.com/sebastianbergmann/type/compare/2.3.0...2.3.1 +[2.3.0]: https://github.com/sebastianbergmann/type/compare/2.2.2...2.3.0 +[2.2.2]: https://github.com/sebastianbergmann/type/compare/2.2.1...2.2.2 +[2.2.1]: https://github.com/sebastianbergmann/type/compare/2.2.0...2.2.1 +[2.2.0]: https://github.com/sebastianbergmann/type/compare/2.1.1...2.2.0 +[2.1.1]: https://github.com/sebastianbergmann/type/compare/2.1.0...2.1.1 +[2.1.0]: https://github.com/sebastianbergmann/type/compare/2.0.0...2.1.0 +[2.0.0]: https://github.com/sebastianbergmann/type/compare/1.1.3...2.0.0 +[1.1.3]: https://github.com/sebastianbergmann/type/compare/1.1.2...1.1.3 +[1.1.2]: https://github.com/sebastianbergmann/type/compare/1.1.1...1.1.2 +[1.1.1]: https://github.com/sebastianbergmann/type/compare/1.1.0...1.1.1 +[1.1.0]: https://github.com/sebastianbergmann/type/compare/1.0.0...1.1.0 +[1.0.0]: https://github.com/sebastianbergmann/type/compare/ff74aa41746bd8d10e931843ebf37d42da513ede...1.0.0 diff --git a/vendor/sebastian/type/LICENSE b/vendor/sebastian/type/LICENSE new file mode 100644 index 000000000..b840591a9 --- /dev/null +++ b/vendor/sebastian/type/LICENSE @@ -0,0 +1,33 @@ +sebastian/type + +Copyright (c) 2019-2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/type/README.md b/vendor/sebastian/type/README.md new file mode 100644 index 000000000..1036ce7a7 --- /dev/null +++ b/vendor/sebastian/type/README.md @@ -0,0 +1,20 @@ +# sebastian/type + +[![CI Status](https://github.com/sebastianbergmann/type/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/type/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/type/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/type) + +Collection of value objects that represent the types of the PHP type system. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/type +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/type +``` diff --git a/vendor/sebastian/type/composer.json b/vendor/sebastian/type/composer.json new file mode 100644 index 000000000..b02d8e92a --- /dev/null +++ b/vendor/sebastian/type/composer.json @@ -0,0 +1,49 @@ +{ + "name": "sebastian/type", + "description": "Collection of value objects that represent the types of the PHP type system", + "type": "library", + "homepage": "https://github.com/sebastianbergmann/type", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues" + }, + "prefer-stable": true, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "autoload-dev": { + "classmap": [ + "tests/_fixture" + ], + "files": [ + "tests/_fixture/callback_function.php" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + } +} diff --git a/vendor/sebastian/type/src/CallableType.php b/vendor/sebastian/type/src/CallableType.php new file mode 100644 index 000000000..026762eaf --- /dev/null +++ b/vendor/sebastian/type/src/CallableType.php @@ -0,0 +1,197 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +use function assert; +use function class_exists; +use function count; +use function explode; +use function function_exists; +use function is_array; +use function is_object; +use function is_string; +use function strpos; +use Closure; +use ReflectionClass; +use ReflectionException; +use ReflectionObject; + +final class CallableType extends Type +{ + /** + * @var bool + */ + private $allowsNull; + + public function __construct(bool $nullable) + { + $this->allowsNull = $nullable; + } + + /** + * @throws RuntimeException + */ + public function isAssignable(Type $other): bool + { + if ($this->allowsNull && $other instanceof NullType) { + return true; + } + + if ($other instanceof self) { + return true; + } + + if ($other instanceof ObjectType) { + if ($this->isClosure($other)) { + return true; + } + + if ($this->hasInvokeMethod($other)) { + return true; + } + } + + if ($other instanceof SimpleType) { + if ($this->isFunction($other)) { + return true; + } + + if ($this->isClassCallback($other)) { + return true; + } + + if ($this->isObjectCallback($other)) { + return true; + } + } + + return false; + } + + public function name(): string + { + return 'callable'; + } + + public function allowsNull(): bool + { + return $this->allowsNull; + } + + private function isClosure(ObjectType $type): bool + { + return !$type->className()->isNamespaced() && $type->className()->simpleName() === Closure::class; + } + + /** + * @throws RuntimeException + */ + private function hasInvokeMethod(ObjectType $type): bool + { + $className = $type->className()->qualifiedName(); + assert(class_exists($className)); + + try { + $class = new ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + // @codeCoverageIgnoreEnd + } + + if ($class->hasMethod('__invoke')) { + return true; + } + + return false; + } + + private function isFunction(SimpleType $type): bool + { + if (!is_string($type->value())) { + return false; + } + + return function_exists($type->value()); + } + + private function isObjectCallback(SimpleType $type): bool + { + if (!is_array($type->value())) { + return false; + } + + if (count($type->value()) !== 2) { + return false; + } + + if (!is_object($type->value()[0]) || !is_string($type->value()[1])) { + return false; + } + + [$object, $methodName] = $type->value(); + + return (new ReflectionObject($object))->hasMethod($methodName); + } + + private function isClassCallback(SimpleType $type): bool + { + if (!is_string($type->value()) && !is_array($type->value())) { + return false; + } + + if (is_string($type->value())) { + if (strpos($type->value(), '::') === false) { + return false; + } + + [$className, $methodName] = explode('::', $type->value()); + } + + if (is_array($type->value())) { + if (count($type->value()) !== 2) { + return false; + } + + if (!is_string($type->value()[0]) || !is_string($type->value()[1])) { + return false; + } + + [$className, $methodName] = $type->value(); + } + + assert(isset($className) && is_string($className) && class_exists($className)); + assert(isset($methodName) && is_string($methodName)); + + try { + $class = new ReflectionClass($className); + + if ($class->hasMethod($methodName)) { + $method = $class->getMethod($methodName); + + return $method->isPublic() && $method->isStatic(); + } + // @codeCoverageIgnoreStart + } catch (ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + // @codeCoverageIgnoreEnd + } + + return false; + } +} diff --git a/vendor/sebastian/type/src/FalseType.php b/vendor/sebastian/type/src/FalseType.php new file mode 100644 index 000000000..425f363c0 --- /dev/null +++ b/vendor/sebastian/type/src/FalseType.php @@ -0,0 +1,46 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +final class FalseType extends Type +{ + public function isAssignable(Type $other): bool + { + if ($other instanceof self) { + return true; + } + + return $other instanceof SimpleType && + $other->name() === 'bool' && + $other->value() === false; + } + + public function name(): string + { + return 'false'; + } + + public function allowsNull(): bool + { + return false; + } + + /** + * @deprecated + * + * @codeCoverageIgnore + * + * @throws LogicException + */ + public function getReturnTypeDeclaration(): string + { + throw new LogicException; + } +} diff --git a/vendor/sebastian/type/src/GenericObjectType.php b/vendor/sebastian/type/src/GenericObjectType.php new file mode 100644 index 000000000..6871008bd --- /dev/null +++ b/vendor/sebastian/type/src/GenericObjectType.php @@ -0,0 +1,46 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +final class GenericObjectType extends Type +{ + /** + * @var bool + */ + private $allowsNull; + + public function __construct(bool $nullable) + { + $this->allowsNull = $nullable; + } + + public function isAssignable(Type $other): bool + { + if ($this->allowsNull && $other instanceof NullType) { + return true; + } + + if (!$other instanceof ObjectType) { + return false; + } + + return true; + } + + public function name(): string + { + return 'object'; + } + + public function allowsNull(): bool + { + return $this->allowsNull; + } +} diff --git a/vendor/sebastian/type/src/IterableType.php b/vendor/sebastian/type/src/IterableType.php new file mode 100644 index 000000000..c5bc6627b --- /dev/null +++ b/vendor/sebastian/type/src/IterableType.php @@ -0,0 +1,76 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +use function assert; +use function class_exists; +use function is_iterable; +use ReflectionClass; +use ReflectionException; + +final class IterableType extends Type +{ + /** + * @var bool + */ + private $allowsNull; + + public function __construct(bool $nullable) + { + $this->allowsNull = $nullable; + } + + /** + * @throws RuntimeException + */ + public function isAssignable(Type $other): bool + { + if ($this->allowsNull && $other instanceof NullType) { + return true; + } + + if ($other instanceof self) { + return true; + } + + if ($other instanceof SimpleType) { + return is_iterable($other->value()); + } + + if ($other instanceof ObjectType) { + $className = $other->className()->qualifiedName(); + assert(class_exists($className)); + + try { + return (new ReflectionClass($className))->isIterable(); + // @codeCoverageIgnoreStart + } catch (ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + // @codeCoverageIgnoreEnd + } + } + + return false; + } + + public function name(): string + { + return 'iterable'; + } + + public function allowsNull(): bool + { + return $this->allowsNull; + } +} diff --git a/vendor/sebastian/type/src/MixedType.php b/vendor/sebastian/type/src/MixedType.php new file mode 100644 index 000000000..7ad9191da --- /dev/null +++ b/vendor/sebastian/type/src/MixedType.php @@ -0,0 +1,33 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +final class MixedType extends Type +{ + public function isAssignable(Type $other): bool + { + return !$other instanceof VoidType; + } + + public function asString(): string + { + return 'mixed'; + } + + public function name(): string + { + return 'mixed'; + } + + public function allowsNull(): bool + { + return true; + } +} diff --git a/vendor/sebastian/type/src/NullType.php b/vendor/sebastian/type/src/NullType.php new file mode 100644 index 000000000..8481fceb8 --- /dev/null +++ b/vendor/sebastian/type/src/NullType.php @@ -0,0 +1,43 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +final class NullType extends Type +{ + public function isAssignable(Type $other): bool + { + return !($other instanceof VoidType); + } + + public function name(): string + { + return 'null'; + } + + public function asString(): string + { + return 'null'; + } + + /** + * @deprecated + * + * @codeCoverageIgnore + */ + public function getReturnTypeDeclaration(): string + { + return ''; + } + + public function allowsNull(): bool + { + return true; + } +} diff --git a/vendor/sebastian/type/src/ObjectType.php b/vendor/sebastian/type/src/ObjectType.php new file mode 100644 index 000000000..c71273cb4 --- /dev/null +++ b/vendor/sebastian/type/src/ObjectType.php @@ -0,0 +1,66 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +use function is_subclass_of; +use function strcasecmp; + +final class ObjectType extends Type +{ + /** + * @var TypeName + */ + private $className; + + /** + * @var bool + */ + private $allowsNull; + + public function __construct(TypeName $className, bool $allowsNull) + { + $this->className = $className; + $this->allowsNull = $allowsNull; + } + + public function isAssignable(Type $other): bool + { + if ($this->allowsNull && $other instanceof NullType) { + return true; + } + + if ($other instanceof self) { + if (0 === strcasecmp($this->className->qualifiedName(), $other->className->qualifiedName())) { + return true; + } + + if (is_subclass_of($other->className->qualifiedName(), $this->className->qualifiedName(), true)) { + return true; + } + } + + return false; + } + + public function name(): string + { + return $this->className->qualifiedName(); + } + + public function allowsNull(): bool + { + return $this->allowsNull; + } + + public function className(): TypeName + { + return $this->className; + } +} diff --git a/vendor/sebastian/type/src/ReflectionMapper.php b/vendor/sebastian/type/src/ReflectionMapper.php new file mode 100644 index 000000000..db9baf425 --- /dev/null +++ b/vendor/sebastian/type/src/ReflectionMapper.php @@ -0,0 +1,123 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +use function assert; +use function sprintf; +use ReflectionMethod; +use ReflectionNamedType; +use ReflectionType; +use ReflectionUnionType; + +final class ReflectionMapper +{ + public function fromMethodReturnType(ReflectionMethod $method): Type + { + if (!$this->reflectionMethodHasReturnType($method)) { + return new UnknownType; + } + + $returnType = $this->reflectionMethodGetReturnType($method); + + assert($returnType instanceof ReflectionNamedType || $returnType instanceof ReflectionUnionType); + + if ($returnType instanceof ReflectionNamedType) { + if ($returnType->getName() === 'self') { + return ObjectType::fromName( + $method->getDeclaringClass()->getName(), + $returnType->allowsNull() + ); + } + + if ($returnType->getName() === 'static') { + return new StaticType( + TypeName::fromReflection($method->getDeclaringClass()), + $returnType->allowsNull() + ); + } + + if ($returnType->getName() === 'mixed') { + return new MixedType; + } + + if ($returnType->getName() === 'parent') { + $parentClass = $method->getDeclaringClass()->getParentClass(); + + // @codeCoverageIgnoreStart + if ($parentClass === false) { + throw new RuntimeException( + sprintf( + '%s::%s() has a "parent" return type declaration but %s does not have a parent class', + $method->getDeclaringClass()->getName(), + $method->getName(), + $method->getDeclaringClass()->getName() + ) + ); + } + // @codeCoverageIgnoreEnd + + return ObjectType::fromName( + $parentClass->getName(), + $returnType->allowsNull() + ); + } + + return Type::fromName( + $returnType->getName(), + $returnType->allowsNull() + ); + } + + assert($returnType instanceof ReflectionUnionType); + + $types = []; + + foreach ($returnType->getTypes() as $type) { + assert($type instanceof ReflectionNamedType); + + if ($type->getName() === 'self') { + $types[] = ObjectType::fromName( + $method->getDeclaringClass()->getName(), + false + ); + } else { + $types[] = Type::fromName($type->getName(), false); + } + } + + return new UnionType(...$types); + } + + private function reflectionMethodHasReturnType(ReflectionMethod $method): bool + { + if ($method->hasReturnType()) { + return true; + } + + if (!method_exists($method, 'hasTentativeReturnType')) { + return false; + } + + return $method->hasTentativeReturnType(); + } + + private function reflectionMethodGetReturnType(ReflectionMethod $method): ?ReflectionType + { + if ($method->hasReturnType()) { + return $method->getReturnType(); + } + + if (!method_exists($method, 'getTentativeReturnType')) { + return null; + } + + return $method->getTentativeReturnType(); + } +} diff --git a/vendor/sebastian/type/src/SimpleType.php b/vendor/sebastian/type/src/SimpleType.php new file mode 100644 index 000000000..8bf0bf7df --- /dev/null +++ b/vendor/sebastian/type/src/SimpleType.php @@ -0,0 +1,92 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +use function strtolower; + +final class SimpleType extends Type +{ + /** + * @var string + */ + private $name; + + /** + * @var bool + */ + private $allowsNull; + + /** + * @var mixed + */ + private $value; + + public function __construct(string $name, bool $nullable, $value = null) + { + $this->name = $this->normalize($name); + $this->allowsNull = $nullable; + $this->value = $value; + } + + public function isAssignable(Type $other): bool + { + if ($this->allowsNull && $other instanceof NullType) { + return true; + } + + if ($this->name === 'bool' && $other->name() === 'false') { + return true; + } + + if ($other instanceof self) { + return $this->name === $other->name; + } + + return false; + } + + public function name(): string + { + return $this->name; + } + + public function allowsNull(): bool + { + return $this->allowsNull; + } + + public function value() + { + return $this->value; + } + + private function normalize(string $name): string + { + $name = strtolower($name); + + switch ($name) { + case 'boolean': + return 'bool'; + + case 'real': + case 'double': + return 'float'; + + case 'integer': + return 'int'; + + case '[]': + return 'array'; + + default: + return $name; + } + } +} diff --git a/vendor/sebastian/type/src/StaticType.php b/vendor/sebastian/type/src/StaticType.php new file mode 100644 index 000000000..6833094d1 --- /dev/null +++ b/vendor/sebastian/type/src/StaticType.php @@ -0,0 +1,60 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +final class StaticType extends Type +{ + /** + * @var TypeName + */ + private $className; + + /** + * @var bool + */ + private $allowsNull; + + public function __construct(TypeName $className, bool $allowsNull) + { + $this->className = $className; + $this->allowsNull = $allowsNull; + } + + public function isAssignable(Type $other): bool + { + if ($this->allowsNull && $other instanceof NullType) { + return true; + } + + if (!$other instanceof ObjectType) { + return false; + } + + if (0 === strcasecmp($this->className->qualifiedName(), $other->className()->qualifiedName())) { + return true; + } + + if (is_subclass_of($other->className()->qualifiedName(), $this->className->qualifiedName(), true)) { + return true; + } + + return false; + } + + public function name(): string + { + return 'static'; + } + + public function allowsNull(): bool + { + return $this->allowsNull; + } +} diff --git a/vendor/sebastian/type/src/Type.php b/vendor/sebastian/type/src/Type.php new file mode 100644 index 000000000..679223d96 --- /dev/null +++ b/vendor/sebastian/type/src/Type.php @@ -0,0 +1,101 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +use function get_class; +use function gettype; +use function strtolower; + +abstract class Type +{ + public static function fromValue($value, bool $allowsNull): self + { + if ($value === false) { + return new FalseType; + } + + $typeName = gettype($value); + + if ($typeName === 'object') { + return new ObjectType(TypeName::fromQualifiedName(get_class($value)), $allowsNull); + } + + $type = self::fromName($typeName, $allowsNull); + + if ($type instanceof SimpleType) { + $type = new SimpleType($typeName, $allowsNull, $value); + } + + return $type; + } + + public static function fromName(string $typeName, bool $allowsNull): self + { + switch (strtolower($typeName)) { + case 'callable': + return new CallableType($allowsNull); + + case 'false': + return new FalseType; + + case 'iterable': + return new IterableType($allowsNull); + + case 'null': + return new NullType; + + case 'object': + return new GenericObjectType($allowsNull); + + case 'unknown type': + return new UnknownType; + + case 'void': + return new VoidType; + + case 'array': + case 'bool': + case 'boolean': + case 'double': + case 'float': + case 'int': + case 'integer': + case 'real': + case 'resource': + case 'resource (closed)': + case 'string': + return new SimpleType($typeName, $allowsNull); + + default: + return new ObjectType(TypeName::fromQualifiedName($typeName), $allowsNull); + } + } + + public function asString(): string + { + return ($this->allowsNull() ? '?' : '') . $this->name(); + } + + /** + * @deprecated + * + * @codeCoverageIgnore + */ + public function getReturnTypeDeclaration(): string + { + return ': ' . $this->asString(); + } + + abstract public function isAssignable(Type $other): bool; + + abstract public function name(): string; + + abstract public function allowsNull(): bool; +} diff --git a/vendor/sebastian/type/src/TypeName.php b/vendor/sebastian/type/src/TypeName.php new file mode 100644 index 000000000..b076e89e0 --- /dev/null +++ b/vendor/sebastian/type/src/TypeName.php @@ -0,0 +1,113 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +use function array_pop; +use function explode; +use function implode; +use function substr; +use ReflectionClass; + +final class TypeName +{ + /** + * @var ?string + */ + private $namespaceName; + + /** + * @var string + */ + private $simpleName; + + public static function fromQualifiedName(string $fullClassName): self + { + if ($fullClassName[0] === '\\') { + $fullClassName = substr($fullClassName, 1); + } + + $classNameParts = explode('\\', $fullClassName); + + $simpleName = array_pop($classNameParts); + $namespaceName = implode('\\', $classNameParts); + + return new self($namespaceName, $simpleName); + } + + public static function fromReflection(ReflectionClass $type): self + { + return new self( + $type->getNamespaceName(), + $type->getShortName() + ); + } + + public function __construct(?string $namespaceName, string $simpleName) + { + if ($namespaceName === '') { + $namespaceName = null; + } + + $this->namespaceName = $namespaceName; + $this->simpleName = $simpleName; + } + + public function namespaceName(): ?string + { + return $this->namespaceName; + } + + public function simpleName(): string + { + return $this->simpleName; + } + + public function qualifiedName(): string + { + return $this->namespaceName === null + ? $this->simpleName + : $this->namespaceName . '\\' . $this->simpleName; + } + + /** + * @deprecated Use namespaceName() instead + * + * @codeCoverageIgnore + */ + public function getNamespaceName(): ?string + { + return $this->namespaceName(); + } + + /** + * @deprecated Use simpleName() instead + * + * @codeCoverageIgnore + */ + public function getSimpleName(): string + { + return $this->simpleName(); + } + + /** + * @deprecated Use qualifiedName() instead + * + * @codeCoverageIgnore + */ + public function getQualifiedName(): string + { + return $this->qualifiedName(); + } + + public function isNamespaced(): bool + { + return $this->namespaceName !== null; + } +} diff --git a/vendor/sebastian/type/src/UnionType.php b/vendor/sebastian/type/src/UnionType.php new file mode 100644 index 000000000..10c4a49b5 --- /dev/null +++ b/vendor/sebastian/type/src/UnionType.php @@ -0,0 +1,115 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +use function count; +use function implode; +use function sort; + +final class UnionType extends Type +{ + /** + * @psalm-var list<Type> + */ + private $types; + + /** + * @throws RuntimeException + */ + public function __construct(Type ...$types) + { + $this->ensureMinimumOfTwoTypes(...$types); + $this->ensureOnlyValidTypes(...$types); + + $this->types = $types; + } + + public function isAssignable(Type $other): bool + { + foreach ($this->types as $type) { + if ($type->isAssignable($other)) { + return true; + } + } + + return false; + } + + public function asString(): string + { + return $this->name(); + } + + /** + * @deprecated + * + * @codeCoverageIgnore + */ + public function getReturnTypeDeclaration(): string + { + return ': ' . $this->name(); + } + + public function name(): string + { + $types = []; + + foreach ($this->types as $type) { + $types[] = $type->name(); + } + + sort($types); + + return implode('|', $types); + } + + public function allowsNull(): bool + { + foreach ($this->types as $type) { + if ($type instanceof NullType) { + return true; + } + } + + return false; + } + + /** + * @throws RuntimeException + */ + private function ensureMinimumOfTwoTypes(Type ...$types): void + { + if (count($types) < 2) { + throw new RuntimeException( + 'A union type must be composed of at least two types' + ); + } + } + + /** + * @throws RuntimeException + */ + private function ensureOnlyValidTypes(Type ...$types): void + { + foreach ($types as $type) { + if ($type instanceof UnknownType) { + throw new RuntimeException( + 'A union type must not be composed of an unknown type' + ); + } + + if ($type instanceof VoidType) { + throw new RuntimeException( + 'A union type must not be composed of a void type' + ); + } + } + } +} diff --git a/vendor/sebastian/type/src/UnknownType.php b/vendor/sebastian/type/src/UnknownType.php new file mode 100644 index 000000000..dde4c6788 --- /dev/null +++ b/vendor/sebastian/type/src/UnknownType.php @@ -0,0 +1,43 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +final class UnknownType extends Type +{ + public function isAssignable(Type $other): bool + { + return true; + } + + public function name(): string + { + return 'unknown type'; + } + + public function asString(): string + { + return ''; + } + + /** + * @deprecated + * + * @codeCoverageIgnore + */ + public function getReturnTypeDeclaration(): string + { + return ''; + } + + public function allowsNull(): bool + { + return true; + } +} diff --git a/vendor/sebastian/type/src/VoidType.php b/vendor/sebastian/type/src/VoidType.php new file mode 100644 index 000000000..18c017564 --- /dev/null +++ b/vendor/sebastian/type/src/VoidType.php @@ -0,0 +1,28 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +final class VoidType extends Type +{ + public function isAssignable(Type $other): bool + { + return $other instanceof self; + } + + public function name(): string + { + return 'void'; + } + + public function allowsNull(): bool + { + return false; + } +} diff --git a/vendor/sebastian/type/src/exception/Exception.php b/vendor/sebastian/type/src/exception/Exception.php new file mode 100644 index 000000000..e0e7ee579 --- /dev/null +++ b/vendor/sebastian/type/src/exception/Exception.php @@ -0,0 +1,16 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +use Throwable; + +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/type/src/exception/LogicException.php b/vendor/sebastian/type/src/exception/LogicException.php new file mode 100644 index 000000000..243582166 --- /dev/null +++ b/vendor/sebastian/type/src/exception/LogicException.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +final class LogicException extends \LogicException implements Exception +{ +} diff --git a/vendor/sebastian/type/src/exception/RuntimeException.php b/vendor/sebastian/type/src/exception/RuntimeException.php new file mode 100644 index 000000000..4dfea6a6a --- /dev/null +++ b/vendor/sebastian/type/src/exception/RuntimeException.php @@ -0,0 +1,14 @@ +<?php declare(strict_types=1); +/* + * This file is part of sebastian/type. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Type; + +final class RuntimeException extends \RuntimeException implements Exception +{ +} diff --git a/vendor/sebastian/version/.gitattributes b/vendor/sebastian/version/.gitattributes new file mode 100644 index 000000000..54b895305 --- /dev/null +++ b/vendor/sebastian/version/.gitattributes @@ -0,0 +1,4 @@ +/.github export-ignore +/.php_cs.dist export-ignore + +*.php diff=php diff --git a/vendor/sebastian/version/.gitignore b/vendor/sebastian/version/.gitignore new file mode 100644 index 000000000..ff5ec9a0e --- /dev/null +++ b/vendor/sebastian/version/.gitignore @@ -0,0 +1,2 @@ +/.php_cs.cache +/.idea diff --git a/vendor/sebastian/version/ChangeLog.md b/vendor/sebastian/version/ChangeLog.md new file mode 100644 index 000000000..10fd9a1a5 --- /dev/null +++ b/vendor/sebastian/version/ChangeLog.md @@ -0,0 +1,25 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles. + +## [3.0.2] - 2020-09-28 + +### Changed + +* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3` + +## [3.0.1] - 2020-06-26 + +### Added + +* This component is now supported on PHP 8 + +## [3.0.0] - 2020-01-21 + +### Removed + +* This component is no longer supported on PHP 7.1 and PHP 7.2 + +[3.0.2]: https://github.com/sebastianbergmann/version/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/sebastianbergmann/version/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/sebastianbergmann/version/compare/2.0.1...3.0.0 diff --git a/vendor/sebastian/version/LICENSE b/vendor/sebastian/version/LICENSE new file mode 100644 index 000000000..aa6bca299 --- /dev/null +++ b/vendor/sebastian/version/LICENSE @@ -0,0 +1,33 @@ +Version + +Copyright (c) 2013-2020, Sebastian Bergmann <[email protected]>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/version/README.md b/vendor/sebastian/version/README.md new file mode 100644 index 000000000..2864c8126 --- /dev/null +++ b/vendor/sebastian/version/README.md @@ -0,0 +1,43 @@ +# Version + +**Version** is a library that helps with managing the version number of Git-hosted PHP projects. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require sebastian/version + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + + composer require --dev sebastian/version + +## Usage + +The constructor of the `SebastianBergmann\Version` class expects two parameters: + +* `$release` is the version number of the latest release (`X.Y.Z`, for instance) or the name of the release series (`X.Y`) when no release has been made from that branch / for that release series yet. +* `$path` is the path to the directory (or a subdirectory thereof) where the sourcecode of the project can be found. Simply passing `__DIR__` here usually suffices. + +Apart from the constructor, the `SebastianBergmann\Version` class has a single public method: `getVersion()`. + +Here is a contrived example that shows the basic usage: + + <?php + $version = new SebastianBergmann\Version( + '3.7.10', '/usr/local/src/phpunit' + ); + + var_dump($version->getVersion()); + ?> + + string(18) "3.7.10-17-g00f3408" + +When a new release is prepared, the string that is passed to the constructor as the first argument needs to be updated. + +### How SebastianBergmann\Version::getVersion() works + +* If `$path` is not (part of) a Git repository and `$release` is in `X.Y.Z` format then `$release` is returned as-is. +* If `$path` is not (part of) a Git repository and `$release` is in `X.Y` format then `$release` is returned suffixed with `-dev`. +* If `$path` is (part of) a Git repository and `$release` is in `X.Y.Z` format then the output of `git describe --tags` is returned as-is. +* If `$path` is (part of) a Git repository and `$release` is in `X.Y` format then a string is returned that begins with `X.Y` and ends with information from `git describe --tags`. diff --git a/vendor/sebastian/version/composer.json b/vendor/sebastian/version/composer.json new file mode 100644 index 000000000..e76dbf412 --- /dev/null +++ b/vendor/sebastian/version/composer.json @@ -0,0 +1,37 @@ +{ + "name": "sebastian/version", + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "[email protected]", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues" + }, + "config": { + "platform": { + "php": "7.3.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "prefer-stable": true, + "require": { + "php": ">=7.3" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + } +} diff --git a/vendor/sebastian/version/src/Version.php b/vendor/sebastian/version/src/Version.php new file mode 100644 index 000000000..53ae7894e --- /dev/null +++ b/vendor/sebastian/version/src/Version.php @@ -0,0 +1,97 @@ +<?php +/* + * This file is part of sebastian/version. + * + * (c) Sebastian Bergmann <[email protected]> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann; + +final class Version +{ + /** + * @var string + */ + private $path; + + /** + * @var string + */ + private $release; + + /** + * @var string + */ + private $version; + + public function __construct(string $release, string $path) + { + $this->release = $release; + $this->path = $path; + } + + public function getVersion(): string + { + if ($this->version === null) { + if (\substr_count($this->release, '.') + 1 === 3) { + $this->version = $this->release; + } else { + $this->version = $this->release . '-dev'; + } + + $git = $this->getGitInformation($this->path); + + if ($git) { + if (\substr_count($this->release, '.') + 1 === 3) { + $this->version = $git; + } else { + $git = \explode('-', $git); + + $this->version = $this->release . '-' . \end($git); + } + } + } + + return $this->version; + } + + /** + * @return bool|string + */ + private function getGitInformation(string $path) + { + if (!\is_dir($path . DIRECTORY_SEPARATOR . '.git')) { + return false; + } + + $process = \proc_open( + 'git describe --tags', + [ + 1 => ['pipe', 'w'], + 2 => ['pipe', 'w'], + ], + $pipes, + $path + ); + + if (!\is_resource($process)) { + return false; + } + + $result = \trim(\stream_get_contents($pipes[1])); + + \fclose($pipes[1]); + \fclose($pipes[2]); + + $returnCode = \proc_close($process); + + if ($returnCode !== 0) { + return false; + } + + return $result; + } +} |