COPYRIGHT.md000064400000000133144760120040006431 0ustar00Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) LICENSE.md000064400000002732144760120040006152 0ustar00Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. 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 Laminas Foundation nor the names of its 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. README.md000064400000001612144760120040006021 0ustar00# laminas-code [![Build Status](https://travis-ci.com/laminas/laminas-code.svg?branch=master)](https://travis-ci.com/laminas/laminas-code) [![Coverage Status](https://coveralls.io/repos/github/laminas/laminas-code/badge.svg?branch=master)](https://coveralls.io/github/laminas/laminas-code?branch=master) `Laminas\Code\Generator` provides facilities to generate arbitrary code using an object-oriented interface, both to create new code as well as to update existing code. While the current implementation is limited to generating PHP code, you can easily extend the base class in order to provide code generation for other tasks: JavaScript, configuration files, apache vhosts, etc. - File issues at https://github.com/laminas/laminas-code/issues - Documentation is at https://docs.laminas.dev/laminas-code/ - Migration documentation from v2 to v3 is at https://docs.laminas.dev/laminas-code/migration/ composer.json000064400000003620144760120040007265 0ustar00{ "name": "laminas/laminas-code", "description": "Extensions to the PHP Reflection API, static code scanning, and code generation", "keywords": [ "laminas", "laminasframework", "code" ], "homepage": "https://laminas.dev", "license": "BSD-3-Clause", "require": { "php": ">=7.4, <8.2" }, "require-dev": { "ext-phar": "*", "doctrine/annotations": "^1.13.2", "laminas/laminas-coding-standard": "^2.3.0", "laminas/laminas-stdlib": "^3.6.1", "phpunit/phpunit": "^9.5.10", "psalm/plugin-phpunit": "^0.16.1", "vimeo/psalm": "^4.13.1" }, "suggest": { "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", "laminas/laminas-stdlib": "Laminas\\Stdlib component" }, "config": { "sort-packages": true, "platform": { "php": "7.4.99" } }, "autoload": { "psr-4": { "Laminas\\Code\\": "src/" }, "files": [ "polyfill/ReflectionEnumPolyfill.php" ] }, "autoload-dev": { "psr-4": { "LaminasTest\\Code\\": "test/" } }, "scripts": { "check": [ "@cs-check", "@test" ], "cs-check": "phpcs", "cs-fix": "phpcbf", "static-analysis": "psalm --shepherd --stats", "test": "phpunit --colors=always", "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" }, "support": { "issues": "https://github.com/laminas/laminas-code/issues", "forum": "https://discourse.laminas.dev", "chat": "https://laminas.dev/chat", "source": "https://github.com/laminas/laminas-code", "docs": "https://docs.laminas.dev/laminas-code/", "rss": "https://github.com/laminas/laminas-code/releases.atom" } } composer.lock000064400000466750144760120040007265 0ustar00{ "_readme": [ "This file locks the dependencies of your project to a known state", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], "content-hash": "efa41c3781b7aa3b5f7f024250477d87", "packages": [], "packages-dev": [ { "name": "amphp/amp", "version": "v2.6.1", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", "reference": "c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/amphp/amp/zipball/c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae", "reference": "c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae", "shasum": "" }, "require": { "php": ">=7.1" }, "require-dev": { "amphp/php-cs-fixer-config": "dev-master", "amphp/phpunit-util": "^1", "ext-json": "*", "jetbrains/phpstorm-stubs": "^2019.3", "phpunit/phpunit": "^7 | ^8 | ^9", "psalm/phar": "^3.11@dev", "react/promise": "^2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { "Amp\\": "lib" }, "files": [ "lib/functions.php", "lib/Internal/functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Daniel Lowrey", "email": "rdlowrey@php.net" }, { "name": "Aaron Piotrowski", "email": "aaron@trowski.com" }, { "name": "Bob Weinand", "email": "bobwei9@hotmail.com" }, { "name": "Niklas Keller", "email": "me@kelunik.com" } ], "description": "A non-blocking concurrency framework for PHP applications.", "homepage": "http://amphp.org/amp", "keywords": [ "async", "asynchronous", "awaitable", "concurrency", "event", "event-loop", "future", "non-blocking", "promise" ], "support": { "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/amp/issues", "source": "https://github.com/amphp/amp/tree/v2.6.1" }, "funding": [ { "url": "https://github.com/amphp", "type": "github" } ], "time": "2021-09-23T18:43:08+00:00" }, { "name": "amphp/byte-stream", "version": "v1.8.1", "source": { "type": "git", "url": "https://github.com/amphp/byte-stream.git", "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd", "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd", "shasum": "" }, "require": { "amphp/amp": "^2", "php": ">=7.1" }, "require-dev": { "amphp/php-cs-fixer-config": "dev-master", "amphp/phpunit-util": "^1.4", "friendsofphp/php-cs-fixer": "^2.3", "jetbrains/phpstorm-stubs": "^2019.3", "phpunit/phpunit": "^6 || ^7 || ^8", "psalm/phar": "^3.11.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "Amp\\ByteStream\\": "lib" }, "files": [ "lib/functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Aaron Piotrowski", "email": "aaron@trowski.com" }, { "name": "Niklas Keller", "email": "me@kelunik.com" } ], "description": "A stream abstraction to make working with non-blocking I/O simple.", "homepage": "http://amphp.org/byte-stream", "keywords": [ "amp", "amphp", "async", "io", "non-blocking", "stream" ], "support": { "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/byte-stream/issues", "source": "https://github.com/amphp/byte-stream/tree/v1.8.1" }, "funding": [ { "url": "https://github.com/amphp", "type": "github" } ], "time": "2021-03-30T17:13:30+00:00" }, { "name": "composer/package-versions-deprecated", "version": "1.11.99.4", "source": { "type": "git", "url": "https://github.com/composer/package-versions-deprecated.git", "reference": "b174585d1fe49ceed21928a945138948cb394600" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600", "reference": "b174585d1fe49ceed21928a945138948cb394600", "shasum": "" }, "require": { "composer-plugin-api": "^1.1.0 || ^2.0", "php": "^7 || ^8" }, "replace": { "ocramius/package-versions": "1.11.99" }, "require-dev": { "composer/composer": "^1.9.3 || ^2.0@dev", "ext-zip": "^1.13", "phpunit/phpunit": "^6.5 || ^7" }, "type": "composer-plugin", "extra": { "class": "PackageVersions\\Installer", "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "PackageVersions\\": "src/PackageVersions" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com" }, { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be" } ], "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", "support": { "issues": "https://github.com/composer/package-versions-deprecated/issues", "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.4" }, "funding": [ { "url": "https://packagist.com", "type": "custom" }, { "url": "https://github.com/composer", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], "time": "2021-09-13T08:41:34+00:00" }, { "name": "composer/semver", "version": "3.2.6", "source": { "type": "git", "url": "https://github.com/composer/semver.git", "reference": "83e511e247de329283478496f7a1e114c9517506" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/semver/zipball/83e511e247de329283478496f7a1e114c9517506", "reference": "83e511e247de329283478496f7a1e114c9517506", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { "phpstan/phpstan": "^0.12.54", "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { "dev-main": "3.x-dev" } }, "autoload": { "psr-4": { "Composer\\Semver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nils Adermann", "email": "naderman@naderman.de", "homepage": "http://www.naderman.de" }, { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "http://seld.be" }, { "name": "Rob Bast", "email": "rob.bast@gmail.com", "homepage": "http://robbast.nl" } ], "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ "semantic", "semver", "validation", "versioning" ], "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/semver/issues", "source": "https://github.com/composer/semver/tree/3.2.6" }, "funding": [ { "url": "https://packagist.com", "type": "custom" }, { "url": "https://github.com/composer", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], "time": "2021-10-25T11:34:17+00:00" }, { "name": "composer/xdebug-handler", "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/84674dd3a7575ba617f5a76d7e9e29a7d3891339", "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0", "psr/log": "^1 || ^2 || ^3" }, "require-dev": { "phpstan/phpstan": "^0.12.55", "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", "autoload": { "psr-4": { "Composer\\XdebugHandler\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "John Stevenson", "email": "john-stevenson@blueyonder.co.uk" } ], "description": "Restarts a process without Xdebug.", "keywords": [ "Xdebug", "performance" ], "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/xdebug-handler/issues", "source": "https://github.com/composer/xdebug-handler/tree/2.0.2" }, "funding": [ { "url": "https://packagist.com", "type": "custom" }, { "url": "https://github.com/composer", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], "time": "2021-07-31T17:03:58+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", "version": "v0.7.1", "source": { "type": "git", "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", "reference": "fe390591e0241955f22eb9ba327d137e501c771c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/fe390591e0241955f22eb9ba327d137e501c771c", "reference": "fe390591e0241955f22eb9ba327d137e501c771c", "shasum": "" }, "require": { "composer-plugin-api": "^1.0 || ^2.0", "php": ">=5.3", "squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0" }, "require-dev": { "composer/composer": "*", "phpcompatibility/php-compatibility": "^9.0", "sensiolabs/security-checker": "^4.1.0" }, "type": "composer-plugin", "extra": { "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, "autoload": { "psr-4": { "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Franck Nijhof", "email": "franck.nijhof@dealerdirect.com", "homepage": "http://www.frenck.nl", "role": "Developer / IT Manager" } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", "homepage": "http://www.dealerdirect.com", "keywords": [ "PHPCodeSniffer", "PHP_CodeSniffer", "code quality", "codesniffer", "composer", "installer", "phpcs", "plugin", "qa", "quality", "standard", "standards", "style guide", "stylecheck", "tests" ], "support": { "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" }, "time": "2020-12-07T18:04:37+00:00" }, { "name": "dnoegel/php-xdg-base-dir", "version": "v0.1.1", "source": { "type": "git", "url": "https://github.com/dnoegel/php-xdg-base-dir.git", "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", "shasum": "" }, "require": { "php": ">=5.3.2" }, "require-dev": { "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" }, "type": "library", "autoload": { "psr-4": { "XdgBaseDir\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "implementation of xdg base directory specification for php", "support": { "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" }, "time": "2019-12-04T15:06:13+00:00" }, { "name": "doctrine/annotations", "version": "1.13.2", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", "reference": "5b668aef16090008790395c02c893b1ba13f7e08" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", "reference": "5b668aef16090008790395c02c893b1ba13f7e08", "shasum": "" }, "require": { "doctrine/lexer": "1.*", "ext-tokenizer": "*", "php": "^7.1 || ^8.0", "psr/cache": "^1 || ^2 || ^3" }, "require-dev": { "doctrine/cache": "^1.11 || ^2.0", "doctrine/coding-standard": "^6.0 || ^8.1", "phpstan/phpstan": "^0.12.20", "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", "symfony/cache": "^4.4 || ^5.2" }, "type": "library", "autoload": { "psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], "description": "Docblock Annotations Parser", "homepage": "https://www.doctrine-project.org/projects/annotations.html", "keywords": [ "annotations", "docblock", "parser" ], "support": { "issues": "https://github.com/doctrine/annotations/issues", "source": "https://github.com/doctrine/annotations/tree/1.13.2" }, "time": "2021-08-05T19:00:23+00:00" }, { "name": "doctrine/instantiator", "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", "phpstan/phpstan": "^0.12", "phpstan/phpstan-phpunit": "^0.12", "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", "source": "https://github.com/doctrine/instantiator/tree/1.4.0" }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { "url": "https://www.patreon.com/phpdoctrine", "type": "patreon" }, { "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", "type": "tidelift" } ], "time": "2020-11-10T18:47:58+00:00" }, { "name": "doctrine/lexer", "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^6.0", "phpstan/phpstan": "^0.11.8", "phpunit/phpunit": "^8.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.2.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", "homepage": "https://www.doctrine-project.org/projects/lexer.html", "keywords": [ "annotations", "docblock", "lexer", "parser", "php" ], "support": { "issues": "https://github.com/doctrine/lexer/issues", "source": "https://github.com/doctrine/lexer/tree/1.2.1" }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { "url": "https://www.patreon.com/phpdoctrine", "type": "patreon" }, { "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", "type": "tidelift" } ], "time": "2020-05-25T17:44:05+00:00" }, { "name": "felixfbecker/advanced-json-rpc", "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", "shasum": "" }, "require": { "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", "php": "^7.1 || ^8.0", "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" }, "require-dev": { "phpunit/phpunit": "^7.0 || ^8.0" }, "type": "library", "autoload": { "psr-4": { "AdvancedJsonRpc\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "ISC" ], "authors": [ { "name": "Felix Becker", "email": "felix.b@outlook.com" } ], "description": "A more advanced JSONRPC implementation", "support": { "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" }, "time": "2021-06-11T22:34:44+00:00" }, { "name": "felixfbecker/language-server-protocol", "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/felixfbecker/php-language-server-protocol.git", "reference": "9d846d1f5cf101deee7a61c8ba7caa0a975cd730" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/9d846d1f5cf101deee7a61c8ba7caa0a975cd730", "reference": "9d846d1f5cf101deee7a61c8ba7caa0a975cd730", "shasum": "" }, "require": { "php": ">=7.1" }, "require-dev": { "phpstan/phpstan": "*", "squizlabs/php_codesniffer": "^3.1", "vimeo/psalm": "^4.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "LanguageServerProtocol\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "ISC" ], "authors": [ { "name": "Felix Becker", "email": "felix.b@outlook.com" } ], "description": "PHP classes for the Language Server Protocol", "keywords": [ "language", "microsoft", "php", "server" ], "support": { "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/1.5.1" }, "time": "2021-02-22T14:02:09+00:00" }, { "name": "laminas/laminas-coding-standard", "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-coding-standard.git", "reference": "bcf6e07fe4690240be7beb6d884d0b0fafa6a251" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/bcf6e07fe4690240be7beb6d884d0b0fafa6a251", "reference": "bcf6e07fe4690240be7beb6d884d0b0fafa6a251", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.7", "php": "^7.3 || ^8.0", "slevomat/coding-standard": "^7.0", "squizlabs/php_codesniffer": "^3.6", "webimpress/coding-standard": "^1.2" }, "type": "phpcodesniffer-standard", "autoload": { "psr-4": { "LaminasCodingStandard\\": "src/LaminasCodingStandard/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "description": "Laminas Coding Standard", "homepage": "https://laminas.dev", "keywords": [ "Coding Standard", "laminas" ], "support": { "chat": "https://laminas.dev/chat", "docs": "https://docs.laminas.dev/laminas-coding-standard/", "forum": "https://discourse.laminas.dev", "issues": "https://github.com/laminas/laminas-coding-standard/issues", "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", "source": "https://github.com/laminas/laminas-coding-standard" }, "funding": [ { "url": "https://funding.communitybridge.org/projects/laminas-project", "type": "community_bridge" } ], "time": "2021-05-29T15:53:59+00:00" }, { "name": "laminas/laminas-stdlib", "version": "3.6.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-stdlib.git", "reference": "db581851a092246ad99e12d4fddf105184924c71" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/db581851a092246ad99e12d4fddf105184924c71", "reference": "db581851a092246ad99e12d4fddf105184924c71", "shasum": "" }, "require": { "php": "^7.3 || ~8.0.0 || ~8.1.0" }, "conflict": { "zendframework/zend-stdlib": "*" }, "require-dev": { "laminas/laminas-coding-standard": "~2.3.0", "phpbench/phpbench": "^0.17.1", "phpunit/phpunit": "~9.3.7", "psalm/plugin-phpunit": "^0.16.0", "vimeo/psalm": "^4.7" }, "type": "library", "autoload": { "psr-4": { "Laminas\\Stdlib\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "description": "SPL extensions, array utilities, error handlers, and more", "homepage": "https://laminas.dev", "keywords": [ "laminas", "stdlib" ], "support": { "chat": "https://laminas.dev/chat", "docs": "https://docs.laminas.dev/laminas-stdlib/", "forum": "https://discourse.laminas.dev", "issues": "https://github.com/laminas/laminas-stdlib/issues", "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", "source": "https://github.com/laminas/laminas-stdlib" }, "funding": [ { "url": "https://funding.communitybridge.org/projects/laminas-project", "type": "community_bridge" } ], "time": "2021-11-10T11:33:52+00:00" }, { "name": "myclabs/deep-copy", "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "replace": { "myclabs/deep-copy": "self.version" }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", "phpunit/phpunit": "^7.1" }, "type": "library", "autoload": { "psr-4": { "DeepCopy\\": "src/DeepCopy/" }, "files": [ "src/DeepCopy/deep_copy.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Create deep copies (clones) of your objects", "keywords": [ "clone", "copy", "duplicate", "object", "object graph" ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", "type": "tidelift" } ], "time": "2020-11-13T09:40:50+00:00" }, { "name": "netresearch/jsonmapper", "version": "v4.0.0", "source": { "type": "git", "url": "https://github.com/cweiske/jsonmapper.git", "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", "shasum": "" }, "require": { "ext-json": "*", "ext-pcre": "*", "ext-reflection": "*", "ext-spl": "*", "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0", "squizlabs/php_codesniffer": "~3.5" }, "type": "library", "autoload": { "psr-0": { "JsonMapper": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "OSL-3.0" ], "authors": [ { "name": "Christian Weiske", "email": "cweiske@cweiske.de", "homepage": "http://github.com/cweiske/jsonmapper/", "role": "Developer" } ], "description": "Map nested JSON structures onto PHP classes", "support": { "email": "cweiske@cweiske.de", "issues": "https://github.com/cweiske/jsonmapper/issues", "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0" }, "time": "2020-12-01T19:48:11+00:00" }, { "name": "nikic/php-parser", "version": "v4.13.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", "reference": "210577fe3cf7badcc5814d99455df46564f3c077" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", "reference": "210577fe3cf7badcc5814d99455df46564f3c077", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=7.0" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" ], "type": "library", "extra": { "branch-alias": { "dev-master": "4.9-dev" } }, "autoload": { "psr-4": { "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Nikita Popov" } ], "description": "A PHP parser written in PHP", "keywords": [ "parser", "php" ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" }, "time": "2021-11-30T19:35:32+00:00" }, { "name": "openlss/lib-array2xml", "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/nullivex/lib-array2xml.git", "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", "shasum": "" }, "require": { "php": ">=5.3.2" }, "type": "library", "autoload": { "psr-0": { "LSS": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "authors": [ { "name": "Bryan Tong", "email": "bryan@nullivex.com", "homepage": "https://www.nullivex.com" }, { "name": "Tony Butler", "email": "spudz76@gmail.com", "homepage": "https://www.nullivex.com" } ], "description": "Array2XML conversion library credit to lalit.org", "homepage": "https://www.nullivex.com", "keywords": [ "array", "array conversion", "xml", "xml conversion" ], "support": { "issues": "https://github.com/nullivex/lib-array2xml/issues", "source": "https://github.com/nullivex/lib-array2xml/tree/master" }, "time": "2019-03-29T20:06:56+00:00" }, { "name": "phar-io/manifest", "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", "reference": "97803eca37d319dfa7826cc2437fc020857acb53" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", "reference": "97803eca37d319dfa7826cc2437fc020857acb53", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1", "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", "source": "https://github.com/phar-io/manifest/tree/2.0.3" }, "time": "2021-07-20T11:28:43+00:00" }, { "name": "phar-io/version", "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", "reference": "bae7c545bef187884426f042434e561ab1ddb182" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", "reference": "bae7c545bef187884426f042434e561ab1ddb182", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", "source": "https://github.com/phar-io/version/tree/3.1.0" }, "time": "2021-02-23T14:00:09+00:00" }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { "dev-2.x": "2.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Jaap van Otterdijk", "email": "opensource@ijaap.nl" } ], "description": "Common reflection classes used by phpdocumentor to reflect the code structure", "homepage": "http://www.phpdoc.org", "keywords": [ "FQSEN", "phpDocumentor", "phpdoc", "reflection", "static analysis" ], "support": { "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" }, "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", "shasum": "" }, "require": { "ext-filter": "*", "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.2", "phpdocumentor/type-resolver": "^1.3", "webmozart/assert": "^1.9.1" }, "require-dev": { "mockery/mockery": "~1.3.2", "psalm/phar": "^4.8" }, "type": "library", "extra": { "branch-alias": { "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" }, { "name": "Jaap van Otterdijk", "email": "account@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" }, "time": "2021-10-19T17:43:47+00:00" }, { "name": "phpdocumentor/type-resolver", "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { "ext-tokenizer": "*", "psalm/phar": "^4.8" }, "type": "library", "extra": { "branch-alias": { "dev-1.x": "1.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" }, "time": "2021-10-02T14:08:47+00:00" }, { "name": "phpspec/prophecy", "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", "php": "^7.2 || ~8.0, <8.2", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { "phpspec/phpspec": "^6.0 || ^7.0", "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "Prophecy\\": "src/Prophecy" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Konstantin Kudryashov", "email": "ever.zet@gmail.com", "homepage": "http://everzet.com" }, { "name": "Marcello Duarte", "email": "marcello.duarte@gmail.com" } ], "description": "Highly opinionated mocking framework for PHP 5.3+", "homepage": "https://github.com/phpspec/prophecy", "keywords": [ "Double", "Dummy", "fake", "mock", "spy", "stub" ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", "source": "https://github.com/phpspec/prophecy/tree/1.14.0" }, "time": "2021-09-10T09:02:12+00:00" }, { "name": "phpstan/phpdoc-parser", "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", "reference": "dbc093d7af60eff5cd575d2ed761b15ed40bd08e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/dbc093d7af60eff5cd575d2ed761b15ed40bd08e", "reference": "dbc093d7af60eff5cd575d2ed761b15ed40bd08e", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { "php-parallel-lint/php-parallel-lint": "^1.2", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^1.0", "phpstan/phpstan-strict-rules": "^1.0", "phpunit/phpunit": "^9.5", "symfony/process": "^5.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, "autoload": { "psr-4": { "PHPStan\\PhpDocParser\\": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", "source": "https://github.com/phpstan/phpdoc-parser/tree/1.2.0" }, "time": "2021-09-16T20:46:02+00:00" }, { "name": "phpunit/php-code-coverage", "version": "9.2.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", "nikic/php-parser": "^4.13.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", "sebastian/code-unit-reverse-lookup": "^2.0.2", "sebastian/complexity": "^2.0", "sebastian/environment": "^5.1.2", "sebastian/lines-of-code": "^1.0.3", "sebastian/version": "^3.0.1", "theseer/tokenizer": "^1.2.0" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "suggest": { "ext-pcov": "*", "ext-xdebug": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "9.2-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ "coverage", "testing", "xunit" ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2021-12-05T09:12:13+00:00" }, { "name": "phpunit/php-file-iterator", "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "FilterIterator implementation that filters files based on a list of suffixes.", "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ "filesystem", "iterator" ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2021-12-02T12:48:52+00:00" }, { "name": "phpunit/php-invoker", "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "ext-pcntl": "*", "phpunit/phpunit": "^9.3" }, "suggest": { "ext-pcntl": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Invoke callables with a timeout", "homepage": "https://github.com/sebastianbergmann/php-invoker/", "keywords": [ "process" ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T05:58:55+00:00" }, { "name": "phpunit/php-text-template", "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Simple template engine.", "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ "template" ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T05:33:50+00:00" }, { "name": "phpunit/php-timer", "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "5.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Utility class for timing", "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ "timer" ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:16:10+00:00" }, { "name": "phpunit/phpunit", "version": "9.5.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", "shasum": "" }, "require": { "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", "phpunit/php-code-coverage": "^9.2.7", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", "phpunit/php-timer": "^5.0.2", "sebastian/cli-parser": "^1.0.1", "sebastian/code-unit": "^1.0.6", "sebastian/comparator": "^4.0.5", "sebastian/diff": "^4.0.3", "sebastian/environment": "^5.1.3", "sebastian/exporter": "^4.0.3", "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", "sebastian/type": "^2.3.4", "sebastian/version": "^3.0.2" }, "require-dev": { "ext-pdo": "*", "phpspec/prophecy-phpunit": "^2.0.1" }, "suggest": { "ext-soap": "*", "ext-xdebug": "*" }, "bin": [ "phpunit" ], "type": "library", "extra": { "branch-alias": { "dev-master": "9.5-dev" } }, "autoload": { "classmap": [ "src/" ], "files": [ "src/Framework/Assert/Functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "The PHP Unit Testing framework.", "homepage": "https://phpunit.de/", "keywords": [ "phpunit", "testing", "xunit" ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" }, "funding": [ { "url": "https://phpunit.de/donate.html", "type": "custom" }, { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2021-09-25T07:38:51+00:00" }, { "name": "psalm/plugin-phpunit", "version": "0.16.1", "source": { "type": "git", "url": "https://github.com/psalm/psalm-plugin-phpunit.git", "reference": "5dd3be04f37a857d52880ef6af2524a441dfef24" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/5dd3be04f37a857d52880ef6af2524a441dfef24", "reference": "5dd3be04f37a857d52880ef6af2524a441dfef24", "shasum": "" }, "require": { "composer/package-versions-deprecated": "^1.10", "composer/semver": "^1.4 || ^2.0 || ^3.0", "ext-simplexml": "*", "php": "^7.1 || ^8.0", "vimeo/psalm": "dev-master || dev-4.x || ^4.5" }, "conflict": { "phpunit/phpunit": "<7.5" }, "require-dev": { "codeception/codeception": "^4.0.3", "php": "^7.3 || ^8.0", "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0", "squizlabs/php_codesniffer": "^3.3.1", "weirdan/codeception-psalm-module": "^0.11.0", "weirdan/prophecy-shim": "^1.0 || ^2.0" }, "type": "psalm-plugin", "extra": { "psalm": { "pluginClass": "Psalm\\PhpUnitPlugin\\Plugin" } }, "autoload": { "psr-4": { "Psalm\\PhpUnitPlugin\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Matt Brown", "email": "github@muglug.com" } ], "description": "Psalm plugin for PHPUnit", "support": { "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues", "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.16.1" }, "time": "2021-06-18T23:56:46+00:00" }, { "name": "psr/cache", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/cache.git", "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", "shasum": "" }, "require": { "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "Psr\\Cache\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "description": "Common interface for caching libraries", "keywords": [ "cache", "psr", "psr-6" ], "support": { "source": "https://github.com/php-fig/cache/tree/master" }, "time": "2016-08-06T20:24:11+00:00" }, { "name": "psr/container", "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", "shasum": "" }, "require": { "php": ">=7.4.0" }, "type": "library", "autoload": { "psr-4": { "Psr\\Container\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", "homepage": "https://github.com/php-fig/container", "keywords": [ "PSR-11", "container", "container-interface", "container-interop", "psr" ], "support": { "issues": "https://github.com/php-fig/container/issues", "source": "https://github.com/php-fig/container/tree/1.1.2" }, "time": "2021-11-05T16:50:12+00:00" }, { "name": "psr/log", "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", "reference": "d49695b909c3b7628b6289db5479a1c204601f11" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", "reference": "d49695b909c3b7628b6289db5479a1c204601f11", "shasum": "" }, "require": { "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1.x-dev" } }, "autoload": { "psr-4": { "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], "support": { "source": "https://github.com/php-fig/log/tree/1.1.4" }, "time": "2021-05-03T11:20:27+00:00" }, { "name": "sebastian/cli-parser", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library for parsing CLI options", "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T06:08:49+00:00" }, { "name": "sebastian/code-unit", "version": "1.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Collection of value objects that represent the PHP code units", "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:08:54+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T05:30:19+00:00" }, { "name": "sebastian/comparator", "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", "reference": "55f4261989e546dc112258c7a75935a81a7ce382" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", "reference": "55f4261989e546dc112258c7a75935a81a7ce382", "shasum": "" }, "require": { "php": ">=7.3", "sebastian/diff": "^4.0", "sebastian/exporter": "^4.0" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" } ], "description": "Provides the functionality to compare PHP values for equality", "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T15:49:45+00:00" }, { "name": "sebastian/complexity", "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", "shasum": "" }, "require": { "nikic/php-parser": "^4.7", "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library for calculating the complexity of PHP code units", "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T15:52:27+00:00" }, { "name": "sebastian/diff", "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3", "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Kore Nordmann", "email": "mail@kore-nordmann.de" } ], "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff", "udiff", "unidiff", "unified diff" ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:10:38+00:00" }, { "name": "sebastian/environment", "version": "5.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", "reference": "388b6ced16caa751030f6a69e588299fa09200ac" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", "reference": "388b6ced16caa751030f6a69e588299fa09200ac", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "suggest": { "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "5.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides functionality to handle HHVM/PHP environments", "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", "hhvm" ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T05:52:38+00:00" }, { "name": "sebastian/exporter", "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { "php": ">=7.3", "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-mbstring": "*", "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Adam Harvey", "email": "aharvey@php.net" }, { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", "shasum": "" }, "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": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "5.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Snapshotting of global state", "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2021-06-11T13:31:12+00:00" }, { "name": "sebastian/lines-of-code", "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", "shasum": "" }, "require": { "nikic/php-parser": "^4.6", "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library for counting the lines of code in PHP source code", "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-28T06:42:11+00:00" }, { "name": "sebastian/object-enumerator", "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", "shasum": "" }, "require": { "php": ">=7.3", "sebastian/object-reflector": "^2.0", "sebastian/recursion-context": "^4.0" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:12:34+00:00" }, { "name": "sebastian/object-reflector", "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:14:26+00:00" }, { "name": "sebastian/recursion-context", "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Adam Harvey", "email": "aharvey@php.net" } ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:17:30+00:00" }, { "name": "sebastian/resource-operations", "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { "issues": "https://github.com/sebastianbergmann/resource-operations/issues", "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T06:45:17+00:00" }, { "name": "sebastian/type", "version": "2.3.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.3-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2021-06-15T12:49:02+00:00" }, { "name": "sebastian/version", "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { "php": ">=7.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T06:39:44+00:00" }, { "name": "slevomat/coding-standard", "version": "7.0.17", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", "reference": "b574727867bc5bba9d28a2a7093fc8ceeda56350" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/b574727867bc5bba9d28a2a7093fc8ceeda56350", "reference": "b574727867bc5bba9d28a2a7093fc8ceeda56350", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", "php": "^7.1 || ^8.0", "phpstan/phpdoc-parser": "^1.0.0", "squizlabs/php_codesniffer": "^3.6.1" }, "require-dev": { "phing/phing": "2.17.0", "php-parallel-lint/php-parallel-lint": "1.3.1", "phpstan/phpstan": "1.2.0", "phpstan/phpstan-deprecation-rules": "1.0.0", "phpstan/phpstan-phpunit": "1.0.0", "phpstan/phpstan-strict-rules": "1.1.0", "phpunit/phpunit": "7.5.20|8.5.21|9.5.10" }, "type": "phpcodesniffer-standard", "extra": { "branch-alias": { "dev-master": "7.x-dev" } }, "autoload": { "psr-4": { "SlevomatCodingStandard\\": "SlevomatCodingStandard" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", "support": { "issues": "https://github.com/slevomat/coding-standard/issues", "source": "https://github.com/slevomat/coding-standard/tree/7.0.17" }, "funding": [ { "url": "https://github.com/kukulich", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", "type": "tidelift" } ], "time": "2021-12-06T22:13:58+00:00" }, { "name": "squizlabs/php_codesniffer", "version": "3.6.1", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", "reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f268ca40d54617c6e06757f83f699775c9b3ff2e", "reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e", "shasum": "" }, "require": { "ext-simplexml": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": ">=5.4.0" }, "require-dev": { "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "bin": [ "bin/phpcs", "bin/phpcbf" ], "type": "library", "extra": { "branch-alias": { "dev-master": "3.x-dev" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Greg Sherwood", "role": "lead" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", "standards" ], "support": { "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", "source": "https://github.com/squizlabs/PHP_CodeSniffer", "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, "time": "2021-10-11T04:00:11+00:00" }, { "name": "symfony/console", "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", "reference": "ec3661faca1d110d6c307e124b44f99ac54179e3" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/console/zipball/ec3661faca1d110d6c307e124b44f99ac54179e3", "reference": "ec3661faca1d110d6c307e124b44f99ac54179e3", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2|^3", "symfony/string": "^5.1|^6.0" }, "conflict": { "psr/log": ">=3", "symfony/dependency-injection": "<4.4", "symfony/dotenv": "<5.1", "symfony/event-dispatcher": "<4.4", "symfony/lock": "<4.4", "symfony/process": "<4.4" }, "provide": { "psr/log-implementation": "1.0|2.0" }, "require-dev": { "psr/log": "^1|^2", "symfony/config": "^4.4|^5.0|^6.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", "symfony/event-dispatcher": "^4.4|^5.0|^6.0", "symfony/lock": "^4.4|^5.0|^6.0", "symfony/process": "^4.4|^5.0|^6.0", "symfony/var-dumper": "^4.4|^5.0|^6.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", "symfony/lock": "", "symfony/process": "" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "keywords": [ "cli", "command line", "console", "terminal" ], "support": { "source": "https://github.com/symfony/console/tree/v5.4.0" }, "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-11-29T15:30:56+00:00" }, { "name": "symfony/deprecation-contracts", "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", "shasum": "" }, "require": { "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", "url": "https://github.com/symfony/contracts" } }, "autoload": { "files": [ "function.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" }, "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-07-12T14:48:14+00:00" }, { "name": "symfony/polyfill-ctype", "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Gert de Pagter", "email": "BackEndTea@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for ctype functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "ctype", "polyfill", "portable" ], "support": { "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" }, "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-intl-grapheme", "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", "reference": "16880ba9c5ebe3642d1995ab866db29270b36535" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/16880ba9c5ebe3642d1995ab866db29270b36535", "reference": "16880ba9c5ebe3642d1995ab866db29270b36535", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Grapheme\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for intl's grapheme_* functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "grapheme", "intl", "polyfill", "portable", "shim" ], "support": { "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.1" }, "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-intl-normalizer", "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, "files": [ "bootstrap.php" ], "classmap": [ "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for intl's Normalizer class and related functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "intl", "normalizer", "polyfill", "portable", "shim" ], "support": { "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.23.0" }, "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-mbstring", "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-mbstring": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", "keywords": [ "compatibility", "mbstring", "polyfill", "portable", "shim" ], "support": { "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" }, "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-php73", "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010", "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010", "shasum": "" }, "require": { "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php73\\": "" }, "files": [ "bootstrap.php" ], "classmap": [ "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "polyfill", "portable", "shim" ], "support": { "source": "https://github.com/symfony/polyfill-php73/tree/v1.23.0" }, "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-php80", "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", "shasum": "" }, "require": { "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php80\\": "" }, "files": [ "bootstrap.php" ], "classmap": [ "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Ion Bazan", "email": "ion.bazan@gmail.com" }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "polyfill", "portable", "shim" ], "support": { "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" }, "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-07-28T13:41:28+00:00" }, { "name": "symfony/service-contracts", "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", "shasum": "" }, "require": { "php": ">=7.2.5", "psr/container": "^1.1", "symfony/deprecation-contracts": "^2.1" }, "conflict": { "ext-psr": "<1.1|>=2" }, "suggest": { "symfony/service-implementation": "" }, "type": "library", "extra": { "branch-alias": { "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", "url": "https://github.com/symfony/contracts" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Generic abstractions related to writing services", "homepage": "https://symfony.com", "keywords": [ "abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards" ], "support": { "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" }, "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-11-04T16:48:04+00:00" }, { "name": "symfony/string", "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", "reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/string/zipball/9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d", "reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "~1.15" }, "conflict": { "symfony/translation-contracts": ">=3.0" }, "require-dev": { "symfony/error-handler": "^4.4|^5.0|^6.0", "symfony/http-client": "^4.4|^5.0|^6.0", "symfony/translation-contracts": "^1.1|^2", "symfony/var-exporter": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\String\\": "" }, "files": [ "Resources/functions.php" ], "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", "homepage": "https://symfony.com", "keywords": [ "grapheme", "i18n", "string", "unicode", "utf-8", "utf8" ], "support": { "source": "https://github.com/symfony/string/tree/v5.4.0" }, "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-11-24T10:02:00+00:00" }, { "name": "theseer/tokenizer", "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", "source": "https://github.com/theseer/tokenizer/tree/1.2.1" }, "funding": [ { "url": "https://github.com/theseer", "type": "github" } ], "time": "2021-07-28T10:34:58+00:00" }, { "name": "vimeo/psalm", "version": "v4.14.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", "reference": "14dcbc908ab2625cd7a74258ee6c740cbecc6140" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/vimeo/psalm/zipball/14dcbc908ab2625cd7a74258ee6c740cbecc6140", "reference": "14dcbc908ab2625cd7a74258ee6c740cbecc6140", "shasum": "" }, "require": { "amphp/amp": "^2.4.2", "amphp/byte-stream": "^1.5", "composer/package-versions-deprecated": "^1.8.0", "composer/semver": "^1.4 || ^2.0 || ^3.0", "composer/xdebug-handler": "^1.1 || ^2.0", "dnoegel/php-xdg-base-dir": "^0.1.1", "ext-ctype": "*", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-simplexml": "*", "ext-tokenizer": "*", "felixfbecker/advanced-json-rpc": "^3.0.3", "felixfbecker/language-server-protocol": "^1.5", "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", "nikic/php-parser": "^4.13", "openlss/lib-array2xml": "^1.0", "php": "^7.1|^8", "sebastian/diff": "^3.0 || ^4.0", "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0 || ^6.0", "webmozart/path-util": "^2.3" }, "provide": { "psalm/psalm": "self.version" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.2", "brianium/paratest": "^4.0||^6.0", "ext-curl": "*", "php-parallel-lint/php-parallel-lint": "^1.2", "phpdocumentor/reflection-docblock": "^5", "phpmyadmin/sql-parser": "5.1.0||dev-master", "phpspec/prophecy": ">=1.9.0", "phpunit/phpunit": "^9.0", "psalm/plugin-phpunit": "^0.16", "slevomat/coding-standard": "^7.0", "squizlabs/php_codesniffer": "^3.5", "symfony/process": "^4.3 || ^5.0 || ^6.0", "weirdan/prophecy-shim": "^1.0 || ^2.0" }, "suggest": { "ext-curl": "In order to send data to shepherd", "ext-igbinary": "^2.0.5 is required, used to serialize caching data" }, "bin": [ "psalm", "psalm-language-server", "psalm-plugin", "psalm-refactor", "psalter" ], "type": "library", "extra": { "branch-alias": { "dev-master": "4.x-dev", "dev-3.x": "3.x-dev", "dev-2.x": "2.x-dev", "dev-1.x": "1.x-dev" } }, "autoload": { "psr-4": { "Psalm\\": "src/Psalm/" }, "files": [ "src/functions.php", "src/spl_object_id.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Matthew Brown" } ], "description": "A static analysis tool for finding errors in PHP applications", "keywords": [ "code", "inspection", "php" ], "support": { "issues": "https://github.com/vimeo/psalm/issues", "source": "https://github.com/vimeo/psalm/tree/v4.14.0" }, "time": "2021-12-04T17:49:24+00:00" }, { "name": "webimpress/coding-standard", "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/webimpress/coding-standard.git", "reference": "7a71421c7fc85827488f10c4c510fe80f94d1a74" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/webimpress/coding-standard/zipball/7a71421c7fc85827488f10c4c510fe80f94d1a74", "reference": "7a71421c7fc85827488f10c4c510fe80f94d1a74", "shasum": "" }, "require": { "php": "^7.3 || ^8.0", "squizlabs/php_codesniffer": "^3.6.1" }, "require-dev": { "phpunit/phpunit": "^9.5.10" }, "type": "phpcodesniffer-standard", "extra": { "dev-master": "1.2.x-dev", "dev-develop": "1.3.x-dev" }, "autoload": { "psr-4": { "WebimpressCodingStandard\\": "src/WebimpressCodingStandard/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-2-Clause" ], "description": "Webimpress Coding Standard", "keywords": [ "Coding Standard", "PSR-2", "phpcs", "psr-12", "webimpress" ], "support": { "issues": "https://github.com/webimpress/coding-standard/issues", "source": "https://github.com/webimpress/coding-standard/tree/1.2.3" }, "funding": [ { "url": "https://github.com/michalbundyra", "type": "github" } ], "time": "2021-10-28T21:18:17+00:00" }, { "name": "webmozart/assert", "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { "phpunit/phpunit": "^8.5.13" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.10-dev" } }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "Assertions to validate method input/output with nice error messages.", "keywords": [ "assert", "check", "validate" ], "support": { "issues": "https://github.com/webmozarts/assert/issues", "source": "https://github.com/webmozarts/assert/tree/1.10.0" }, "time": "2021-03-09T10:59:23+00:00" }, { "name": "webmozart/path-util", "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/webmozart/path-util.git", "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", "shasum": "" }, "require": { "php": ">=5.3.3", "webmozart/assert": "~1.0" }, "require-dev": { "phpunit/phpunit": "^4.6", "sebastian/version": "^1.0.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.3-dev" } }, "autoload": { "psr-4": { "Webmozart\\PathUtil\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", "support": { "issues": "https://github.com/webmozart/path-util/issues", "source": "https://github.com/webmozart/path-util/tree/2.3.0" }, "abandoned": "symfony/filesystem", "time": "2015-12-17T08:42:14+00:00" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { "php": ">=7.4, <8.2" }, "platform-dev": { "ext-phar": "*" }, "platform-overrides": { "php": "7.4.99" }, "plugin-api-version": "2.1.0" } polyfill/ReflectionEnumPolyfill.php000064400000000232144760120040013534 0ustar00= 80100) { return; } /** @internal */ final class ReflectionEnum { public function __construct($enum) { } } src/DeclareStatement.php000064400000004737144760120040011301 0ustar00 'integer', self::STRICT_TYPES => 'integer', self::ENCODING => 'string', ]; protected string $directive; /** @var int|string */ protected $value; /** @param int|string $value */ private function __construct(string $directive, $value) { $this->directive = $directive; $this->value = $value; } public function getDirective(): string { return $this->directive; } /** * @return int|string */ public function getValue() { return $this->value; } public static function ticks(int $value): self { return new self(self::TICKS, $value); } public static function strictTypes(int $value): self { return new self(self::STRICT_TYPES, $value); } public static function encoding(string $value): self { return new self(self::ENCODING, $value); } public static function fromArray(array $config): self { $directive = key($config); $value = $config[$directive]; if (! isset(self::ALLOWED[$directive])) { throw new InvalidArgumentException( sprintf( 'Declare directive must be one of: %s.', implode(', ', array_keys(self::ALLOWED)) ) ); } if (gettype($value) !== self::ALLOWED[$directive]) { throw new InvalidArgumentException( sprintf( 'Declare value invalid. Expected %s, got %s.', self::ALLOWED[$directive], gettype($value) ) ); } $method = str_replace('_', '', lcfirst(ucwords($directive, '_'))); return self::{$method}($value); } public function getStatement(): string { $value = is_string($this->value) ? '\'' . $this->value . '\'' : $this->value; return sprintf('declare(%s=%s);', $this->directive, $value); } } src/Exception/BadMethodCallException.php000064400000000215144760120040014300 0ustar00setOptions($options); } } /** * @param bool $isSourceDirty * @return AbstractGenerator */ public function setSourceDirty($isSourceDirty = true) { $this->isSourceDirty = (bool) $isSourceDirty; return $this; } /** * @return bool */ public function isSourceDirty() { return $this->isSourceDirty; } /** * @param string $indentation * @return AbstractGenerator */ public function setIndentation($indentation) { $this->indentation = (string) $indentation; return $this; } /** * @return string */ public function getIndentation() { return $this->indentation; } /** * @param ?string $sourceContent * @return AbstractGenerator */ public function setSourceContent($sourceContent) { $this->sourceContent = (string) $sourceContent; return $this; } /** * @return ?string */ public function getSourceContent() { return $this->sourceContent; } /** * @param array|Traversable $options * @throws Exception\InvalidArgumentException * @return AbstractGenerator */ public function setOptions($options) { if (! is_array($options) && ! $options instanceof Traversable) { throw new Exception\InvalidArgumentException(sprintf( '%s expects an array or Traversable object; received "%s"', __METHOD__, is_object($options) ? get_class($options) : gettype($options) )); } foreach ($options as $optionName => $optionValue) { $methodName = 'set' . $optionName; if (method_exists($this, $methodName)) { $this->{$methodName}($optionValue); } } return $this; } } src/Generator/AbstractMemberGenerator.php000064400000013027144760120040014535 0ustar00flags = $flags; return $this; } /** * @param int $flag * @return AbstractMemberGenerator */ public function addFlag($flag) { $this->setFlags($this->flags | $flag); return $this; } /** * @param int $flag * @return AbstractMemberGenerator */ public function removeFlag($flag) { $this->setFlags($this->flags & ~$flag); return $this; } /** * @param bool $isAbstract * @return AbstractMemberGenerator */ public function setAbstract($isAbstract) { return $isAbstract ? $this->addFlag(self::FLAG_ABSTRACT) : $this->removeFlag(self::FLAG_ABSTRACT); } /** * @return bool */ public function isAbstract() { return (bool) ($this->flags & self::FLAG_ABSTRACT); } /** * @param bool $isInterface * @return AbstractMemberGenerator */ public function setInterface($isInterface) { return $isInterface ? $this->addFlag(self::FLAG_INTERFACE) : $this->removeFlag(self::FLAG_INTERFACE); } /** * @return bool */ public function isInterface() { return (bool) ($this->flags & self::FLAG_INTERFACE); } /** * @param bool $isFinal * @return AbstractMemberGenerator */ public function setFinal($isFinal) { return $isFinal ? $this->addFlag(self::FLAG_FINAL) : $this->removeFlag(self::FLAG_FINAL); } /** * @return bool */ public function isFinal() { return (bool) ($this->flags & self::FLAG_FINAL); } /** * @param bool $isStatic * @return AbstractMemberGenerator */ public function setStatic($isStatic) { return $isStatic ? $this->addFlag(self::FLAG_STATIC) : $this->removeFlag(self::FLAG_STATIC); } /** * @return bool */ public function isStatic() { return (bool) ($this->flags & self::FLAG_STATIC); // is FLAG_STATIC in flags } /** * @param string $visibility * @return AbstractMemberGenerator */ public function setVisibility($visibility) { switch ($visibility) { case self::VISIBILITY_PUBLIC: $this->removeFlag(self::FLAG_PRIVATE | self::FLAG_PROTECTED); // remove both $this->addFlag(self::FLAG_PUBLIC); break; case self::VISIBILITY_PROTECTED: $this->removeFlag(self::FLAG_PUBLIC | self::FLAG_PRIVATE); // remove both $this->addFlag(self::FLAG_PROTECTED); break; case self::VISIBILITY_PRIVATE: $this->removeFlag(self::FLAG_PUBLIC | self::FLAG_PROTECTED); // remove both $this->addFlag(self::FLAG_PRIVATE); break; } return $this; } /** * @psalm-return static::VISIBILITY_* */ public function getVisibility() { switch (true) { case $this->flags & self::FLAG_PROTECTED: return self::VISIBILITY_PROTECTED; case $this->flags & self::FLAG_PRIVATE: return self::VISIBILITY_PRIVATE; default: return self::VISIBILITY_PUBLIC; } } /** * @param string $name * @return AbstractMemberGenerator */ public function setName($name) { $this->name = (string) $name; return $this; } /** * @return string */ public function getName() { return $this->name; } /** * @param DocBlockGenerator|string $docBlock * @throws Exception\InvalidArgumentException * @return AbstractMemberGenerator */ public function setDocBlock($docBlock) { if (is_string($docBlock)) { $docBlock = new DocBlockGenerator($docBlock); } elseif (! $docBlock instanceof DocBlockGenerator) { throw new Exception\InvalidArgumentException(sprintf( '%s is expecting either a string, array or an instance of %s\DocBlockGenerator', __METHOD__, __NAMESPACE__ )); } $this->docBlock = $docBlock; return $this; } public function removeDocBlock(): void { $this->docBlock = null; } /** * @return DocBlockGenerator|null */ public function getDocBlock() { return $this->docBlock; } } src/Generator/BodyGenerator.php000064400000001055144760120040012535 0ustar00content = (string) $content; return $this; } /** * @return string */ public function getContent() { return $this->content; } /** * @return string */ public function generate() { return $this->getContent(); } } src/Generator/ClassGenerator.php000064400000075211144760120040012712 0ustar00 */ protected array $implementedInterfaces = []; /** @var PropertyGenerator[] */ protected array $properties = []; /** @var PropertyGenerator[] */ protected array $constants = []; /** @var MethodGenerator[] */ protected array $methods = []; /** @var TraitUsageGenerator Object to encapsulate trait usage logic */ protected TraitUsageGenerator $traitUsageGenerator; /** * Build a Code Generation Php Object from a Class Reflection * * @return static */ public static function fromReflection(ClassReflection $classReflection) { $cg = new static($classReflection->getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock())); } $cg->setAbstract($classReflection->isAbstract()); // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } $parentClass = $classReflection->getParentClass(); $interfaces = $classReflection->getInterfaces(); if ($parentClass) { $cg->setExtendedClass($parentClass->getName()); $interfaces = array_diff($interfaces, $parentClass->getInterfaces()); } $interfaceNames = []; foreach ($interfaces as $interface) { $interfaceNames[] = $interface->getName(); } $cg->setImplementedInterfaces($interfaceNames); $properties = []; foreach ($classReflection->getProperties() as $reflectionProperty) { if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) { $properties[] = PropertyGenerator::fromReflection($reflectionProperty); } } $cg->addProperties($properties); $constants = []; foreach ($classReflection->getReflectionConstants() as $constReflection) { $constants[] = [ 'name' => $constReflection->getName(), 'value' => $constReflection->getValue(), 'isFinal' => method_exists($constReflection, 'isFinal') ? $constReflection->isFinal() : false, ]; } $cg->addConstants($constants); $methods = []; foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getName(); $namespaceName = $cg->getNamespaceName(); if ($namespaceName !== null) { $className = $namespaceName . '\\' . $className; } if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $method = MethodGenerator::fromReflection($reflectionMethod); if (self::CONSTRUCTOR_NAME === strtolower($method->getName())) { foreach ($method->getParameters() as $parameter) { if ($parameter instanceof PromotedParameterGenerator) { $cg->removeProperty($parameter->getName()); } } } $methods[] = $method; } } $cg->addMethods($methods); return $cg; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey filegenerator FileGenerator File generator that holds this class * @configkey namespacename string The namespace for this class * @configkey docblock string The docblock information * @configkey flags int Flags, one of ClassGenerator::FLAG_ABSTRACT ClassGenerator::FLAG_FINAL * @configkey extendedclass string Class which this class is extending * @configkey implementedinterfaces * @configkey properties * @configkey methods * @throws Exception\InvalidArgumentException * @param array $array * @return static */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Class generator requires that a name is provided for this object' ); } $cg = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'containingfile': $cg->setContainingFileGenerator($value); break; case 'namespacename': $cg->setNamespaceName($value); break; case 'docblock': $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value); $cg->setDocBlock($docBlock); break; case 'flags': $cg->setFlags($value); break; case 'extendedclass': $cg->setExtendedClass($value); break; case 'implementedinterfaces': $cg->setImplementedInterfaces($value); break; case 'properties': $cg->addProperties($value); break; case 'methods': $cg->addMethods($value); break; } } return $cg; } /** * @param string $name * @param string $namespaceName * @param int|int[]|null $flags * @param class-string|null $extends * @param string[] $interfaces * @psalm-param array $interfaces * @param PropertyGenerator[]|string[]|array[] $properties * @param MethodGenerator[]|string[]|array[] $methods * @param DocBlockGenerator $docBlock */ public function __construct( $name = null, $namespaceName = null, $flags = null, $extends = null, array $interfaces = [], array $properties = [], array $methods = [], $docBlock = null ) { $this->traitUsageGenerator = new TraitUsageGenerator($this); if ($name !== null) { $this->setName($name); } if ($namespaceName !== null) { $this->setNamespaceName($namespaceName); } if ($flags !== null) { $this->setFlags($flags); } if ($properties !== []) { $this->addProperties($properties); } if ($extends !== null) { $this->setExtendedClass($extends); } if ($interfaces !== []) { $this->setImplementedInterfaces($interfaces); } if ($methods !== []) { $this->addMethods($methods); } if ($docBlock !== null) { $this->setDocBlock($docBlock); } } /** * @param string $name * @return static */ public function setName($name) { if (false !== strpos($name, '\\')) { $namespace = substr($name, 0, strrpos($name, '\\')); $name = substr($name, strrpos($name, '\\') + 1); $this->setNamespaceName($namespace); } $this->name = $name; return $this; } /** * @return string */ public function getName() { return $this->name; } /** * @param ?string $namespaceName * @return static */ public function setNamespaceName($namespaceName) { $this->namespaceName = $namespaceName; return $this; } /** * @return ?string */ public function getNamespaceName() { return $this->namespaceName; } /** * @return static */ public function setContainingFileGenerator(FileGenerator $fileGenerator) { $this->containingFileGenerator = $fileGenerator; return $this; } /** * @return ?FileGenerator */ public function getContainingFileGenerator() { return $this->containingFileGenerator; } /** * @return static */ public function setDocBlock(DocBlockGenerator $docBlock) { $this->docBlock = $docBlock; return $this; } /** * @return ?DocBlockGenerator */ public function getDocBlock() { return $this->docBlock; } /** * @param int[]|int $flags * @return static */ public function setFlags($flags) { if (is_array($flags)) { $flagsArray = $flags; $flags = 0x00; foreach ($flagsArray as $flag) { $flags |= $flag; } } // check that visibility is one of three $this->flags = $flags; return $this; } /** * @param int $flag * @return static */ public function addFlag($flag) { $this->setFlags($this->flags | $flag); return $this; } /** * @param int $flag * @return static */ public function removeFlag($flag) { $this->setFlags($this->flags & ~$flag); return $this; } /** * @param bool $isAbstract * @return static */ public function setAbstract($isAbstract) { return $isAbstract ? $this->addFlag(self::FLAG_ABSTRACT) : $this->removeFlag(self::FLAG_ABSTRACT); } /** * @return bool */ public function isAbstract() { return (bool) ($this->flags & self::FLAG_ABSTRACT); } /** * @param bool $isFinal * @return static */ public function setFinal($isFinal) { return $isFinal ? $this->addFlag(self::FLAG_FINAL) : $this->removeFlag(self::FLAG_FINAL); } /** * @return bool */ public function isFinal() { return (bool) ($this->flags & self::FLAG_FINAL); } /** * @param ?string $extendedClass * @psalm-param ?class-string $extendedClass * @return static */ public function setExtendedClass($extendedClass) { $this->extendedClass = $extendedClass; return $this; } /** * @return ?string * @psalm-return ?class-string */ public function getExtendedClass() { return $this->extendedClass; } /** * @return bool */ public function hasExtentedClass() { return ! empty($this->extendedClass); } /** * @return static */ public function removeExtentedClass() { $this->setExtendedClass(null); return $this; } /** * @param string[] $implementedInterfaces * @psalm-param array $implementedInterfaces * @return static */ public function setImplementedInterfaces(array $implementedInterfaces) { $this->implementedInterfaces = $implementedInterfaces; return $this; } /** * @return string[] * @psalm-return array */ public function getImplementedInterfaces() { return $this->implementedInterfaces; } /** * @param string $implementedInterface * @psalm-param class-string $implementedInterface * @return bool */ public function hasImplementedInterface($implementedInterface) { $interfaceType = TypeGenerator::fromTypeString($implementedInterface); return (bool) array_filter( array_map([TypeGenerator::class, 'fromTypeString'], $this->implementedInterfaces), static fn (TypeGenerator $interface): bool => $interfaceType->equals($interface) ); } /** * @param string $implementedInterface * @psalm-param class-string $implementedInterface * @return static */ public function removeImplementedInterface($implementedInterface) { $interfaceType = TypeGenerator::fromTypeString($implementedInterface); $this->implementedInterfaces = array_filter( $this->implementedInterfaces, static fn (string $interface): bool => ! TypeGenerator::fromTypeString($interface)->equals($interfaceType) ); return $this; } /** * @param string $constantName * @return PropertyGenerator|false */ public function getConstant($constantName) { if (isset($this->constants[$constantName])) { return $this->constants[$constantName]; } return false; } /** * @return PropertyGenerator[] indexed by constant name */ public function getConstants() { return $this->constants; } /** * @param string $constantName * @return static */ public function removeConstant($constantName) { unset($this->constants[$constantName]); return $this; } /** * @param string $constantName * @return bool */ public function hasConstant($constantName) { return isset($this->constants[$constantName]); } /** * Add constant from PropertyGenerator * * @throws Exception\InvalidArgumentException * @return static */ public function addConstantFromGenerator(PropertyGenerator $constant) { $constantName = $constant->getName(); if (isset($this->constants[$constantName])) { throw new Exception\InvalidArgumentException(sprintf( 'A constant by name %s already exists in this class.', $constantName )); } if (! $constant->isConst()) { throw new Exception\InvalidArgumentException(sprintf( 'The value %s is not defined as a constant.', $constantName )); } $this->constants[$constantName] = $constant; return $this; } /** * Add Constant * * @param string $name Non-empty string * @param string|int|null|float|array $value Scalar * @throws Exception\InvalidArgumentException * @return static */ public function addConstant($name, $value, bool $isFinal = false) { if (empty($name) || ! is_string($name)) { throw new Exception\InvalidArgumentException(sprintf( '%s expects string for name', __METHOD__ )); } $this->validateConstantValue($value); return $this->addConstantFromGenerator( new PropertyGenerator( $name, new PropertyValueGenerator($value), $isFinal ? PropertyGenerator::FLAG_CONSTANT | PropertyGenerator::FLAG_FINAL : PropertyGenerator::FLAG_CONSTANT ) ); } /** * @param PropertyGenerator[]|array[] $constants * @return static */ public function addConstants(array $constants) { foreach ($constants as $constant) { if ($constant instanceof PropertyGenerator) { $this->addPropertyFromGenerator($constant); } else { if (is_array($constant)) { $this->addConstant(...array_values($constant)); } } } return $this; } /** * @param PropertyGenerator[]|string[]|array[] $properties * @return static */ public function addProperties(array $properties) { foreach ($properties as $property) { if ($property instanceof PropertyGenerator) { $this->addPropertyFromGenerator($property); } elseif (is_string($property)) { $this->addProperty($property); } else { $this->addProperty(...array_values($property)); } } return $this; } /** * Add Property from scalars * * @param string $name * @param string|array $defaultValue * @param int $flags * @throws Exception\InvalidArgumentException * @return static */ public function addProperty($name, $defaultValue = null, $flags = PropertyGenerator::FLAG_PUBLIC) { if (! is_string($name)) { throw new Exception\InvalidArgumentException(sprintf( '%s::%s expects string for name', static::class, __FUNCTION__ )); } // backwards compatibility // @todo remove this on next major version if ($flags === PropertyGenerator::FLAG_CONSTANT) { return $this->addConstant($name, $defaultValue); } return $this->addPropertyFromGenerator(new PropertyGenerator($name, $defaultValue, $flags)); } /** * Add property from PropertyGenerator * * @throws Exception\InvalidArgumentException * @return static */ public function addPropertyFromGenerator(PropertyGenerator $property) { $propertyName = $property->getName(); if (isset($this->properties[$propertyName])) { throw new Exception\InvalidArgumentException(sprintf( 'A property by name %s already exists in this class.', $propertyName )); } // backwards compatibility // @todo remove this on next major version if ($property->isConst()) { return $this->addConstantFromGenerator($property); } $this->properties[$propertyName] = $property; return $this; } /** * @return PropertyGenerator[] */ public function getProperties() { return $this->properties; } /** * @param string $propertyName * @return PropertyGenerator|false */ public function getProperty($propertyName) { foreach ($this->getProperties() as $property) { if ($property->getName() == $propertyName) { return $property; } } return false; } /** * Add a class to "use" classes * * @param string $use * @param string|null $useAlias * @return static */ public function addUse($use, $useAlias = null) { $this->traitUsageGenerator->addUse($use, $useAlias); return $this; } /** * @param string $use * @return bool */ public function hasUse($use) { return $this->traitUsageGenerator->hasUse($use); } /** * @param string $use * @return static */ public function removeUse($use) { $this->traitUsageGenerator->removeUse($use); return $this; } /** * @param string $use * @return bool */ public function hasUseAlias($use) { return $this->traitUsageGenerator->hasUseAlias($use); } /** * @param string $use * @return static */ public function removeUseAlias($use) { $this->traitUsageGenerator->removeUseAlias($use); return $this; } /** * Returns the "use" classes * * @return array */ public function getUses() { return $this->traitUsageGenerator->getUses(); } /** * @param string $propertyName * @return static */ public function removeProperty($propertyName) { unset($this->properties[$propertyName]); return $this; } /** * @param string $propertyName * @return bool */ public function hasProperty($propertyName) { return isset($this->properties[$propertyName]); } /** * @param MethodGenerator[]|string[]|array[] $methods * @return static */ public function addMethods(array $methods) { foreach ($methods as $method) { if ($method instanceof MethodGenerator) { $this->addMethodFromGenerator($method); } elseif (is_string($method)) { $this->addMethod($method); } else { $this->addMethod(...array_values($method)); } } return $this; } /** * Add Method from scalars * * @param string $name * @param ParameterGenerator[]|array[]|string[] $parameters * @param int $flags * @param string $body * @param string $docBlock * @throws Exception\InvalidArgumentException * @return static */ public function addMethod( $name, array $parameters = [], $flags = MethodGenerator::FLAG_PUBLIC, $body = null, $docBlock = null ) { if (! is_string($name)) { throw new Exception\InvalidArgumentException(sprintf( '%s::%s expects string for name', static::class, __FUNCTION__ )); } return $this->addMethodFromGenerator(new MethodGenerator($name, $parameters, $flags, $body, $docBlock)); } /** * Add Method from MethodGenerator * * @throws Exception\InvalidArgumentException * @return static */ public function addMethodFromGenerator(MethodGenerator $method) { $methodName = $method->getName(); if ($this->hasMethod($methodName)) { throw new Exception\InvalidArgumentException(sprintf( 'A method by name %s already exists in this class.', $methodName )); } if (self::CONSTRUCTOR_NAME !== strtolower($methodName)) { foreach ($method->getParameters() as $parameter) { if ($parameter instanceof PromotedParameterGenerator) { throw new Exception\InvalidArgumentException( 'Promoted parameter can only be added to constructor.' ); } } } $this->methods[strtolower($methodName)] = $method; return $this; } /** * @return MethodGenerator[] */ public function getMethods() { return $this->methods; } /** * @param string $methodName * @return MethodGenerator|false */ public function getMethod($methodName) { return $this->hasMethod($methodName) ? $this->methods[strtolower($methodName)] : false; } /** * @param string $methodName * @return static */ public function removeMethod($methodName) { unset($this->methods[strtolower($methodName)]); return $this; } /** * @param string $methodName * @return bool */ public function hasMethod($methodName) { return isset($this->methods[strtolower($methodName)]); } /** * @inheritDoc */ public function addTrait($trait) { $this->traitUsageGenerator->addTrait($trait); return $this; } /** * @inheritDoc */ public function addTraits(array $traits) { $this->traitUsageGenerator->addTraits($traits); return $this; } /** * @inheritDoc */ public function hasTrait($traitName) { return $this->traitUsageGenerator->hasTrait($traitName); } /** * @inheritDoc */ public function getTraits() { return $this->traitUsageGenerator->getTraits(); } /** * @inheritDoc */ public function removeTrait($traitName) { return $this->traitUsageGenerator->removeTrait($traitName); } /** * @inheritDoc */ public function addTraitAlias($method, $alias, $visibility = null) { $this->traitUsageGenerator->addTraitAlias($method, $alias, $visibility); return $this; } /** * @inheritDoc */ public function getTraitAliases() { return $this->traitUsageGenerator->getTraitAliases(); } /** * @inheritDoc */ public function addTraitOverride($method, $traitsToReplace) { $this->traitUsageGenerator->addTraitOverride($method, $traitsToReplace); return $this; } /** * @inheritDoc */ public function removeTraitOverride($method, $overridesToRemove = null) { $this->traitUsageGenerator->removeTraitOverride($method, $overridesToRemove); return $this; } /** * @inheritDoc */ public function getTraitOverrides() { return $this->traitUsageGenerator->getTraitOverrides(); } /** * @return bool */ public function isSourceDirty() { if (($docBlock = $this->getDocBlock()) && $docBlock->isSourceDirty()) { return true; } foreach ($this->getProperties() as $property) { if ($property->isSourceDirty()) { return true; } } foreach ($this->getMethods() as $method) { if ($method->isSourceDirty()) { return true; } } return parent::isSourceDirty(); } /** * @inheritDoc */ public function generate() { if (! $this->isSourceDirty()) { $output = $this->getSourceContent(); if (! empty($output)) { return $output; } } $indent = $this->getIndentation(); $output = ''; if (null !== ($namespace = $this->getNamespaceName())) { $output .= 'namespace ' . $namespace . ';' . self::LINE_FEED . self::LINE_FEED; } $uses = $this->getUses(); if (! empty($uses)) { foreach ($uses as $use) { $output .= 'use ' . $use . ';' . self::LINE_FEED; } $output .= self::LINE_FEED; } if (null !== ($docBlock = $this->getDocBlock())) { $docBlock->setIndentation(''); $output .= $docBlock->generate(); } if ($this->isAbstract()) { $output .= 'abstract '; } elseif ($this->isFinal()) { $output .= 'final '; } $output .= static::OBJECT_TYPE . ' ' . $this->getName(); if (! empty($this->extendedClass)) { $output .= ' extends ' . $this->generateShortOrCompleteClassname($this->extendedClass); } $implemented = $this->getImplementedInterfaces(); if (! empty($implemented)) { $implemented = array_map([$this, 'generateShortOrCompleteClassname'], $implemented); $output .= ' ' . static::IMPLEMENTS_KEYWORD . ' ' . implode(', ', $implemented); } $output .= self::LINE_FEED . '{' . self::LINE_FEED; $traitUseOutput = rtrim($this->traitUsageGenerator->generate(), self::LINE_FEED); $constants = []; $properties = []; $methods = []; foreach ($this->getConstants() as $constant) { $constants[] = $constant->generate(); } foreach ($this->getProperties() as $property) { $properties[] = $property->generate(); } foreach ($this->getMethods() as $method) { $methods[] = $method->generate(); } $contents = rtrim( implode( self::LINE_FEED . self::LINE_FEED, array_filter([ $traitUseOutput, implode(self::LINE_FEED . self::LINE_FEED, $constants), implode(self::LINE_FEED . self::LINE_FEED, $properties), implode(self::LINE_FEED, $methods), ]) ), self::LINE_FEED ); return $output . $contents . ($contents === '' ? '' : self::LINE_FEED) . '}' . self::LINE_FEED; } /** * @param mixed $value * @return void * @throws Exception\InvalidArgumentException */ private function validateConstantValue($value) { if (null === $value || is_scalar($value)) { return; } if (is_array($value)) { array_walk($value, [$this, 'validateConstantValue']); return; } throw new Exception\InvalidArgumentException(sprintf( 'Expected value for constant, value must be a "scalar" or "null", "%s" found', gettype($value) )); } /** * @param string $fqnClassName * @return string */ private function generateShortOrCompleteClassname($fqnClassName) { $fqnClassName = ltrim($fqnClassName, '\\'); $parts = explode('\\', $fqnClassName); $className = array_pop($parts); $classNamespace = implode('\\', $parts); $currentNamespace = (string) $this->getNamespaceName(); if ($this->hasUseAlias($fqnClassName)) { return $this->traitUsageGenerator->getUseAlias($fqnClassName); } if ($this->hasUseAlias($classNamespace)) { $namespaceAlias = $this->traitUsageGenerator->getUseAlias($classNamespace); return $namespaceAlias . '\\' . $className; } if ($this->traitUsageGenerator->isUseAlias($fqnClassName)) { return $fqnClassName; } if ($this->traitUsageGenerator->isUseAlias($classNamespace)) { return $fqnClassName; } if ($classNamespace === $currentNamespace || in_array($fqnClassName, $this->getUses())) { return $className; } return '\\' . $fqnClassName; } } src/Generator/DocBlock/Tag.php000064400000002151144760120040012162 0ustar00initializeDefaultTags(); return $tagManager->createTagFromReflection($reflectionTag); } /** * @deprecated Deprecated in 2.3. Use GenericTag::setContent() instead * * @param string $description * @return Tag */ public function setDescription($description) { return $this->setContent($description); } /** * @deprecated Deprecated in 2.3. Use GenericTag::getContent() instead * * @return string */ public function getDescription() { return $this->getContent(); } } src/Generator/DocBlock/Tag/AbstractTypeableTag.php000064400000003546144760120040016060 0ustar00setTypes($types); } if (! empty($description)) { $this->setDescription($description); } } /** * @param string $description * @return AbstractTypeableTag */ public function setDescription($description) { $this->description = $description; return $this; } /** * @return string */ public function getDescription() { return $this->description; } /** * Array of types or string with types delimited by pipe (|) * e.g. array('int', 'null') or "int|null" * * @param array|string $types * @return AbstractTypeableTag */ public function setTypes($types) { if (is_string($types)) { $types = explode('|', $types); } $this->types = $types; return $this; } /** * @return array */ public function getTypes() { return $this->types; } /** * @param string $delimiter * @return string */ public function getTypesAsString($delimiter = '|') { return implode($delimiter, $this->types); } } src/Generator/DocBlock/Tag/AuthorTag.php000064400000004161144760120040014063 0ustar00setAuthorName($authorName); } if (! empty($authorEmail)) { $this->setAuthorEmail($authorEmail); } } /** * @deprecated Deprecated in 2.3. Use TagManager::createTagFromReflection() instead * * @return AuthorTag */ public static function fromReflection(ReflectionTagInterface $reflectionTag) { $tagManager = new TagManager(); $tagManager->initializeDefaultTags(); return $tagManager->createTagFromReflection($reflectionTag); } /** * @return string */ public function getName() { return 'author'; } /** * @param string $authorEmail * @return AuthorTag */ public function setAuthorEmail($authorEmail) { $this->authorEmail = $authorEmail; return $this; } /** * @return string */ public function getAuthorEmail() { return $this->authorEmail; } /** * @param string $authorName * @return AuthorTag */ public function setAuthorName($authorName) { $this->authorName = $authorName; return $this; } /** * @return string */ public function getAuthorName() { return $this->authorName; } /** * @return string */ public function generate() { return '@author' . (! empty($this->authorName) ? ' ' . $this->authorName : '') . (! empty($this->authorEmail) ? ' <' . $this->authorEmail . '>' : ''); } } src/Generator/DocBlock/Tag/GenericTag.php000064400000002660144760120040014177 0ustar00setName($name); } if (! empty($content)) { $this->setContent($content); } } /** * @param string $name * @return GenericTag */ public function setName($name) { $this->name = ltrim($name, '@'); return $this; } /** * @return string */ public function getName() { return $this->name; } /** * @param string $content * @return GenericTag */ public function setContent($content) { $this->content = $content; return $this; } /** * @return string */ public function getContent() { return $this->content; } /** * @return string */ public function generate() { return '@' . $this->name . (! empty($this->content) ? ' ' . $this->content : ''); } } src/Generator/DocBlock/Tag/LicenseTag.php000064400000003762144760120040014211 0ustar00setUrl($url); } if (! empty($licenseName)) { $this->setLicenseName($licenseName); } } /** * @deprecated Deprecated in 2.3. Use TagManager::createTagFromReflection() instead * * @return ReturnTag */ public static function fromReflection(ReflectionTagInterface $reflectionTag) { $tagManager = new TagManager(); $tagManager->initializeDefaultTags(); return $tagManager->createTagFromReflection($reflectionTag); } /** * @return string */ public function getName() { return 'license'; } /** * @param string $url * @return LicenseTag */ public function setUrl($url) { $this->url = $url; return $this; } /** * @return string */ public function getUrl() { return $this->url; } /** * @param string $name * @return LicenseTag */ public function setLicenseName($name) { $this->licenseName = $name; return $this; } /** * @return string */ public function getLicenseName() { return $this->licenseName; } /** * @return string */ public function generate() { return '@license' . (! empty($this->url) ? ' ' . $this->url : '') . (! empty($this->licenseName) ? ' ' . $this->licenseName : ''); } } src/Generator/DocBlock/Tag/MethodTag.php000064400000003443144760120040014043 0ustar00setMethodName($methodName); } $this->setIsStatic((bool) $isStatic); parent::__construct($types, $description); } /** * @return string */ public function getName() { return 'method'; } /** * @param bool $isStatic * @return MethodTag */ public function setIsStatic($isStatic) { $this->isStatic = $isStatic; return $this; } /** * @return bool */ public function isStatic() { return $this->isStatic; } /** * @param string $methodName * @return MethodTag */ public function setMethodName($methodName) { $this->methodName = rtrim($methodName, ')('); return $this; } /** * @return string */ public function getMethodName() { return $this->methodName; } /** * @return string */ public function generate() { return '@method' . ($this->isStatic ? ' static' : '') . (! empty($this->types) ? ' ' . $this->getTypesAsString() : '') . (! empty($this->methodName) ? ' ' . $this->methodName . '()' : '') . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/Tag/ParamTag.php000064400000005332144760120040013662 0ustar00setVariableName($variableName); } parent::__construct($types, $description); } /** * @deprecated Deprecated in 2.3. Use TagManager::createTagFromReflection() instead * * @return ParamTag */ public static function fromReflection(ReflectionTagInterface $reflectionTag) { $tagManager = new TagManager(); $tagManager->initializeDefaultTags(); return $tagManager->createTagFromReflection($reflectionTag); } /** * @return string */ public function getName() { return 'param'; } /** * @param string $variableName * @return ParamTag */ public function setVariableName($variableName) { $this->variableName = ltrim($variableName, '$'); return $this; } /** * @return string */ public function getVariableName() { return $this->variableName; } /** * @deprecated Deprecated in 2.3. Use setTypes() instead * * @param string $datatype * @return ParamTag */ public function setDatatype($datatype) { return $this->setTypes($datatype); } /** * @deprecated Deprecated in 2.3. Use getTypes() or getTypesAsString() instead * * @return string */ public function getDatatype() { return $this->getTypesAsString(); } /** * @deprecated Deprecated in 2.3. Use setVariableName() instead * * @param string $paramName * @return ParamTag */ public function setParamName($paramName) { return $this->setVariableName($paramName); } /** * @deprecated Deprecated in 2.3. Use getVariableName() instead * * @return string */ public function getParamName() { return $this->getVariableName(); } /** * @return string */ public function generate() { return '@param' . (! empty($this->types) ? ' ' . $this->getTypesAsString() : '') . (! empty($this->variableName) ? ' $' . $this->variableName : '') . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/Tag/PropertyTag.php000064400000002513144760120040014444 0ustar00setPropertyName($propertyName); } parent::__construct($types, $description); } /** * @return string */ public function getName() { return 'property'; } /** * @param string $propertyName * @return self */ public function setPropertyName($propertyName) { $this->propertyName = ltrim($propertyName, '$'); return $this; } /** * @return string */ public function getPropertyName() { return $this->propertyName; } /** * @return string */ public function generate() { return '@property' . (! empty($this->types) ? ' ' . $this->getTypesAsString() : '') . (! empty($this->propertyName) ? ' $' . $this->propertyName : '') . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/Tag/ReturnTag.php000064400000002614144760120040014101 0ustar00initializeDefaultTags(); return $tagManager->createTagFromReflection($reflectionTag); } /** * @return string */ public function getName() { return 'return'; } /** * @deprecated Deprecated in 2.3. Use setTypes() instead * * @param string $datatype * @return ReturnTag */ public function setDatatype($datatype) { return $this->setTypes($datatype); } /** * @deprecated Deprecated in 2.3. Use getTypes() or getTypesAsString() instead * * @return string */ public function getDatatype() { return $this->getTypesAsString(); } /** * @return string */ public function generate() { return '@return ' . $this->getTypesAsString() . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/Tag/TagInterface.php000064400000000245144760120040014520 0ustar00types) ? ' ' . $this->getTypesAsString() : '') . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/Tag/VarTag.php000064400000002640144760120040013351 0ustar00variableName = ltrim($variableName, '$'); } parent::__construct($types, $description); } /** * {@inheritDoc} */ public function getName(): string { return 'var'; } /** * @internal this code is only public for compatibility with the * * @see \Laminas\Code\Generator\DocBlock\TagManager, which * uses setters */ public function setVariableName(?string $variableName): void { if (null !== $variableName) { $this->variableName = ltrim($variableName, '$'); } } public function getVariableName(): ?string { return $this->variableName; } /** * {@inheritDoc} */ public function generate(): string { return '@var' . (! empty($this->types) ? ' ' . $this->getTypesAsString() : '') . (null !== $this->variableName ? ' $' . $this->variableName : '') . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/TagManager.php000064400000004624144760120040013464 0ustar00addPrototype(new Tag\ParamTag()); $this->addPrototype(new Tag\ReturnTag()); $this->addPrototype(new Tag\MethodTag()); $this->addPrototype(new Tag\PropertyTag()); $this->addPrototype(new Tag\AuthorTag()); $this->addPrototype(new Tag\LicenseTag()); $this->addPrototype(new Tag\ThrowsTag()); $this->addPrototype(new Tag\VarTag()); $this->setGenericPrototype(new Tag\GenericTag()); } /** * @return TagInterface */ public function createTagFromReflection(ReflectionTagInterface $reflectionTag) { $tagName = $reflectionTag->getName(); /** @var TagInterface $newTag */ $newTag = $this->getClonedPrototype($tagName); // transport any properties via accessors and mutators from reflection to codegen object $reflectionClass = new ReflectionClass($reflectionTag); foreach ($reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { if (0 === strpos($method->getName(), 'get')) { $propertyName = substr($method->getName(), 3); if (method_exists($newTag, 'set' . $propertyName)) { $newTag->{'set' . $propertyName}($reflectionTag->{'get' . $propertyName}()); } } elseif (0 === strpos($method->getName(), 'is')) { $propertyName = ucfirst($method->getName()); if (method_exists($newTag, 'set' . $propertyName)) { $newTag->{'set' . $propertyName}($reflectionTag->{$method->getName()}()); } } } return $newTag; } } src/Generator/DocBlockGenerator.php000064400000015262144760120040013325 0ustar00setSourceContent($reflectionDocBlock->getContents()); $docBlock->setSourceDirty(false); $docBlock->setShortDescription($reflectionDocBlock->getShortDescription()); $docBlock->setLongDescription($reflectionDocBlock->getLongDescription()); foreach ($reflectionDocBlock->getTags() as $tag) { $docBlock->setTag(self::getTagManager()->createTagFromReflection($tag)); } return $docBlock; } /** * Generate from array * * @configkey shortdescription string The short description for this doc block * @configkey longdescription string The long description for this doc block * @configkey tags array * @throws Exception\InvalidArgumentException * @param array $array * @return DocBlockGenerator */ public static function fromArray(array $array) { $docBlock = new static(); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'shortdescription': $docBlock->setShortDescription($value); break; case 'longdescription': $docBlock->setLongDescription($value); break; case 'tags': $docBlock->setTags($value); break; } } return $docBlock; } /** * @return TagManager */ protected static function getTagManager() { if (! isset(static::$tagManager)) { static::$tagManager = new TagManager(); static::$tagManager->initializeDefaultTags(); } return static::$tagManager; } /** * @param ?string $shortDescription * @param ?string $longDescription * @param array[]|TagInterface[] $tags */ public function __construct($shortDescription = null, $longDescription = null, array $tags = []) { if ($shortDescription) { $this->setShortDescription($shortDescription); } if ($longDescription) { $this->setLongDescription($longDescription); } if ($tags) { $this->setTags($tags); } } /** * @param string $shortDescription * @return DocBlockGenerator */ public function setShortDescription($shortDescription) { $this->shortDescription = $shortDescription; return $this; } /** * @return string */ public function getShortDescription() { return $this->shortDescription; } /** * @param string $longDescription * @return DocBlockGenerator */ public function setLongDescription($longDescription) { $this->longDescription = $longDescription; return $this; } /** * @return string */ public function getLongDescription() { return $this->longDescription; } /** * @param array[]|TagInterface[] $tags * @return DocBlockGenerator */ public function setTags(array $tags) { foreach ($tags as $tag) { $this->setTag($tag); } return $this; } /** * @param array|TagInterface $tag * @throws Exception\InvalidArgumentException * @return DocBlockGenerator */ public function setTag($tag) { if (is_array($tag)) { // use deprecated Tag class for backward compatibility to old array-keys $genericTag = new Tag(); $genericTag->setOptions($tag); $tag = $genericTag; } elseif (! $tag instanceof TagInterface) { throw new Exception\InvalidArgumentException(sprintf( '%s expects either an array of method options or an instance of %s\DocBlock\Tag\TagInterface', __METHOD__, __NAMESPACE__ )); } $this->tags[] = $tag; return $this; } /** * @return TagInterface[] */ public function getTags() { return $this->tags; } /** * @param bool $value * @return DocBlockGenerator */ public function setWordWrap($value) { $this->wordwrap = (bool) $value; return $this; } /** * @return bool */ public function getWordWrap() { return $this->wordwrap; } /** * @return string */ public function generate() { if (! $this->isSourceDirty()) { return $this->docCommentize(trim($this->getSourceContent() ?? '')); } $output = ''; if ($sd = $this->getShortDescription()) { $output .= $sd . self::LINE_FEED . self::LINE_FEED; } if ($ld = $this->getLongDescription()) { $output .= $ld . self::LINE_FEED . self::LINE_FEED; } /** @var GeneratorInterface $tag */ foreach ($this->getTags() as $tag) { $output .= $tag->generate() . self::LINE_FEED; } return $this->docCommentize(trim($output)); } /** * @param string $content * @return string */ protected function docCommentize($content) { $indent = $this->getIndentation(); $output = $indent . '/**' . self::LINE_FEED; $content = $this->getWordWrap() == true ? wordwrap($content, 80, self::LINE_FEED) : $content; $lines = explode(self::LINE_FEED, $content); foreach ($lines as $line) { $output .= $indent . ' *'; if ($line) { $output .= ' ' . $line; } $output .= self::LINE_FEED; } $output .= $indent . ' */' . self::LINE_FEED; return $output; } } src/Generator/EnumGenerator/Cases/BackedCases.php000064400000002660144760120040015735 0ustar00 */ private array $cases; /** * @param list $cases */ private function __construct(string $type, array $cases) { $this->type = $type; $this->cases = $cases; } public function getBackedType(): string { return $this->type; } /** * @return list */ public function getCases(): array { return $this->cases; } /** * @param array|array $backedCases */ public static function fromCasesWithType(array $backedCases, string $type): self { if (in_array($type, ['int', 'string']) === false) { throw new InvalidArgumentException(sprintf( '"%s" is not a valid type for Enums, only "int" and "string" types are allowed.', $type )); } $cases = []; foreach ($backedCases as $case => $value) { if ($type === 'string') { $value = sprintf("'%s'", $value); } $cases[] = $case . ' = ' . $value; } return new self($type, $cases); } } src/Generator/EnumGenerator/Cases/CaseFactory.php000064400000004117144760120040016007 0ustar00, * }|array{ * name: non-empty-string, * backedCases: array{ * type: 'int', * cases: array, * }|array{ * type: 'string', * cases: array, * }, * } $options * @return BackedCases|PureCases */ public static function fromOptions(array $options) { if (array_key_exists('pureCases', $options) && ! array_key_exists('backedCases', $options)) { return PureCases::fromCases($options['pureCases']); } assert(! array_key_exists('pureCases', $options) && array_key_exists('backedCases', $options)); return BackedCases::fromCasesWithType($options['backedCases']['cases'], $options['backedCases']['type']); } /** * @return BackedCases|PureCases */ public static function fromReflectionCases(ReflectionEnum $enum) { if (PHP_VERSION_ID < 80100) { throw new InvalidArgumentException('This feature only works from PHP 8.1 onwards.'); } $backingType = $enum->getBackingType(); if ($backingType === null) { $callback = static fn(ReflectionEnumUnitCase $singleCase): string => $singleCase->getName(); $pureCases = array_map($callback, $enum->getCases()); return PureCases::fromCases($pureCases); } $backedCases = []; foreach ($enum->getCases() as $singleCase) { $backedCases[$singleCase->getName()] = $singleCase->getBackingValue(); } return BackedCases::fromCasesWithType($backedCases, $backingType->getName()); } } src/Generator/EnumGenerator/Cases/PureCases.php000064400000001207144760120040015473 0ustar00 */ private array $cases; /** * @param list $cases */ private function __construct(array $cases) { $this->cases = $cases; } /** * @return list */ public function getCases(): array { return $this->cases; } /** * @param list $pureCases */ public static function fromCases(array $pureCases): self { return new self($pureCases); } } src/Generator/EnumGenerator/EnumGenerator.php000064400000005316144760120040015323 0ustar00name = $name; $this->cases = $cases; } public function generate(): string { $output = ''; if (null !== $this->name->getNamespace()) { $output .= 'namespace ' . $this->name->getNamespace() . ';' . self::LINE_FEED . self::LINE_FEED; } return $output . 'enum ' . $this->name->getName() . $this->retrieveType() . ' {' . self::LINE_FEED . $this->retrieveCases() . '}' . self::LINE_FEED; } private function retrieveType(): string { if ($this->cases instanceof PureCases) { return ''; } return ': ' . $this->cases->getBackedType(); } private function retrieveCases(): string { return implode( '', array_map( fn (string $case): string => self::INDENTATION . 'case ' . $case . ';' . self::LINE_FEED, $this->cases->getCases() ) ); } /** * @psalm-param array{ * name: non-empty-string, * pureCases: list, * }|array{ * name: non-empty-string, * backedCases: array{ * type: 'int'|'string', * cases: array, * }, * } $options */ public static function withConfig(array $options): self { return new self( Name::fromFullyQualifiedClassName($options['name']), CaseFactory::fromOptions($options), ); } public static function fromReflection(ReflectionEnum $enum): self { if (PHP_VERSION_ID < 80100) { throw new InvalidArgumentException('This feature only works from PHP 8.1 onwards.'); } return new self( Name::fromFullyQualifiedClassName($enum->getName()), CaseFactory::fromReflectionCases($enum), ); } } src/Generator/EnumGenerator/Name.php000064400000001617144760120040013430 0ustar00name = $name; $this->namespace = $namespace; } public function getName(): string { return $this->name; } public function getNamespace(): ?string { return $this->namespace; } public static function fromFullyQualifiedClassName(string $name): self { $namespace = null; $nsPosition = strrpos($name, '\\'); if (false !== $nsPosition) { $namespace = substr($name, 0, $nsPosition); $name = substr($name, $nsPosition + 1); } return new self($name, $namespace); } } src/Generator/Exception/ClassNotFoundException.php000064400000000220144760120040016321 0ustar00 */ protected array $uses = []; /** * @var ClassGenerator[] * @psalm-var array */ protected array $classes = []; protected string $body = ''; /** * @var DeclareStatement[] * @psalm-var array */ protected array $declares = []; /** * Passes $options to {@link setOptions()}. * * @param array|Traversable|null $options */ public function __construct($options = null) { if (null !== $options) { $this->setOptions($options); } } /** * @param array $values * @return FileGenerator */ public static function fromArray(array $values) { $fileGenerator = new static(); foreach ($values as $name => $value) { switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'filename': $fileGenerator->setFilename($value); break; case 'class': $fileGenerator->setClass( $value instanceof ClassGenerator ? $value : ClassGenerator::fromArray($value) ); break; case 'requiredfiles': $fileGenerator->setRequiredFiles($value); break; case 'declares': $fileGenerator->setDeclares( array_map(static fn($directive, $value) => DeclareStatement::fromArray([$directive => $value]), array_keys($value), $value) ); break; default: if (property_exists($fileGenerator, $name)) { $fileGenerator->{$name} = $value; } elseif (method_exists($fileGenerator, 'set' . $name)) { $fileGenerator->{'set' . $name}($value); } } } return $fileGenerator; } /** * @param DocBlockGenerator|array|string $docBlock * @throws Exception\InvalidArgumentException * @return FileGenerator */ public function setDocBlock($docBlock) { if (is_string($docBlock)) { $docBlock = ['shortDescription' => $docBlock]; } if (is_array($docBlock)) { $docBlock = new DocBlockGenerator($docBlock); } elseif (! $docBlock instanceof DocBlockGenerator) { throw new Exception\InvalidArgumentException(sprintf( '%s is expecting either a string, array or an instance of %s\DocBlockGenerator', __METHOD__, __NAMESPACE__ )); } $this->docBlock = $docBlock; return $this; } /** * @return ?DocBlockGenerator */ public function getDocBlock() { return $this->docBlock; } /** * @param string[] $requiredFiles * @return FileGenerator */ public function setRequiredFiles(array $requiredFiles) { $this->requiredFiles = $requiredFiles; return $this; } /** * @return string[] */ public function getRequiredFiles() { return $this->requiredFiles; } /** * @return string */ public function getNamespace() { return $this->namespace; } /** * @param string $namespace * @return FileGenerator */ public function setNamespace($namespace) { $this->namespace = (string) $namespace; return $this; } /** * Returns an array with the first element the use statement, second is the as part. * If $withResolvedAs is set to true, there will be a third element that is the * "resolved" as statement, as the second part is not required in use statements * * @param bool $withResolvedAs * @return array * @psalm-return array */ public function getUses($withResolvedAs = false) { $uses = $this->uses; if ($withResolvedAs) { for ($useIndex = 0, $count = count($uses); $useIndex < $count; $useIndex++) { if ($uses[$useIndex][1] == '') { if (($lastSeparator = strrpos($uses[$useIndex][0], '\\')) !== false) { $uses[$useIndex][2] = substr($uses[$useIndex][0], $lastSeparator + 1); } else { $uses[$useIndex][2] = $uses[$useIndex][0]; } } else { $uses[$useIndex][2] = $uses[$useIndex][1]; } } } return $uses; } /** * @param array $uses * @return FileGenerator */ public function setUses(array $uses) { foreach ($uses as $use) { $use = (array) $use; if (array_key_exists('use', $use) && array_key_exists('as', $use)) { $import = $use['use']; $alias = $use['as']; } elseif (count($use) == 2) { [$import, $alias] = $use; } else { $import = current($use); $alias = null; } $this->setUse($import, $alias); } return $this; } /** * @param string $use * @param null|string $as * @return FileGenerator */ public function setUse($use, $as = null) { if (! in_array([$use, $as], $this->uses)) { $this->uses[] = [$use, $as]; } return $this; } /** * @param array[]|string[]|ClassGenerator[] $classes * @return FileGenerator */ public function setClasses(array $classes) { foreach ($classes as $class) { $this->setClass($class); } return $this; } /** * @param string|null $name * @return ClassGenerator * @throws ClassNotFoundException */ public function getClass($name = null) { if ($name === null) { reset($this->classes); $class = current($this->classes); if (false === $class) { throw new ClassNotFoundException('No class is set'); } return $class; } if (false === array_key_exists($name, $this->classes)) { throw new ClassNotFoundException(sprintf('Class %s is not set', $name)); } return $this->classes[$name]; } /** * @param array|string|ClassGenerator $class * @throws Exception\InvalidArgumentException * @return FileGenerator */ public function setClass($class) { if (is_array($class)) { $class = ClassGenerator::fromArray($class); } elseif (is_string($class)) { $class = new ClassGenerator($class); } elseif (! $class instanceof ClassGenerator) { throw new Exception\InvalidArgumentException(sprintf( '%s is expecting either a string, array or an instance of %s\ClassGenerator', __METHOD__, __NAMESPACE__ )); } // @todo check for dup here $className = $class->getName(); $this->classes[$className] = $class; return $this; } /** * @param string $filename * @return FileGenerator */ public function setFilename($filename) { $this->filename = (string) $filename; return $this; } /** * @return string */ public function getFilename() { return $this->filename; } /** * @return ClassGenerator[] */ public function getClasses() { return $this->classes; } /** * @param string $body * @return FileGenerator */ public function setBody($body) { $this->body = (string) $body; return $this; } /** * @return string */ public function getBody() { return $this->body; } /** * @param DeclareStatement[] $declares * @return static */ public function setDeclares(array $declares) { foreach ($declares as $declare) { if (! $declare instanceof DeclareStatement) { throw new InvalidArgumentException(sprintf( '%s is expecting an array of %s objects', __METHOD__, DeclareStatement::class )); } if (! array_key_exists($declare->getDirective(), $this->declares)) { $this->declares[$declare->getDirective()] = $declare; } } return $this; } /** * @return bool */ public function isSourceDirty() { $docBlock = $this->getDocBlock(); if ($docBlock && $docBlock->isSourceDirty()) { return true; } foreach ($this->classes as $class) { if ($class->isSourceDirty()) { return true; } } return parent::isSourceDirty(); } /** * @return string */ public function generate() { if ($this->isSourceDirty() === false) { return $this->sourceContent ?? ''; } $output = ''; // @note body gets populated when FileGenerator created // from a file. @see fromReflection and may also be set // via FileGenerator::setBody $body = $this->getBody(); // start with the body (if there), or open tag if (preg_match('#(?:\s*)<\?php#', $body) == false) { $output = 'getDocBlock())) { $docBlock->setIndentation(''); if (preg_match('#/\* Laminas_Code_Generator_FileGenerator-DocBlockMarker \*/#m', $output)) { // @codingStandardsIgnoreStart $output = preg_replace('#/\* Laminas_Code_Generator_FileGenerator-DocBlockMarker \*/#m', $docBlock->generate(), $output, 1); // @codingStandardsIgnoreEnd } else { $output .= $docBlock->generate() . self::LINE_FEED; } } // newline $output .= self::LINE_FEED; // declares, if any if ($this->declares) { $declareStatements = ''; foreach ($this->declares as $declare) { $declareStatements .= $declare->getStatement() . self::LINE_FEED; } if (preg_match('#/\* Laminas_Code_Generator_FileGenerator-DeclaresMarker \*/#m', $output)) { $output = preg_replace( '#/\* Laminas_Code_Generator_FileGenerator-DeclaresMarker \*/#m', $declareStatements, $output, 1 ); } else { $output .= $declareStatements; } $output .= self::LINE_FEED; } // namespace, if any $namespace = $this->getNamespace(); if ($namespace) { $namespace = sprintf('namespace %s;%s', $namespace, str_repeat(self::LINE_FEED, 2)); if (preg_match('#/\* Laminas_Code_Generator_FileGenerator-NamespaceMarker \*/#m', $output)) { $output = preg_replace( '#/\* Laminas_Code_Generator_FileGenerator-NamespaceMarker \*/#m', $namespace, $output, 1 ); } else { $output .= $namespace; } } // process required files // @todo marker replacement for required files $requiredFiles = $this->getRequiredFiles(); if (! empty($requiredFiles)) { foreach ($requiredFiles as $requiredFile) { $output .= 'require_once \'' . $requiredFile . '\';' . self::LINE_FEED; } $output .= self::LINE_FEED; } $classes = $this->getClasses(); $classUses = []; //build uses array foreach ($classes as $class) { //check for duplicate use statements $uses = $class->getUses(); if (! empty($uses) && is_array($uses)) { $classUses = array_merge($classUses, $uses); } } // process import statements $uses = $this->getUses(); if (! empty($uses)) { $useOutput = ''; foreach ($uses as $use) { [$import, $alias] = $use; if (null === $alias) { $tempOutput = sprintf('%s', $import); } else { $tempOutput = sprintf('%s as %s', $import, $alias); } //don't duplicate use statements if (! in_array($tempOutput, $classUses)) { $useOutput .= 'use ' . $tempOutput . ';'; $useOutput .= self::LINE_FEED; } } $useOutput .= self::LINE_FEED; if (preg_match('#/\* Laminas_Code_Generator_FileGenerator-UseMarker \*/#m', $output)) { $output = preg_replace( '#/\* Laminas_Code_Generator_FileGenerator-UseMarker \*/#m', $useOutput, $output, 1 ); } else { $output .= $useOutput; } } // process classes if (! empty($classes)) { foreach ($classes as $class) { // @codingStandardsIgnoreStart $regex = str_replace('&', $class->getName(), '/\* Laminas_Code_Generator_Php_File-ClassMarker: \{[A-Za-z0-9\\\]+?&\} \*/'); // @codingStandardsIgnoreEnd if (preg_match('#' . $regex . '#m', $output)) { $output = preg_replace('#' . $regex . '#', $class->generate(), $output, 1); } else { if ($namespace) { $class->setNamespaceName(null); } $output .= $class->generate() . self::LINE_FEED; } } } if (! empty($body)) { // add an extra space between classes and if (! empty($classes)) { $output .= self::LINE_FEED; } $output .= $body; } return $output; } /** * @return FileGenerator * @throws Exception\RuntimeException */ public function write() { if ($this->filename == '' || ! is_writable(dirname($this->filename))) { throw new Exception\RuntimeException('This code generator object is not writable.'); } file_put_contents($this->filename, $this->generate()); return $this; } } src/Generator/GeneratorInterface.php000064400000000205144760120040013534 0ustar00isInterface()) { throw new Exception\InvalidArgumentException(sprintf( 'Class %s is not a interface', $classReflection->getName() )); } // class generator $cg = new static($classReflection->getName()); $methods = []; $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock())); } // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getName(); $namespaceName = $cg->getNamespaceName(); if ($namespaceName !== null) { $className = $namespaceName . '\\' . $className; } if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } foreach ($classReflection->getConstants() as $name => $value) { $cg->addConstant($name, $value); } $cg->addMethods($methods); return $cg; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey filegenerator FileGenerator File generator that holds this class * @configkey namespacename string The namespace for this class * @configkey docblock string The docblock information * @configkey constants * @configkey methods * @throws Exception\InvalidArgumentException * @param array $array * @return static */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Class generator requires that a name is provided for this object' ); } $cg = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'containingfile': $cg->setContainingFileGenerator($value); break; case 'namespacename': $cg->setNamespaceName($value); break; case 'docblock': $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value); $cg->setDocBlock($docBlock); break; case 'methods': $cg->addMethods($value); break; case 'constants': $cg->addConstants($value); break; } } return $cg; } /** * {@inheritDoc} */ public function addPropertyFromGenerator(PropertyGenerator $property) { return $this; } /** * {@inheritDoc} */ public function addMethodFromGenerator(MethodGenerator $method) { $method->setInterface(true); return parent::addMethodFromGenerator($method); } /** * {@inheritDoc} */ public function setExtendedClass($extendedClass) { return $this; } /** * {@inheritDoc} */ public function setAbstract($isAbstract) { return $this; } } src/Generator/MethodGenerator.php000064400000026443144760120040013070 0ustar00setSourceContent($reflectionMethod->getContents(false)); $method->setSourceDirty(false); if ($reflectionMethod->getDocComment() != '') { $method->setDocBlock(DocBlockGenerator::fromReflection($reflectionMethod->getDocBlock())); } $method->setBody(static::clearBodyIndention($reflectionMethod->getBody())); return $method; } /** * Returns a MethodGenerator based on a MethodReflection with only the signature copied. * * This is similar to fromReflection() but without the method body and phpdoc as this is quite heavy to copy. * It's for example useful when creating proxies where you normally change the method body anyway. */ public static function copyMethodSignature(MethodReflection $reflectionMethod): MethodGenerator { $method = new static(); $declaringClass = $reflectionMethod->getDeclaringClass(); $method->returnType = TypeGenerator::fromReflectionType($reflectionMethod->getReturnType(), $declaringClass); $method->setFinal($reflectionMethod->isFinal()); if ($reflectionMethod->isPrivate()) { $method->setVisibility(self::VISIBILITY_PRIVATE); } elseif ($reflectionMethod->isProtected()) { $method->setVisibility(self::VISIBILITY_PROTECTED); } else { $method->setVisibility(self::VISIBILITY_PUBLIC); } $method->setInterface($declaringClass->isInterface()); $method->setStatic($reflectionMethod->isStatic()); $method->setReturnsReference($reflectionMethod->returnsReference()); $method->setName($reflectionMethod->getName()); foreach ($reflectionMethod->getParameters() as $reflectionParameter) { $method->setParameter( $reflectionParameter->isPromoted() ? PromotedParameterGenerator::fromReflection($reflectionParameter) : ParameterGenerator::fromReflection($reflectionParameter) ); } return $method; } /** * Identify the space indention from the first line and remove this indention * from all lines * * @param string $body * @return string */ protected static function clearBodyIndention($body) { if (empty($body)) { return $body; } $lines = explode("\n", $body); $indention = str_replace(trim($lines[1]), '', $lines[1]); foreach ($lines as $key => $line) { if (substr($line, 0, strlen($indention)) == $indention) { $lines[$key] = substr($line, strlen($indention)); } } $body = implode("\n", $lines); return $body; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey docblock string The DocBlock information * @configkey flags int Flags, one of self::FLAG_ABSTRACT, self::FLAG_FINAL * @configkey parameters string Class which this class is extending * @configkey body string * @configkey returntype string * @configkey returnsreference bool * @configkey abstract bool * @configkey final bool * @configkey static bool * @configkey visibility string * @throws Exception\InvalidArgumentException * @param array $array * @return MethodGenerator */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Method generator requires that a name is provided for this object' ); } $method = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'docblock': $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value); $method->setDocBlock($docBlock); break; case 'flags': $method->setFlags($value); break; case 'parameters': $method->setParameters($value); break; case 'body': $method->setBody($value); break; case 'abstract': $method->setAbstract($value); break; case 'final': $method->setFinal($value); break; case 'interface': $method->setInterface($value); break; case 'static': $method->setStatic($value); break; case 'visibility': $method->setVisibility($value); break; case 'returntype': $method->setReturnType($value); break; case 'returnsreference': $method->setReturnsReference((bool) $value); } } return $method; } /** * @param ?string $name * @param ParameterGenerator[]|array[]|string[] $parameters * @param int|int[] $flags * @param ?string $body * @param DocBlockGenerator|string|null $docBlock */ public function __construct( $name = null, array $parameters = [], $flags = self::FLAG_PUBLIC, $body = null, $docBlock = null ) { if ($name) { $this->setName($name); } if ($parameters) { $this->setParameters($parameters); } if ($flags !== self::FLAG_PUBLIC) { $this->setFlags($flags); } if ($body) { $this->setBody($body); } if ($docBlock) { $this->setDocBlock($docBlock); } } /** * @param ParameterGenerator[]|array[]|string[] $parameters * @return MethodGenerator */ public function setParameters(array $parameters) { foreach ($parameters as $parameter) { $this->setParameter($parameter); } $this->sortParameters(); return $this; } /** * @param ParameterGenerator|array|string $parameter * @throws Exception\InvalidArgumentException * @return MethodGenerator */ public function setParameter($parameter) { if (is_string($parameter)) { $parameter = new ParameterGenerator($parameter); } if (is_array($parameter)) { $parameter = ParameterGenerator::fromArray($parameter); } if (! $parameter instanceof ParameterGenerator) { throw new Exception\InvalidArgumentException(sprintf( '%s is expecting either a string, array or an instance of %s\ParameterGenerator', __METHOD__, __NAMESPACE__ )); } $this->parameters[$parameter->getName()] = $parameter; $this->sortParameters(); return $this; } /** * @return ParameterGenerator[] */ public function getParameters() { return $this->parameters; } /** * @param string $body * @return MethodGenerator */ public function setBody($body) { $this->body = $body; return $this; } /** * @return string */ public function getBody() { return $this->body; } /** * @param string|null $returnType * @return MethodGenerator */ public function setReturnType($returnType = null) { $this->returnType = null === $returnType ? null : TypeGenerator::fromTypeString($returnType); return $this; } /** * @return TypeGenerator|null */ public function getReturnType() { return $this->returnType; } /** * @param bool $returnsReference * @return MethodGenerator */ public function setReturnsReference($returnsReference) { $this->returnsReference = (bool) $returnsReference; return $this; } public function returnsReference(): bool { return $this->returnsReference; } /** * Sort parameters by their position */ private function sortParameters(): void { uasort( $this->parameters, static fn(ParameterGenerator $item1, ParameterGenerator $item2) => $item1->getPosition() <=> $item2->getPosition() ); } /** * @return string */ public function generate() { $output = ''; $indent = $this->getIndentation(); if (($docBlock = $this->getDocBlock()) !== null) { $docBlock->setIndentation($indent); $output .= $docBlock->generate(); } $output .= $indent; if ($this->isAbstract()) { $output .= 'abstract '; } else { $output .= $this->isFinal() ? 'final ' : ''; } $output .= $this->getVisibility() . ($this->isStatic() ? ' static' : '') . ' function ' . ($this->returnsReference ? '& ' : '') . $this->getName() . '('; $parameters = $this->getParameters(); if (! empty($parameters)) { foreach ($parameters as $parameter) { $parameterOutput[] = $parameter->generate(); } $output .= implode(', ', $parameterOutput); } $output .= ')'; if ($this->returnType) { $output .= ' : ' . $this->returnType->generate(); } if ($this->isAbstract()) { return $output . ';'; } if ($this->isInterface()) { return $output . ';'; } $output .= self::LINE_FEED . $indent . '{' . self::LINE_FEED; if ($this->body) { $output .= preg_replace('#^((?![a-zA-Z0-9_-]+;).+?)$#m', $indent . $indent . '$1', trim($this->body)) . self::LINE_FEED; } $output .= $indent . '}' . self::LINE_FEED; return $output; } /** @return string */ public function __toString() { return $this->generate(); } } src/Generator/ParameterGenerator.php000064400000017712144760120040013567 0ustar00setName($reflectionParameter->getName()); $param->type = TypeGenerator::fromReflectionType( $reflectionParameter->getType(), $reflectionParameter->getDeclaringClass() ); $param->setPosition($reflectionParameter->getPosition()); $variadic = $reflectionParameter->isVariadic(); $param->setVariadic($variadic); if (! $variadic && ($reflectionParameter->isOptional() || $reflectionParameter->isDefaultValueAvailable())) { try { $param->setDefaultValue($reflectionParameter->getDefaultValue()); } catch (ReflectionException $e) { $param->setDefaultValue(null); } } $param->setPassedByReference($reflectionParameter->isPassedByReference()); return $param; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey type string * @configkey defaultvalue null|bool|string|int|float|array|ValueGenerator * @configkey passedbyreference bool * @configkey position int * @configkey sourcedirty bool * @configkey indentation string * @configkey sourcecontent string * @configkey omitdefaultvalue bool * @throws Exception\InvalidArgumentException * @param array $array * @return ParameterGenerator */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Parameter generator requires that a name is provided for this object' ); } $param = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'type': $param->setType($value); break; case 'defaultvalue': $param->setDefaultValue($value); break; case 'passedbyreference': $param->setPassedByReference($value); break; case 'position': $param->setPosition($value); break; case 'sourcedirty': $param->setSourceDirty($value); break; case 'indentation': $param->setIndentation($value); break; case 'sourcecontent': $param->setSourceContent($value); break; case 'omitdefaultvalue': $param->omitDefaultValue($value); break; } } return $param; } /** * @param ?string $name * @param ?string $type * @param ?mixed $defaultValue * @param ?int $position * @param bool $passByReference */ public function __construct( $name = null, $type = null, $defaultValue = null, $position = null, $passByReference = false ) { if (null !== $name) { $this->setName($name); } if (null !== $type) { $this->setType($type); } if (null !== $defaultValue) { $this->setDefaultValue($defaultValue); } if (null !== $position) { $this->setPosition($position); } if (false !== $passByReference) { $this->setPassedByReference(true); } } /** * @param string $type * @return ParameterGenerator */ public function setType($type) { $this->type = TypeGenerator::fromTypeString($type); return $this; } /** * @return string */ public function getType() { return $this->type ? $this->type->__toString() : null; } /** * @param string $name * @return ParameterGenerator */ public function setName($name) { $this->name = (string) $name; return $this; } /** * @return string */ public function getName() { return $this->name; } /** * Set the default value of the parameter. * * Certain variables are difficult to express * * @param null|bool|string|int|float|array|ValueGenerator $defaultValue * @return ParameterGenerator */ public function setDefaultValue($defaultValue) { if ($this->variadic) { throw new Exception\InvalidArgumentException('Variadic parameter cannot have a default value'); } if (! $defaultValue instanceof ValueGenerator) { $defaultValue = new ValueGenerator($defaultValue); } $this->defaultValue = $defaultValue; return $this; } /** * @return ?ValueGenerator */ public function getDefaultValue() { return $this->defaultValue; } /** * @param int $position * @return ParameterGenerator */ public function setPosition($position) { $this->position = (int) $position; return $this; } /** * @return int */ public function getPosition() { return $this->position; } /** * @return bool */ public function getPassedByReference() { return $this->passedByReference; } /** * @param bool $passedByReference * @return ParameterGenerator */ public function setPassedByReference($passedByReference) { $this->passedByReference = (bool) $passedByReference; return $this; } /** * @param bool $variadic * @return ParameterGenerator */ public function setVariadic($variadic) { if (isset($this->defaultValue)) { throw new Exception\InvalidArgumentException('Variadic parameter cannot have a default value'); } $this->variadic = (bool) $variadic; return $this; } /** * @return bool */ public function getVariadic() { return $this->variadic; } /** * @return string */ public function generate() { $output = $this->generateTypeHint(); if (true === $this->passedByReference) { $output .= '&'; } if ($this->variadic) { $output .= '... '; } $output .= '$' . $this->name; if ($this->omitDefaultValue) { return $output; } if ($this->defaultValue instanceof ValueGenerator) { $output .= ' = '; $this->defaultValue->setOutputMode(ValueGenerator::OUTPUT_SINGLE_LINE); $output .= $this->defaultValue; } return $output; } /** * @return string */ private function generateTypeHint() { if (null === $this->type) { return ''; } return $this->type->generate() . ' '; } /** * @return ParameterGenerator */ public function omitDefaultValue(bool $omit = true) { $this->omitDefaultValue = $omit; return $this; } } src/Generator/PromotedParameterGenerator.php000064400000005503144760120040015274 0ustar00visibility = $visibility; } /** @psalm-return non-empty-string */ public function generate(): string { return $this->visibility . ' ' . parent::generate(); } public static function fromReflection(ParameterReflection $reflectionParameter): self { if (! $reflectionParameter->isPromoted()) { throw new RuntimeException( sprintf('Can not create "%s" from unprompted reflection.', self::class) ); } $visibility = self::VISIBILITY_PUBLIC; if ($reflectionParameter->isProtectedPromoted()) { $visibility = self::VISIBILITY_PROTECTED; } elseif ($reflectionParameter->isPrivatePromoted()) { $visibility = self::VISIBILITY_PRIVATE; } return self::fromParameterGeneratorWithVisibility( parent::fromReflection($reflectionParameter), $visibility ); } /** @psalm-param PromotedParameterGenerator::VISIBILITY_* $visibility */ public static function fromParameterGeneratorWithVisibility(ParameterGenerator $generator, string $visibility): self { $name = $generator->getName(); $type = $generator->getType(); if ('' === $name) { throw new \Laminas\Code\Generator\Exception\RuntimeException( 'Name of promoted parameter must be non-empty-string.' ); } if ('' === $type) { throw new \Laminas\Code\Generator\Exception\RuntimeException( 'Type of promoted parameter must be non-empty-string.' ); } return new self( $name, $type, $visibility, $generator->getPosition(), $generator->getPassedByReference() ); } } src/Generator/PropertyGenerator.php000064400000022337144760120040013472 0ustar00setName($reflectionProperty->getName()); $allDefaultProperties = $reflectionProperty->getDeclaringClass()->getDefaultProperties(); $defaultValue = $allDefaultProperties[$reflectionProperty->getName()] ?? null; $property->setDefaultValue($defaultValue); if ($defaultValue === null) { $property->omitDefaultValue = true; } if ($reflectionProperty->getDocComment() != '') { $property->setDocBlock(DocBlockGenerator::fromReflection($reflectionProperty->getDocBlock())); } if ($reflectionProperty->isStatic()) { $property->setStatic(true); } if (method_exists($reflectionProperty, 'isReadonly') && $reflectionProperty->isReadonly()) { $property->setReadonly(true); } if ($reflectionProperty->isPrivate()) { $property->setVisibility(self::VISIBILITY_PRIVATE); } elseif ($reflectionProperty->isProtected()) { $property->setVisibility(self::VISIBILITY_PROTECTED); } else { $property->setVisibility(self::VISIBILITY_PUBLIC); } $property->setSourceDirty(false); return $property; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey const bool * @configkey defaultvalue null|bool|string|int|float|array|ValueGenerator * @configkey flags int * @configkey abstract bool * @configkey final bool * @configkey static bool * @configkey visibility string * @configkey omitdefaultvalue bool * @configkey readonly bool * @throws Exception\InvalidArgumentException * @param array $array * @return static */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Property generator requires that a name is provided for this object' ); } $property = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'const': $property->setConst($value); break; case 'defaultvalue': $property->setDefaultValue($value); break; case 'docblock': $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value); $property->setDocBlock($docBlock); break; case 'flags': $property->setFlags($value); break; case 'abstract': $property->setAbstract($value); break; case 'final': $property->setFinal($value); break; case 'static': $property->setStatic($value); break; case 'visibility': $property->setVisibility($value); break; case 'omitdefaultvalue': $property->omitDefaultValue($value); break; case 'readonly': if (! is_bool($value)) { throw new Exception\InvalidArgumentException(sprintf( '%s is expecting boolean on key %s. Got %s', __METHOD__, $name, is_object($value) ? get_class($value) : gettype($value) )); } $property->setReadonly($value); break; } } return $property; } /** * @param PropertyValueGenerator|string|array|null $defaultValue * @param int|int[] $flags */ public function __construct(?string $name = null, $defaultValue = null, $flags = self::FLAG_PUBLIC) { parent::__construct(); if (null !== $name) { $this->setName($name); } if (null !== $defaultValue) { $this->setDefaultValue($defaultValue); } if ($flags !== self::FLAG_PUBLIC) { $this->setFlags($flags); } } /** * @param bool $const * @return PropertyGenerator */ public function setConst($const) { if (true === $const) { $this->setFlags(self::FLAG_CONSTANT); return $this; } $this->removeFlag(self::FLAG_CONSTANT); return $this; } /** * @return bool */ public function isConst() { return (bool) ($this->flags & self::FLAG_CONSTANT); } public function setReadonly(bool $readonly): self { if (true === $readonly) { $this->setFlags(self::FLAG_READONLY); return $this; } $this->removeFlag(self::FLAG_READONLY); return $this; } public function isReadonly(): bool { return (bool) ($this->flags & self::FLAG_READONLY); } /** * {@inheritDoc} */ public function setFlags($flags) { $flags = array_reduce((array) $flags, static function (int $a, int $b): int { return $a | $b; }, 0); if ($flags & self::FLAG_READONLY && $flags & self::FLAG_STATIC) { throw new Exception\RuntimeException('Modifier "readonly" in combination with "static" not permitted.'); } if ($flags & self::FLAG_READONLY && $flags & self::FLAG_CONSTANT) { throw new Exception\RuntimeException('Modifier "readonly" in combination with "constant" not permitted.'); } return parent::setFlags($flags); } /** * @param PropertyValueGenerator|mixed $defaultValue * @param string $defaultValueType * @param string $defaultValueOutputMode * @return static */ public function setDefaultValue( $defaultValue, $defaultValueType = PropertyValueGenerator::TYPE_AUTO, $defaultValueOutputMode = PropertyValueGenerator::OUTPUT_MULTIPLE_LINE ) { if (! $defaultValue instanceof PropertyValueGenerator) { $defaultValue = new PropertyValueGenerator($defaultValue, $defaultValueType, $defaultValueOutputMode); } $this->defaultValue = $defaultValue; return $this; } /** * @return ?PropertyValueGenerator */ public function getDefaultValue() { return $this->defaultValue; } /** * @throws Exception\RuntimeException * @return string * @psalm-return non-empty-string */ public function generate() { $name = $this->getName(); $defaultValue = $this->getDefaultValue(); $output = ''; if (($docBlock = $this->getDocBlock()) !== null) { $docBlock->setIndentation(' '); $output .= $docBlock->generate(); } if ($this->isConst()) { if ($defaultValue !== null && ! $defaultValue->isValidConstantType()) { throw new Exception\RuntimeException(sprintf( 'The property %s is said to be ' . 'constant but does not have a valid constant value.', $this->name )); } return $output . $this->indentation . ($this->isFinal() ? 'final ' : '') . $this->getVisibility() . ' const ' . $name . ' = ' . ($defaultValue !== null ? $defaultValue->generate() : 'null;'); } $output .= $this->indentation . $this->getVisibility() . ($this->isReadonly() ? ' readonly' : '') . ($this->isStatic() ? ' static' : '') . ' $' . $name; if ($this->omitDefaultValue) { return $output . ';'; } return $output . ' = ' . ($defaultValue !== null ? $defaultValue->generate() : 'null;'); } /** * @return PropertyGenerator */ public function omitDefaultValue(bool $omit = true) { $this->omitDefaultValue = $omit; return $this; } } src/Generator/PropertyValueGenerator.php000064400000000400144760120040014452 0ustar00getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock())); } // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } $properties = []; foreach ($classReflection->getProperties() as $reflectionProperty) { if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) { $properties[] = PropertyGenerator::fromReflection($reflectionProperty); } } $cg->addProperties($properties); $methods = []; foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getName(); $namespaceName = $cg->getNamespaceName(); if ($namespaceName !== null) { $className = $namespaceName . '\\' . $className; } if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } $cg->addMethods($methods); return $cg; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey filegenerator FileGenerator File generator that holds this class * @configkey namespacename string The namespace for this class * @configkey docblock string The docblock information * @configkey properties * @configkey methods * @throws Exception\InvalidArgumentException * @param array $array * @return static */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Class generator requires that a name is provided for this object' ); } $cg = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'containingfile': $cg->setContainingFileGenerator($value); break; case 'namespacename': $cg->setNamespaceName($value); break; case 'docblock': $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value); $cg->setDocBlock($docBlock); break; case 'properties': $cg->addProperties($value); break; case 'methods': $cg->addMethods($value); break; } } return $cg; } /** * @inheritDoc * @param int[]|int $flags */ public function setFlags($flags) { return $this; } /** * @param int $flag * @return static */ public function addFlag($flag) { return $this; } /** * @param int $flag * @return static */ public function removeFlag($flag) { return $this; } /** * @inheritDoc */ public function setFinal($isFinal) { return $this; } /** * @param ?string $extendedClass * @return static */ public function setExtendedClass($extendedClass) { return $this; } /** * @inheritDoc */ public function setImplementedInterfaces(array $implementedInterfaces) { return $this; } /** * @inheritDoc */ public function setAbstract($isAbstract) { return $this; } } src/Generator/TraitUsageGenerator.php000064400000027324144760120040013717 0ustar00 Array of trait names */ protected array $traits = []; /** @var array Array of trait aliases */ protected array $traitAliases = []; /** @var array Array of trait overrides */ protected array $traitOverrides = []; /** @var array Array of string names */ protected array $uses = []; public function __construct(ClassGenerator $classGenerator) { $this->classGenerator = $classGenerator; } /** * @inheritDoc */ public function addUse($use, $useAlias = null) { $this->removeUse($use); if (! empty($useAlias)) { $use .= ' as ' . $useAlias; } $this->uses[$use] = $use; return $this; } /** * @inheritDoc */ public function getUses() { return array_values($this->uses); } /** * @param string $use * @return bool */ public function hasUse($use) { foreach ($this->uses as $key => $value) { $parts = explode(' ', $value); if ($parts[0] === $use) { return true; } } return false; } /** * @param string $use * @return bool */ public function hasUseAlias($use) { foreach ($this->uses as $key => $value) { $parts = explode(' as ', $value); if ($parts[0] === $use && count($parts) == 2) { return true; } } return false; } /** * Returns the alias of the provided FQCN */ public function getUseAlias(string $use): ?string { foreach ($this->uses as $key => $value) { $parts = explode(' as ', $key); if ($parts[0] === $use && count($parts) == 2) { return $parts[1]; } } return null; } /** * Returns true if the alias is defined in the use list */ public function isUseAlias(string $alias): bool { foreach ($this->uses as $key => $value) { $parts = explode(' as ', $key); if (count($parts) === 2 && $parts[1] === $alias) { return true; } } return false; } /** * @param string $use * @return TraitUsageGenerator */ public function removeUse($use) { foreach ($this->uses as $key => $value) { $parts = explode(' ', $value); if ($parts[0] === $use) { unset($this->uses[$value]); } } return $this; } /** * @param string $use * @return TraitUsageGenerator */ public function removeUseAlias($use) { foreach ($this->uses as $key => $value) { $parts = explode(' as ', $value); if ($parts[0] === $use && count($parts) == 2) { unset($this->uses[$value]); } } return $this; } /** * @inheritDoc */ public function addTrait($trait) { if (is_array($trait)) { if (! array_key_exists('traitName', $trait)) { throw new Exception\InvalidArgumentException('Missing required value for traitName'); } $traitName = $trait['traitName']; if (array_key_exists('aliases', $trait)) { foreach ($trait['aliases'] as $alias) { $this->addAlias($alias); } } if (array_key_exists('insteadof', $trait)) { foreach ($trait['insteadof'] as $insteadof) { $this->addTraitOverride($insteadof); } } } else { $traitName = $trait; } if (! $this->hasTrait($traitName)) { $this->traits[] = $traitName; } return $this; } /** * @inheritDoc */ public function addTraits(array $traits) { foreach ($traits as $trait) { $this->addTrait($trait); } return $this; } /** * @inheritDoc */ public function hasTrait($traitName) { return in_array($traitName, $this->traits); } /** * @inheritDoc */ public function getTraits() { return $this->traits; } /** * @inheritDoc */ public function removeTrait($traitName) { $key = array_search($traitName, $this->traits); if (false !== $key) { unset($this->traits[$key]); } return $this; } /** * @inheritDoc */ public function addTraitAlias($method, $alias, $visibility = null) { $traitAndMethod = $method; if (is_array($method)) { if (! array_key_exists('traitName', $method)) { throw new Exception\InvalidArgumentException('Missing required argument "traitName" for $method'); } if (! array_key_exists('method', $method)) { throw new Exception\InvalidArgumentException('Missing required argument "method" for $method'); } $traitAndMethod = $method['traitName'] . '::' . $method['method']; } // Validations if (false === strpos($traitAndMethod, '::')) { throw new Exception\InvalidArgumentException( 'Invalid Format: $method must be in the format of trait::method' ); } if (! is_string($alias)) { throw new Exception\InvalidArgumentException('Invalid Alias: $alias must be a string or array.'); } if ($this->classGenerator->hasMethod($alias)) { throw new Exception\InvalidArgumentException('Invalid Alias: Method name already exists on this class.'); } if ( null !== $visibility && $visibility !== ReflectionMethod::IS_PUBLIC && $visibility !== ReflectionMethod::IS_PRIVATE && $visibility !== ReflectionMethod::IS_PROTECTED ) { throw new Exception\InvalidArgumentException( 'Invalid Type: $visibility must of ReflectionMethod::IS_PUBLIC,' . ' ReflectionMethod::IS_PRIVATE or ReflectionMethod::IS_PROTECTED' ); } [$trait, $method] = explode('::', $traitAndMethod); if (! $this->hasTrait($trait)) { throw new Exception\InvalidArgumentException('Invalid trait: Trait does not exists on this class'); } $this->traitAliases[$traitAndMethod] = [ 'alias' => $alias, 'visibility' => $visibility, ]; return $this; } /** * @inheritDoc */ public function getTraitAliases() { return $this->traitAliases; } /** * @inheritDoc */ public function addTraitOverride($method, $traitsToReplace) { if (false === is_array($traitsToReplace)) { $traitsToReplace = [$traitsToReplace]; } $traitAndMethod = $method; if (is_array($method)) { if (! array_key_exists('traitName', $method)) { throw new Exception\InvalidArgumentException('Missing required argument "traitName" for $method'); } if (! array_key_exists('method', $method)) { throw new Exception\InvalidArgumentException('Missing required argument "method" for $method'); } $traitAndMethod = (string) $method['traitName'] . '::' . (string) $method['method']; } // Validations if (false === strpos($traitAndMethod, '::')) { throw new Exception\InvalidArgumentException( 'Invalid Format: $method must be in the format of trait::method' ); } [$trait, $method] = explode('::', $traitAndMethod); if (! $this->hasTrait($trait)) { throw new Exception\InvalidArgumentException('Invalid trait: Trait does not exists on this class'); } if (! array_key_exists($traitAndMethod, $this->traitOverrides)) { $this->traitOverrides[$traitAndMethod] = []; } foreach ($traitsToReplace as $traitToReplace) { if (! is_string($traitToReplace)) { throw new Exception\InvalidArgumentException( 'Invalid Argument: $traitToReplace must be a string or array of strings' ); } if (! in_array($traitToReplace, $this->traitOverrides[$traitAndMethod])) { $this->traitOverrides[$traitAndMethod][] = $traitToReplace; } } return $this; } /** * @inheritDoc */ public function removeTraitOverride($method, $overridesToRemove = null) { if (! array_key_exists($method, $this->traitOverrides)) { return $this; } if (null === $overridesToRemove) { unset($this->traitOverrides[$method]); return $this; } $overridesToRemove = ! is_array($overridesToRemove) ? [$overridesToRemove] : $overridesToRemove; foreach ($overridesToRemove as $traitToRemove) { $key = array_search($traitToRemove, $this->traitOverrides[$method]); if (false !== $key) { unset($this->traitOverrides[$method][$key]); } } return $this; } /** * @inheritDoc */ public function getTraitOverrides() { return $this->traitOverrides; } /** * @inheritDoc */ public function generate() { $output = ''; $indent = $this->getIndentation(); $traits = $this->getTraits(); if (empty($traits)) { return $output; } $output .= $indent . 'use ' . implode(', ', $traits); $aliases = $this->getTraitAliases(); $overrides = $this->getTraitOverrides(); if (empty($aliases) && empty($overrides)) { return $output . ';' . self::LINE_FEED . self::LINE_FEED; } $output .= ' {' . self::LINE_FEED; foreach ($aliases as $method => $alias) { $visibility = null !== $alias['visibility'] ? current(Reflection::getModifierNames($alias['visibility'])) . ' ' : ''; // validation check if ($this->classGenerator->hasMethod($alias['alias'])) { throw new Exception\RuntimeException(sprintf( 'Generation Error: Aliased method %s already exists on this class', $alias['alias'] )); } $output .= $indent . $indent . $method . ' as ' . $visibility . $alias['alias'] . ';' . self::LINE_FEED; } foreach ($overrides as $method => $insteadofTraits) { foreach ($insteadofTraits as $insteadofTrait) { $output .= $indent . $indent . $method . ' insteadof ' . $insteadofTrait . ';' . self::LINE_FEED; } } return $output . self::LINE_FEED . $indent . '}' . self::LINE_FEED . self::LINE_FEED; } } src/Generator/TraitUsageInterface.php000064400000010374144760120040013666 0ustar00 $traits * @return self */ public function addTraits(array $traits); /** * Check to see if the class has a trait defined * * @param string $traitName * @return bool */ public function hasTrait($traitName); /** * Get a list of trait names * * @return array */ public function getTraits(); /** * Remove a trait by its name * * @param string $traitName */ public function removeTrait($traitName); /** * Add a trait alias. This will be used to generate the AS portion of the use statement. * * $method: * This method provides 2 ways for defining the trait method. * Option 1: String * Option 2: Array * key: traitName value: name of trait * key: method value: trait method * * $alias: * Alias is a string representing the new method name. * * $visibilty: * ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PRIVATE | ReflectionMethod::IS_PROTECTED * * @param mixed $method String or Array * @param string $alias * @param null|int $visibility */ public function addTraitAlias($method, $alias, $visibility = null); /** * @return array */ public function getTraitAliases(); /** * Add a trait method override. This will be used to generate the INSTEADOF portion of the use * statement. * * $method: * This method provides 2 ways for defining the trait method. * Option 1: String Format: :: * Option 2: Array * key: traitName value: trait name * key: method value: method name * * $traitToReplace: * The name of the trait that you wish to supersede. * * This method provides 2 ways for defining the trait method. * Option 1: String of trait to replace * Option 2: Array of strings of traits to replace * @param mixed $method * @param mixed $traitsToReplace */ public function addTraitOverride($method, $traitsToReplace); /** * Remove an override for a given trait::method * * $method: * This method provides 2 ways for defining the trait method. * Option 1: String Format: :: * Option 2: Array * key: traitName value: trait name * key: method value: method name * * $overridesToRemove: * The name of the trait that you wish to remove. * * This method provides 2 ways for defining the trait method. * Option 1: String of trait to replace * Option 2: Array of strings of traits to replace * * @param mixed $method * @param mixed $overridesToRemove * @return self */ public function removeTraitOverride($method, $overridesToRemove = null); /** * Return trait overrides * * @return array */ public function getTraitOverrides(); } src/Generator/TypeGenerator.php000064400000015416144760120040012567 0ustar00 */ private array $types; private bool $nullable; private bool $isIntersection; /** * @internal * * @psalm-pure */ public static function fromReflectionType( ?ReflectionType $type, ?ReflectionClass $currentClass ): ?self { if (null === $type) { return null; } assert( $type instanceof ReflectionNamedType || $type instanceof ReflectionUnionType || $type instanceof ReflectionIntersectionType ); // Having to go through `fromTypeString` leads to interesting invalid types as "acceptable", but that's neither // a security issue, nor a major problem, since {@see ReflectionType} should itself produce valid/usable strings return self::fromTypeString(implode( $type instanceof ReflectionIntersectionType ? '&' : '|', array_map( static fn(ReflectionNamedType $type): string => self::reflectionNamedTypeToString($type, $currentClass), $type instanceof ReflectionNamedType ? [$type] : $type->getTypes() ) )); } /** @psalm-pure */ private static function reflectionNamedTypeToString( ReflectionNamedType $type, ?ReflectionClass $currentClass ): string { $lowerCaseName = strtolower($type->getName()); if ('mixed' === $lowerCaseName || 'null' === $lowerCaseName) { // `mixed` and `null` are implicitly nullable, therefore we need to skip adding nullability markers to it return $lowerCaseName; } $nullabilityMarker = $type->allowsNull() ? '?' : ''; if ('self' === $lowerCaseName && $currentClass) { return $nullabilityMarker . $currentClass->getName(); } if ('parent' === $lowerCaseName && $currentClass && $parentClass = $currentClass->getParentClass()) { return $nullabilityMarker . $parentClass->getName(); } return $nullabilityMarker . $type->getName(); } /** * @throws InvalidArgumentException * @psalm-pure */ public static function fromTypeString(string $type): self { [$nullable, $trimmedNullable] = self::trimNullable($type); $isIntersection = false; $separator = '|'; if (false !== strpos($type, '&')) { $isIntersection = true; $separator = '&'; } $types = array_map([AtomicType::class, 'fromString'], explode($separator, $trimmedNullable)); usort( $types, static fn(AtomicType $left, AtomicType $right): int => [$left->sortIndex, $left->type] <=> [$right->sortIndex, $right->type] ); assert([] !== $types); if (1 === count($types)) { $types[0]->assertCanBeAStandaloneType(); if ($nullable) { $types[0]->assertCanBeStandaloneNullable(); } return new self($types, $nullable, $isIntersection); } if ($nullable) { throw new InvalidArgumentException(sprintf( 'Type "%s" is a union type, and therefore cannot be also marked nullable with the "?" prefix', $type )); } foreach ($types as $index => $atomicType) { $otherTypes = array_diff_key($types, array_flip([$index])); assert([] !== $otherTypes, 'There are always 2 or more types in a union type'); if ($isIntersection) { $atomicType->assertCanIntersectWith($otherTypes); } else { $atomicType->assertCanUnionWith($otherTypes); } } return new self($types, $nullable, $isIntersection); } /** * @param AtomicType[] $types * @psalm-param non-empty-list $types */ private function __construct(array $types, bool $nullable, bool $isIntersection) { $this->types = $types; $this->nullable = $nullable; $this->isIntersection = $isIntersection; } /** * {@inheritDoc} * * Generates the type string, including FQCN "\\" prefix, so that * it can directly be used within any code snippet, regardless of * imports. * * @psalm-return non-empty-string */ public function generate(): string { $typesAsStrings = array_map( static fn (AtomicType $type): string => $type->fullyQualifiedName(), $this->types ); if ($this->nullable) { return '?' . implode($this->atomicTypesSeparator(), $typesAsStrings); } return implode($this->atomicTypesSeparator(), $typesAsStrings); } public function equals(TypeGenerator $otherType): bool { return $this->generate() === $otherType->generate(); } /** * @return string the cleaned type string. Please note that this value is not suitable for code generation, * since the returned value does not include any root namespace prefixes, when applicable, * and therefore the values cannot be used as FQCN in generated code. */ public function __toString(): string { return implode($this->atomicTypesSeparator(), array_map( static fn (AtomicType $type): string => $type->type, $this->types )); } /** * @param string $type * @return bool[]|string[] ordered tuple, first key represents whether the type is nullable, second is the * trimmed string * @psalm-return array{bool, string} * @psalm-pure */ private static function trimNullable($type): array { if (0 === strpos($type, '?')) { return [true, substr($type, 1)]; } return [false, $type]; } /** @psalm-return '|'|'&' */ private function atomicTypesSeparator(): string { return $this->isIntersection ? '&' : '|'; } } src/Generator/TypeGenerator/AtomicType.php000064400000015612144760120040014643 0ustar00 */ private const BUILT_IN_TYPES_PRECEDENCE = [ 'bool' => 1, 'int' => 2, 'float' => 3, 'string' => 4, 'array' => 5, 'callable' => 6, 'iterable' => 7, 'object' => 8, 'static' => 9, 'mixed' => 10, 'void' => 11, 'false' => 12, 'null' => 13, 'never' => 14, ]; /** @psalm-var array */ private const NOT_NULLABLE_TYPES = [ 'null' => null, 'false' => null, 'void' => null, 'mixed' => null, 'never' => null, ]; /** A regex pattern to match valid class/interface/trait names */ private const VALID_IDENTIFIER_MATCHER = '/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*' . '(\\\\[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)*$/'; /** @psalm-var value-of|0 */ public int $sortIndex; /** @psalm-var non-empty-string */ public string $type; /** * @psalm-param non-empty-string $type * @psalm-param value-of|0 $sortIndex */ private function __construct(string $type, int $sortIndex) { $this->type = $type; $this->sortIndex = $sortIndex; } /** * @psalm-pure * @throws InvalidArgumentException */ public static function fromString(string $type): self { $trimmedType = '\\' === ($type[0] ?? '') ? substr($type, 1) : $type; $lowerCaseType = strtolower($trimmedType); if (array_key_exists($lowerCaseType, self::BUILT_IN_TYPES_PRECEDENCE)) { if ($lowerCaseType !== strtolower($type)) { throw new InvalidArgumentException(sprintf( 'Provided type "%s" is a built-in type, and should not be prefixed with "\\"', $type )); } return new self($lowerCaseType, self::BUILT_IN_TYPES_PRECEDENCE[$lowerCaseType]); } if (1 !== preg_match(self::VALID_IDENTIFIER_MATCHER, $trimmedType)) { throw new InvalidArgumentException(sprintf( 'Provided type "%s" is not recognized as a valid expression: ' . 'it must match "%s" or be one of the built-in types (%s)', $type, self::VALID_IDENTIFIER_MATCHER, implode(', ', self::BUILT_IN_TYPES_PRECEDENCE) )); } assert('' !== $trimmedType); return new self($trimmedType, 0); } /** @psalm-pure */ public static function null(): self { return new self('null', self::BUILT_IN_TYPES_PRECEDENCE['null']); } /** @psalm-return non-empty-string */ public function fullyQualifiedName(): string { return array_key_exists($this->type, self::BUILT_IN_TYPES_PRECEDENCE) ? $this->type : '\\' . $this->type; } /** * @psalm-param non-empty-array $others * @throws InvalidArgumentException */ public function assertCanUnionWith(array $others): void { if ( 'mixed' === $this->type || 'void' === $this->type || 'never' === $this->type ) { throw new InvalidArgumentException(sprintf( 'Type "%s" cannot be composed in a union with any other types', $this->type )); } foreach ($others as $other) { if ($other->type === $this->type) { throw new InvalidArgumentException(sprintf( 'Type "%s" cannot be composed in a union with the same type "%s"', $this->type, $other->type )); } } if ( $this->requiresUnionWithStandaloneType() && [] === array_filter($others, static fn (self $type): bool => ! $type->requiresUnionWithStandaloneType()) ) { throw new InvalidArgumentException(sprintf( 'Type "%s" requires to be composed with non-standalone types', $this->type )); } } /** * @psalm-param non-empty-array $others * @throws InvalidArgumentException */ public function assertCanIntersectWith(array $others): void { if (array_key_exists($this->type, self::BUILT_IN_TYPES_PRECEDENCE)) { throw new InvalidArgumentException(sprintf( 'Type "%s" cannot be composed in an intersection with any other types', $this->type )); } foreach ($others as $other) { if ($other->type === $this->type) { throw new InvalidArgumentException(sprintf( 'Type "%s" cannot be composed in an intersection with the same type "%s"', $this->type, $other->type )); } } if ( $this->requiresUnionWithStandaloneType() && [] === array_filter($others, static fn (self $type): bool => ! $type->requiresUnionWithStandaloneType()) ) { throw new InvalidArgumentException(sprintf( 'Type "%s" requires to be composed with non-standalone types', $this->type )); } } /** @throws InvalidArgumentException */ public function assertCanBeAStandaloneType(): void { if ($this->requiresUnionWithStandaloneType()) { throw new InvalidArgumentException(sprintf( 'Type "%s" cannot be used standalone, and must be part of a union type', $this->type )); } } /** @throws InvalidArgumentException */ public function assertCanBeStandaloneNullable(): void { if (array_key_exists($this->type, self::NOT_NULLABLE_TYPES)) { throw new InvalidArgumentException(sprintf( 'Type "%s" cannot be nullable', $this->type )); } } private function requiresUnionWithStandaloneType(): bool { return 'null' === $this->type || 'false' === $this->type; } } src/Generator/ValueGenerator.php000064400000031142144760120040012714 0ustar00setValue($value); } if ($type !== self::TYPE_AUTO) { $this->setType($type); } if ($outputMode !== self::OUTPUT_MULTIPLE_LINE) { $this->setOutputMode($outputMode); } if ($constants === null) { $constants = new SplArrayObject(); } elseif (! ($constants instanceof SplArrayObject || $constants instanceof StdlibArrayObject)) { throw new InvalidArgumentException( '$constants must be an instance of ArrayObject or Laminas\Stdlib\ArrayObject' ); } $this->constants = $constants; } /** * Init constant list by defined and magic constants */ public function initEnvironmentConstants() { $constants = [ '__DIR__', '__FILE__', '__LINE__', '__CLASS__', '__TRAIT__', '__METHOD__', '__FUNCTION__', '__NAMESPACE__', '::', ]; $constants = array_merge($constants, array_keys(get_defined_constants()), $this->constants->getArrayCopy()); $this->constants->exchangeArray($constants); } /** * Add constant to list * * @param string $constant * @return $this */ public function addConstant($constant) { $this->constants->append($constant); return $this; } /** * Delete constant from constant list * * @param string $constant * @return bool */ public function deleteConstant($constant) { if (($index = array_search($constant, $this->constants->getArrayCopy())) !== false) { $this->constants->offsetUnset($index); } return $index !== false; } /** * Return constant list * * @return SplArrayObject|StdlibArrayObject */ public function getConstants() { return $this->constants; } /** * @return bool */ public function isValidConstantType() { if ($this->type === self::TYPE_AUTO) { $type = $this->getAutoDeterminedType($this->value); } else { $type = $this->type; } $validConstantTypes = [ self::TYPE_ARRAY, self::TYPE_ARRAY_LONG, self::TYPE_ARRAY_SHORT, self::TYPE_BOOLEAN, self::TYPE_BOOL, self::TYPE_NUMBER, self::TYPE_INTEGER, self::TYPE_INT, self::TYPE_FLOAT, self::TYPE_DOUBLE, self::TYPE_STRING, self::TYPE_CONSTANT, self::TYPE_NULL, ]; return in_array($type, $validConstantTypes); } /** * @param mixed $value * @return ValueGenerator */ public function setValue($value) { $this->value = $value; return $this; } /** * @return mixed */ public function getValue() { return $this->value; } /** * @param string $type * @return ValueGenerator */ public function setType($type) { $this->type = (string) $type; return $this; } /** * @return string */ public function getType() { return $this->type; } /** * @param int $arrayDepth * @return ValueGenerator */ public function setArrayDepth($arrayDepth) { $this->arrayDepth = (int) $arrayDepth; return $this; } /** * @return int */ public function getArrayDepth() { return $this->arrayDepth; } /** * @param string $type * @return string */ protected function getValidatedType($type) { $types = [ self::TYPE_AUTO, self::TYPE_BOOLEAN, self::TYPE_BOOL, self::TYPE_NUMBER, self::TYPE_INTEGER, self::TYPE_INT, self::TYPE_FLOAT, self::TYPE_DOUBLE, self::TYPE_STRING, self::TYPE_ARRAY, self::TYPE_ARRAY_SHORT, self::TYPE_ARRAY_LONG, self::TYPE_CONSTANT, self::TYPE_NULL, self::TYPE_OBJECT, self::TYPE_OTHER, ]; if (in_array($type, $types)) { return $type; } return self::TYPE_AUTO; } /** * @param mixed $value * @return string */ public function getAutoDeterminedType($value) { switch (gettype($value)) { case 'boolean': return self::TYPE_BOOLEAN; case 'string': foreach ($this->constants as $constant) { if ($value === $constant) { return self::TYPE_CONSTANT; } if (strpos($value, $constant) !== false) { return self::TYPE_CONSTANT; } } return self::TYPE_STRING; case 'double': case 'float': case 'integer': return self::TYPE_NUMBER; case 'array': return self::TYPE_ARRAY; case 'NULL': return self::TYPE_NULL; case 'object': case 'resource': case 'unknown type': default: return self::TYPE_OTHER; } } /** * @throws Exception\RuntimeException * @return string */ public function generate() { $type = $this->type; if ($type !== self::TYPE_AUTO) { $type = $this->getValidatedType($type); } $value = $this->value; if ($type === self::TYPE_AUTO) { $type = $this->getAutoDeterminedType($value); } $isArrayType = in_array($type, [self::TYPE_ARRAY, self::TYPE_ARRAY_LONG, self::TYPE_ARRAY_SHORT]); if ($isArrayType) { foreach ($value as &$curValue) { if ($curValue instanceof self) { continue; } if (is_array($curValue)) { $newType = $type; } else { $newType = self::TYPE_AUTO; } $curValue = new self($curValue, $newType, self::OUTPUT_MULTIPLE_LINE, $this->getConstants()); $curValue->setIndentation($this->indentation); } } $output = ''; switch ($type) { case self::TYPE_BOOLEAN: case self::TYPE_BOOL: $output .= $value ? 'true' : 'false'; break; case self::TYPE_STRING: $output .= self::escape($value); break; case self::TYPE_NULL: $output .= 'null'; break; case self::TYPE_NUMBER: case self::TYPE_INTEGER: case self::TYPE_INT: case self::TYPE_FLOAT: case self::TYPE_DOUBLE: case self::TYPE_CONSTANT: $output .= $value; break; case self::TYPE_ARRAY: case self::TYPE_ARRAY_LONG: case self::TYPE_ARRAY_SHORT: if ($type === self::TYPE_ARRAY_LONG) { $startArray = 'array('; $endArray = ')'; } else { $startArray = '['; $endArray = ']'; } $output .= $startArray; if ($this->outputMode == self::OUTPUT_MULTIPLE_LINE) { $output .= self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth + 1); } $outputParts = []; $noKeyIndex = 0; foreach ($value as $n => $v) { /** @var ValueGenerator $v */ $v->setArrayDepth($this->arrayDepth + 1); $partV = $v->generate(); $short = false; if (is_int($n)) { if ($n === $noKeyIndex) { $short = true; $noKeyIndex++; } else { $noKeyIndex = max($n + 1, $noKeyIndex); } } if ($short) { $outputParts[] = $partV; } else { $outputParts[] = (is_int($n) ? $n : self::escape($n)) . ' => ' . $partV; } } $padding = $this->outputMode == self::OUTPUT_MULTIPLE_LINE ? self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth + 1) : ' '; $output .= implode(',' . $padding, $outputParts); if ($this->outputMode == self::OUTPUT_MULTIPLE_LINE) { if (count($outputParts) > 0) { $output .= ','; } $output .= self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth); } $output .= $endArray; break; case self::TYPE_OTHER: default: throw new Exception\RuntimeException(sprintf( 'Type "%s" is unknown or cannot be used as property default value.', is_object($value) ? get_class($value) : gettype($value) )); } return $output; } /** * Quotes value for PHP code. * * @param string $input Raw string. * @param bool $quote Whether add surrounding quotes or not. * @return string PHP-ready code. */ public static function escape($input, $quote = true) { $output = addcslashes($input, "\\'"); // adds quoting strings if ($quote) { $output = "'" . $output . "'"; } return $output; } /** * @param string $outputMode * @return ValueGenerator */ public function setOutputMode($outputMode) { $this->outputMode = (string) $outputMode; return $this; } /** * @return string */ public function getOutputMode() { return $this->outputMode; } /** @return string */ public function __toString() { return $this->generate(); } } src/Generic/Prototype/PrototypeClassFactory.php000064400000006061144760120040015751 0ustar00addPrototype($prototype); } if ($genericPrototype) { $this->setGenericPrototype($genericPrototype); } } /** * @throws Exception\InvalidArgumentException */ public function addPrototype(PrototypeInterface $prototype) { $prototypeName = $this->normalizeName($prototype->getName()); if (isset($this->prototypes[$prototypeName])) { throw new Exception\InvalidArgumentException('A prototype with this name already exists in this manager'); } $this->prototypes[$prototypeName] = $prototype; } /** * @throws Exception\InvalidArgumentException */ public function setGenericPrototype(PrototypeGenericInterface $prototype) { if (isset($this->genericPrototype)) { throw new Exception\InvalidArgumentException('A default prototype is already set'); } $this->genericPrototype = $prototype; } /** * @param string $name * @return string */ protected function normalizeName($name) { return str_replace(['-', '_'], '', $name); } /** * @param string $name * @return bool */ public function hasPrototype($name) { $name = $this->normalizeName($name); return isset($this->prototypes[$name]); } /** * @param string $prototypeName * @return PrototypeInterface * @throws Exception\RuntimeException */ public function getClonedPrototype($prototypeName) { $prototypeName = $this->normalizeName($prototypeName); if (! $this->hasPrototype($prototypeName) && ! isset($this->genericPrototype)) { throw new Exception\RuntimeException('This tag name is not supported by this tag manager'); } if (! $this->hasPrototype($prototypeName)) { $newPrototype = clone $this->genericPrototype; $newPrototype->setName($prototypeName); } else { $newPrototype = clone $this->prototypes[$prototypeName]; } return $newPrototype; } } src/Generic/Prototype/PrototypeGenericInterface.php000064400000000416144760120040016547 0ustar00docBlock)) { return $this->docBlock; } if ('' == $this->getDocComment()) { return false; } $this->docBlock = new DocBlockReflection($this); return $this->docBlock; } /** * Return the start line of the class * * @param bool $includeDocComment * @return int */ #[ReturnTypeWillChange] public function getStartLine($includeDocComment = false) { if ($includeDocComment && $this->getDocComment() != '') { return $this->getDocBlock()->getStartLine(); } return parent::getStartLine(); } /** * Return the contents of the class * * @param bool $includeDocBlock * @return string */ public function getContents($includeDocBlock = true) { $fileName = $this->getFileName(); if (false === $fileName || ! file_exists($fileName)) { return ''; } $filelines = file($fileName); $startnum = $this->getStartLine($includeDocBlock); $endnum = $this->getEndLine() - $this->getStartLine(); // Ensure we get between the open and close braces $lines = array_slice($filelines, $startnum, $endnum); array_unshift($lines, $filelines[$startnum - 1]); return strstr(implode('', $lines), '{'); } /** * Get all reflection objects of implemented interfaces * * @return ClassReflection[] */ #[ReturnTypeWillChange] public function getInterfaces() { $phpReflections = parent::getInterfaces(); $laminasReflections = []; while ($phpReflections && ($phpReflection = array_shift($phpReflections))) { $instance = new ClassReflection($phpReflection->getName()); $laminasReflections[] = $instance; unset($phpReflection); } unset($phpReflections); return $laminasReflections; } /** * Return method reflection by name * * @param string $name * @return MethodReflection */ #[ReturnTypeWillChange] public function getMethod($name) { return new MethodReflection($this->getName(), parent::getMethod($name)->getName()); } /** * Get reflection objects of all methods * * @param int $filter * @return MethodReflection[] */ #[ReturnTypeWillChange] public function getMethods($filter = -1) { $methods = []; foreach (parent::getMethods($filter) as $method) { $instance = new MethodReflection($this->getName(), $method->getName()); $methods[] = $instance; } return $methods; } /** * Returns an array of reflection classes of traits used by this class. * * @return null|array */ #[ReturnTypeWillChange] public function getTraits() { $vals = []; $traits = parent::getTraits(); if ($traits === null) { return; } foreach ($traits as $trait) { $vals[] = new ClassReflection($trait->getName()); } return $vals; } /** * Get parent reflection class of reflected class * * @return ClassReflection|bool */ #[ReturnTypeWillChange] public function getParentClass() { $phpReflection = parent::getParentClass(); if ($phpReflection) { $laminasReflection = new ClassReflection($phpReflection->getName()); unset($phpReflection); return $laminasReflection; } return false; } /** * Return reflection property of this class by name * * @param string $name * @return PropertyReflection */ #[ReturnTypeWillChange] public function getProperty($name) { $phpReflection = parent::getProperty($name); $laminasReflection = new PropertyReflection($this->getName(), $phpReflection->getName()); unset($phpReflection); return $laminasReflection; } /** * Return reflection properties of this class * * @param int $filter * @return PropertyReflection[] */ #[ReturnTypeWillChange] public function getProperties($filter = -1) { $phpReflections = parent::getProperties($filter); $laminasReflections = []; while ($phpReflections && ($phpReflection = array_shift($phpReflections))) { $instance = new PropertyReflection($this->getName(), $phpReflection->getName()); $laminasReflections[] = $instance; unset($phpReflection); } unset($phpReflections); return $laminasReflections; } /** * @return string */ public function toString() { return parent::__toString(); } /** * @return string */ public function __toString() { return parent::__toString(); } } src/Reflection/DocBlock/Tag/AuthorTag.php000064400000002405144760120040014226 0ustar00]*)\>)?(.*)$/u', $tagDocblockLine, $match)) { return; } if ($match[1] !== '') { $this->authorName = rtrim($match[1]); } if (isset($match[3]) && $match[3] !== '') { $this->authorEmail = $match[3]; } } /** * @return null|string */ public function getAuthorName() { return $this->authorName; } /** * @return null|string */ public function getAuthorEmail() { return $this->authorEmail; } /** * @return string * @psalm-return non-empty-string */ public function __toString() { return 'DocBlock Tag [ * @' . $this->getName() . ' ]' . "\n"; } } src/Reflection/DocBlock/Tag/GenericTag.php000064400000003545144760120040014346 0ustar00contentSplitCharacter = $contentSplitCharacter; } /** * @param string $tagDocBlockLine * @return void */ public function initialize($tagDocBlockLine) { $this->parse($tagDocBlockLine); } /** * Get annotation tag name * * @return string */ public function getName() { return $this->name; } /** * @param string $name */ public function setName($name) { $this->name = $name; } /** * @return string */ public function getContent() { return $this->content; } /** * @param int $position * @return string */ public function returnValue($position) { return $this->values[$position]; } /** * Serialize to string * * Required by Reflector * * @todo What should this do? * @return string * @psalm-return non-empty-string */ public function __toString() { return 'DocBlock Tag [ * @' . $this->name . ' ]' . "\n"; } /** * @param string $docBlockLine */ protected function parse($docBlockLine) { $this->content = trim($docBlockLine); $this->values = explode($this->contentSplitCharacter, $docBlockLine); } } src/Reflection/DocBlock/Tag/LicenseTag.php000064400000002341144760120040014345 0ustar00url = trim($match[1]); } if (isset($match[2]) && $match[2] !== '') { $this->licenseName = $match[2]; } } /** * @return null|string */ public function getUrl() { return $this->url; } /** * @return null|string */ public function getLicenseName() { return $this->licenseName; } /** * @return string * @psalm-return non-empty-string */ public function __toString() { return 'DocBlock Tag [ * @' . $this->getName() . ' ]' . "\n"; } } src/Reflection/DocBlock/Tag/MethodTag.php000064400000004164144760120040014210 0ustar00 */ protected $types = []; /** @var string */ protected $methodName; /** @var string */ protected $description; /** * Is static method * * @var bool */ protected $isStatic = false; /** * @return string */ public function getName() { return 'method'; } /** * Initializer * * @param string $tagDocblockLine */ public function initialize($tagDocblockLine) { $match = []; if (! preg_match('#^(static[\s]+)?(.+[\s]+)?(.+\(\))[\s]*(.*)$#m', $tagDocblockLine, $match)) { return; } if ($match[1] !== '') { $this->isStatic = true; } if ($match[2] !== '') { $this->types = explode('|', rtrim($match[2])); } $this->methodName = $match[3]; if ($match[4] !== '') { $this->description = $match[4]; } } /** * Get return value type * * @deprecated 2.0.4 use getTypes instead * * @return null|string */ public function getReturnType() { if (empty($this->types)) { return; } return $this->types[0]; } /** {@inheritDoc} */ public function getTypes() { return $this->types; } /** * @return string */ public function getMethodName() { return $this->methodName; } /** * @return null|string */ public function getDescription() { return $this->description; } /** * @return bool */ public function isStatic() { return $this->isStatic; } /** * @return string * @psalm-return non-empty-string */ public function __toString() { return 'DocBlock Tag [ * @' . $this->getName() . ' ]' . "\n"; } } src/Reflection/DocBlock/Tag/ParamTag.php000064400000003345144760120040014030 0ustar00 */ protected $types = []; /** @var string */ protected $variableName; /** @var string */ protected $description; /** * @return string */ public function getName() { return 'param'; } /** * Initializer * * @param string $tagDocBlockLine */ public function initialize($tagDocBlockLine) { $matches = []; if (! preg_match('#((?:[\w|\\\]+(?:\[\])*\|?)+)(?:\s+(\$\S+))?(?:\s+(.*))?#s', $tagDocBlockLine, $matches)) { return; } $this->types = explode('|', $matches[1]); if (isset($matches[2])) { $this->variableName = $matches[2]; } if (isset($matches[3])) { $this->description = trim(preg_replace('#\s+#', ' ', $matches[3])); } } /** * Get parameter variable type * * @deprecated 2.0.4 use getTypes instead * * @return string */ public function getType() { if (empty($this->types)) { return ''; } return $this->types[0]; } /** {@inheritDoc} */ public function getTypes() { return $this->types; } /** * Get parameter name * * @return string */ public function getVariableName() { return $this->variableName; } /** * @return string */ public function getDescription() { return $this->description; } } src/Reflection/DocBlock/Tag/PhpDocTypedTagInterface.php000064400000000407144760120040016770 0ustar00 */ public function getTypes(); } src/Reflection/DocBlock/Tag/PropertyTag.php000064400000003465144760120040014617 0ustar00 */ protected $types = []; /** @var string */ protected $propertyName; /** @var string */ protected $description; /** * @return string */ public function getName() { return 'property'; } /** * Initializer * * @param string $tagDocblockLine */ public function initialize($tagDocblockLine) { $match = []; if (! preg_match('#^(.+)?(\$[\S]+)[\s]*(.*)$#m', $tagDocblockLine, $match)) { return; } if ($match[1] !== '') { $this->types = explode('|', rtrim($match[1])); } if ($match[2] !== '') { $this->propertyName = $match[2]; } if ($match[3] !== '') { $this->description = $match[3]; } } /** * @deprecated 2.0.4 use getTypes instead * * @return null|string */ public function getType() { if (empty($this->types)) { return; } return $this->types[0]; } /** {@inheritDoc} */ public function getTypes() { return $this->types; } /** * @return null|string */ public function getPropertyName() { return $this->propertyName; } /** * @return null|string */ public function getDescription() { return $this->description; } /** * @return string * @psalm-return non-empty-string */ public function __toString() { return 'DocBlock Tag [ * @' . $this->getName() . ' ]' . "\n"; } } src/Reflection/DocBlock/Tag/ReturnTag.php000064400000002507144760120040014246 0ustar00types = explode('|', $matches[1]); if (isset($matches[2])) { $this->description = trim(preg_replace('#\s+#', ' ', $matches[2])); } } /** * @deprecated 2.0.4 use getTypes instead * * @return string */ public function getType() { if (empty($this->types)) { return ''; } return $this->types[0]; } /** {@inheritDoc} */ public function getTypes() { return $this->types; } /** * @return string */ public function getDescription() { return $this->description; } } src/Reflection/DocBlock/Tag/TagInterface.php000064400000000423144760120040014662 0ustar00 */ protected $types = []; /** @var string */ protected $description; /** * @return string */ public function getName() { return 'throws'; } /** * @param string $tagDocBlockLine * @return void */ public function initialize($tagDocBlockLine) { $matches = []; preg_match('#([\w|\\\]+)(?:\s+(.*))?#', $tagDocBlockLine, $matches); $this->types = explode('|', $matches[1]); if (isset($matches[2])) { $this->description = $matches[2]; } } /** * Get return variable type * * @deprecated 2.0.4 use getTypes instead * * @return string */ public function getType() { return implode('|', $this->getTypes()); } /** {@inheritDoc} */ public function getTypes() { return $this->types; } /** * @return string */ public function getDescription() { return $this->description; } } src/Reflection/DocBlock/Tag/VarTag.php000064400000003114144760120040013512 0ustar00 */ private $types = []; /** @var string|null */ private $variableName; /** @var string|null */ private $description; /** * {@inheritDoc} */ public function getName(): string { return 'var'; } /** * {@inheritDoc} */ public function initialize($tagDocblockLine): void { $match = []; if ( ! preg_match( '#^([^\$]\S+)?\s*(\$[\S]+)?\s*(.*)$#m', $tagDocblockLine, $match ) ) { return; } if ($match[1] !== '') { $this->types = explode('|', rtrim($match[1])); } if ($match[2] !== '') { $this->variableName = $match[2]; } if ($match[3] !== '') { $this->description = $match[3]; } } /** {@inheritDoc} */ public function getTypes(): array { return $this->types; } public function getVariableName(): ?string { return $this->variableName; } public function getDescription(): ?string { return $this->description; } /** * @psalm-return non-empty-string */ public function __toString(): string { return 'DocBlock Tag [ * @' . $this->getName() . ' ]' . PHP_EOL; } } src/Reflection/DocBlock/TagManager.php000064400000002163144760120040013624 0ustar00addPrototype(new Tag\ParamTag()); $this->addPrototype(new Tag\ReturnTag()); $this->addPrototype(new Tag\MethodTag()); $this->addPrototype(new Tag\PropertyTag()); $this->addPrototype(new Tag\AuthorTag()); $this->addPrototype(new Tag\LicenseTag()); $this->addPrototype(new Tag\ThrowsTag()); $this->addPrototype(new Tag\VarTag()); $this->setGenericPrototype(new Tag\GenericTag()); } /** * @param string $tagName * @param string $content * @return TagInterface */ public function createTag($tagName, $content = null) { /** @var TagInterface $newTag */ $newTag = $this->getClonedPrototype($tagName); if ($content) { $newTag->initialize($content); } return $newTag; } } src/Reflection/DocBlockReflection.php000064400000014600144760120040013630 0ustar00initializeDefaultTags(); } $this->tagManager = $tagManager; if ($commentOrReflector instanceof Reflector) { $this->reflector = $commentOrReflector; if (! method_exists($commentOrReflector, 'getDocComment')) { throw new Exception\InvalidArgumentException('Reflector must contain method "getDocComment"'); } $this->docComment = $commentOrReflector->getDocComment(); // determine line numbers $lineCount = substr_count($this->docComment, "\n"); $this->startLine = $this->reflector->getStartLine() - $lineCount - 1; $this->endLine = $this->reflector->getStartLine() - 1; } elseif (is_string($commentOrReflector)) { $this->docComment = $commentOrReflector; } else { throw new Exception\InvalidArgumentException(sprintf( '%s must have a (string) DocComment or a Reflector in the constructor', static::class )); } if ($this->docComment == '') { throw new Exception\InvalidArgumentException('DocComment cannot be empty'); } $this->reflect(); } /** * Retrieve contents of DocBlock * * @return string */ public function getContents() { $this->reflect(); return $this->cleanDocComment; } /** * Get start line (position) of DocBlock * * @return int */ public function getStartLine() { $this->reflect(); return $this->startLine; } /** * Get last line (position) of DocBlock * * @return int */ public function getEndLine() { $this->reflect(); return $this->endLine; } /** * Get DocBlock short description * * @return string */ public function getShortDescription() { $this->reflect(); return $this->shortDescription; } /** * Get DocBlock long description * * @return string */ public function getLongDescription() { $this->reflect(); return $this->longDescription; } /** * Does the DocBlock contain the given annotation tag? * * @param string $name * @return bool */ public function hasTag($name) { $this->reflect(); foreach ($this->tags as $tag) { if ($tag->getName() == $name) { return true; } } return false; } /** * Retrieve the given DocBlock tag * * @param string $name * @return DocBlockTagInterface|false */ public function getTag($name) { $this->reflect(); foreach ($this->tags as $tag) { if ($tag->getName() == $name) { return $tag; } } return false; } /** * Get all DocBlock annotation tags * * @param string $filter * @return DocBlockTagInterface[] */ public function getTags($filter = null) { $this->reflect(); if ($filter === null || ! is_string($filter)) { return $this->tags; } $returnTags = []; foreach ($this->tags as $tag) { if ($tag->getName() == $filter) { $returnTags[] = $tag; } } return $returnTags; } /** * Parse the DocBlock * * @return void */ protected function reflect() { if ($this->isReflected) { return; } $docComment = preg_replace('#[ ]{0,1}\*/$#', '', $this->docComment); // create a clean docComment $this->cleanDocComment = preg_replace("#[ \t]*(?:/\*\*|\*/|\*)[ ]{0,1}(.*)?#", '$1', $docComment); // @todo should be changed to remove first and last empty line $this->cleanDocComment = ltrim($this->cleanDocComment, "\r\n"); $scanner = new DocBlockScanner($docComment); $this->shortDescription = ltrim($scanner->getShortDescription()); $this->longDescription = ltrim($scanner->getLongDescription()); foreach ($scanner->getTags() as $tag) { $this->tags[] = $this->tagManager->createTag(ltrim($tag['name'], '@'), ltrim($tag['value'])); } $this->isReflected = true; } /** * @return string */ public function toString() { $str = 'DocBlock [ /* DocBlock */ ] {' . "\n\n"; $str .= ' - Tags [' . count($this->tags) . '] {' . "\n"; foreach ($this->tags as $tag) { $str .= ' ' . $tag; } $str .= ' }' . "\n"; $str .= '}' . "\n"; return $str; } /** * Serialize to string * * Required by the Reflector interface * * @return string */ public function __toString() { return $this->toString(); } } src/Reflection/Exception/BadMethodCallException.php000064400000000276144760120040016401 0ustar00getDocComment())) { throw new Exception\InvalidArgumentException(sprintf( '%s does not have a DocBlock', $this->getName() )); } return new DocBlockReflection($comment); } /** * Get start line (position) of function * * @param bool $includeDocComment * @return int */ #[ReturnTypeWillChange] public function getStartLine($includeDocComment = false) { if ($includeDocComment) { if ($this->getDocComment() != '') { return $this->getDocBlock()->getStartLine(); } } return parent::getStartLine(); } /** * Get contents of function * * @param bool $includeDocBlock * @return string */ public function getContents($includeDocBlock = true) { $fileName = $this->getFileName(); if (false === $fileName) { return ''; } $startLine = $this->getStartLine(); $endLine = $this->getEndLine(); // eval'd protect if (preg_match('#\((\d+)\) : eval\(\)\'d code$#', $fileName, $matches)) { $fileName = preg_replace('#\(\d+\) : eval\(\)\'d code$#', '', $fileName); $startLine = $endLine = $matches[1]; } $lines = array_slice( file($fileName, FILE_IGNORE_NEW_LINES), $startLine - 1, $endLine - ($startLine - 1), true ); $functionLine = implode("\n", $lines); $content = ''; if ($this->isClosure()) { preg_match('#function\s*\([^\)]*\)\s*(use\s*\([^\)]+\))?\s*\{(.*\;)?\s*\}#s', $functionLine, $matches); if (isset($matches[0])) { $content = $matches[0]; } } else { $name = substr($this->getName(), strrpos($this->getName(), '\\') + 1); preg_match( '#function\s+' . preg_quote($name) . '\s*\([^\)]*\)\s*{([^{}]+({[^}]+})*[^}]+)?}#', $functionLine, $matches ); if (isset($matches[0])) { $content = $matches[0]; } } $docComment = $this->getDocComment(); return $includeDocBlock && $docComment ? $docComment . "\n" . $content : $content; } /** * Get method prototype * * @param string $format * @return array|string */ public function getPrototype($format = self::PROTOTYPE_AS_ARRAY) { $docBlock = $this->getDocBlock(); $return = $docBlock->getTag('return'); $returnTypes = $return->getTypes(); $returnType = count($returnTypes) > 1 ? implode('|', $returnTypes) : $returnTypes[0]; $prototype = [ 'namespace' => $this->getNamespaceName(), 'name' => substr($this->getName(), strlen($this->getNamespaceName()) + 1), 'return' => $returnType, 'arguments' => [], ]; $parameters = $this->getParameters(); foreach ($parameters as $parameter) { $prototype['arguments'][$parameter->getName()] = [ 'type' => $parameter->detectType(), 'required' => ! $parameter->isOptional(), 'by_ref' => $parameter->isPassedByReference(), 'default' => $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null, ]; } if ($format == self::PROTOTYPE_AS_STRING) { $line = $prototype['return'] . ' ' . $prototype['name'] . '('; $args = []; foreach ($prototype['arguments'] as $name => $argument) { $argsLine = ($argument['type'] ? $argument['type'] . ' ' : '') . ($argument['by_ref'] ? '&' : '') . '$' . $name; if (! $argument['required']) { $argsLine .= ' = ' . var_export($argument['default'], true); } $args[] = $argsLine; } $line .= implode(', ', $args); $line .= ')'; return $line; } return $prototype; } /** * Get function parameters * * @return ParameterReflection[] */ #[ReturnTypeWillChange] public function getParameters() { $phpReflections = parent::getParameters(); $laminasReflections = []; while ($phpReflections && ($phpReflection = array_shift($phpReflections))) { $instance = new ParameterReflection($this->getName(), $phpReflection->getName()); $laminasReflections[] = $instance; unset($phpReflection); } unset($phpReflections); return $laminasReflections; } /** * Get return type tag * * @throws Exception\InvalidArgumentException * @return DocBlockReflection */ public function getReturn() { $docBlock = $this->getDocBlock(); if (! $docBlock->hasTag('return')) { throw new Exception\InvalidArgumentException( 'Function does not specify an @return annotation tag; cannot determine return type' ); } $tag = $docBlock->getTag('return'); return new DocBlockReflection('@return ' . $tag->getDescription()); } /** * Get method body * * @return string|false */ public function getBody() { $fileName = $this->getFileName(); if (false === $fileName) { throw new Exception\InvalidArgumentException( 'Cannot determine internals functions body' ); } $startLine = $this->getStartLine(); $endLine = $this->getEndLine(); // eval'd protect if (preg_match('#\((\d+)\) : eval\(\)\'d code$#', $fileName, $matches)) { $fileName = preg_replace('#\(\d+\) : eval\(\)\'d code$#', '', $fileName); $startLine = $endLine = $matches[1]; } $lines = array_slice( file($fileName, FILE_IGNORE_NEW_LINES), $startLine - 1, $endLine - ($startLine - 1), true ); $functionLine = implode("\n", $lines); $body = false; if ($this->isClosure()) { preg_match('#function\s*\([^\)]*\)\s*(use\s*\([^\)]+\))?\s*\{(.*\;)\s*\}#s', $functionLine, $matches); if (isset($matches[2])) { $body = $matches[2]; } } else { $name = substr($this->getName(), strrpos($this->getName(), '\\') + 1); preg_match('#function\s+' . $name . '\s*\([^\)]*\)\s*{([^{}]+({[^}]+})*[^}]+)}#', $functionLine, $matches); if (isset($matches[1])) { $body = $matches[1]; } } return $body; } /** * @return string */ public function toString() { return $this->__toString(); } /** * Required due to bug in php * * @return string */ public function __toString() { return parent::__toString(); } } src/Reflection/MethodReflection.php000064400000034625144760120040013401 0ustar00getDocComment()) { return false; } return new DocBlockReflection($this); } /** * Get start line (position) of method * * @param bool $includeDocComment * @return int */ #[ReturnTypeWillChange] public function getStartLine($includeDocComment = false) { if ($includeDocComment) { if ($this->getDocComment() != '') { return $this->getDocBlock()->getStartLine(); } } return parent::getStartLine(); } /** * Get reflection of declaring class * * @return ClassReflection */ #[ReturnTypeWillChange] public function getDeclaringClass() { $phpReflection = parent::getDeclaringClass(); $laminasReflection = new ClassReflection($phpReflection->getName()); unset($phpReflection); return $laminasReflection; } /** * Get method prototype * * @param string $format * @return array|string */ #[ReturnTypeWillChange] public function getPrototype($format = self::PROTOTYPE_AS_ARRAY) { $returnType = 'mixed'; $docBlock = $this->getDocBlock(); if ($docBlock) { $return = $docBlock->getTag('return'); $returnTypes = $return->getTypes(); $returnType = count($returnTypes) > 1 ? implode('|', $returnTypes) : $returnTypes[0]; } $declaringClass = $this->getDeclaringClass(); $prototype = [ 'namespace' => $declaringClass->getNamespaceName(), 'class' => substr($declaringClass->getName(), strlen($declaringClass->getNamespaceName()) + 1), 'name' => $this->getName(), 'visibility' => $this->isPublic() ? 'public' : ($this->isPrivate() ? 'private' : 'protected'), 'return' => $returnType, 'arguments' => [], ]; $parameters = $this->getParameters(); foreach ($parameters as $parameter) { $prototype['arguments'][$parameter->getName()] = [ 'type' => $parameter->detectType(), 'required' => ! $parameter->isOptional(), 'by_ref' => $parameter->isPassedByReference(), 'default' => $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null, ]; if ($parameter->isPromoted()) { $prototype['arguments'][$parameter->getName()]['promoted'] = true; if ($parameter->isPublicPromoted()) { $prototype['arguments'][$parameter->getName()]['visibility'] = 'public'; } elseif ($parameter->isProtectedPromoted()) { $prototype['arguments'][$parameter->getName()]['visibility'] = 'protected'; } elseif ($parameter->isPrivatePromoted()) { $prototype['arguments'][$parameter->getName()]['visibility'] = 'private'; } } } if ($format == self::PROTOTYPE_AS_STRING) { $line = $prototype['visibility'] . ' ' . $prototype['return'] . ' ' . $prototype['name'] . '('; $args = []; foreach ($prototype['arguments'] as $name => $argument) { $argsLine = ( array_key_exists('visibility', $argument) ? $argument['visibility'] . ' ' : '' ) . ( $argument['type'] ? $argument['type'] . ' ' : '' ) . ( $argument['by_ref'] ? '&' : '' ) . '$' . $name; if (! $argument['required']) { $argsLine .= ' = ' . var_export($argument['default'], true); } $args[] = $argsLine; } $line .= implode(', ', $args); $line .= ')'; return $line; } return $prototype; } /** * Get all method parameter reflection objects * * @return ParameterReflection[] */ #[ReturnTypeWillChange] public function getParameters() { $phpReflections = parent::getParameters(); $laminasReflections = []; while ($phpReflections && ($phpReflection = array_shift($phpReflections))) { $instance = new ParameterReflection( [$this->getDeclaringClass()->getName(), $this->getName()], $phpReflection->getName() ); $laminasReflections[] = $instance; unset($phpReflection); } unset($phpReflections); return $laminasReflections; } /** * Get method contents * * @param bool $includeDocBlock * @return string */ public function getContents($includeDocBlock = true) { $docComment = $this->getDocComment(); $content = $includeDocBlock && ! empty($docComment) ? $docComment . "\n" : ''; $content .= $this->extractMethodContents(); return $content; } /** * Get method body * * @return string */ public function getBody() { return $this->extractMethodContents(true); } /** * Tokenize method string and return concatenated body * * @param bool $bodyOnly * @return string */ protected function extractMethodContents($bodyOnly = false) { $fileName = $this->getFileName(); if ((class_exists($this->class) && false === $fileName) || ! file_exists($fileName)) { return ''; } $lines = array_slice( file($fileName, FILE_IGNORE_NEW_LINES), $this->getStartLine() - 1, $this->getEndLine() - ($this->getStartLine() - 1), true ); $functionLine = implode("\n", $lines); $tokens = token_get_all(' $token) { $tokenType = is_array($token) ? token_name($token[0]) : $token; $tokenValue = is_array($token) ? $token[1] : $token; switch ($tokenType) { case 'T_FINAL': case 'T_ABSTRACT': case 'T_PUBLIC': case 'T_PROTECTED': case 'T_PRIVATE': case 'T_STATIC': case 'T_FUNCTION': // check to see if we have a valid function // then check if we are inside function and have a closure if ($this->isValidFunction($tokens, $key, $this->getName())) { if ($bodyOnly === false) { //if first instance of tokenType grab prefixed whitespace //and append to body if ($capture === false) { $body .= $this->extractPrefixedWhitespace($tokens, $key); } $body .= $tokenValue; } $capture = true; } else { //closure test if ($firstBrace && $tokenType == 'T_FUNCTION') { $body .= $tokenValue; break; } $capture = false; break; } break; case '{': if ($capture === false) { break; } if ($firstBrace === false) { $firstBrace = true; if ($bodyOnly === true) { break; } } $body .= $tokenValue; break; case '}': if ($capture === false) { break; } //check to see if this is the last brace if ($this->isEndingBrace($tokens, $key)) { //capture the end brace if not bodyOnly if ($bodyOnly === false) { $body .= $tokenValue; } break 2; } $body .= $tokenValue; break; default: if ($capture === false) { break; } // if returning body only wait for first brace before capturing if ($bodyOnly === true && $firstBrace !== true) { break; } $body .= $tokenValue; break; } } //remove ending whitespace and return return rtrim($body); } /** * Take current position and find any whitespace * * @param array $haystack * @param int $position * @return string */ protected function extractPrefixedWhitespace($haystack, $position) { $content = ''; $count = count($haystack); if ($position + 1 == $count) { return $content; } for ($i = $position - 1; $i >= 0; $i--) { $tokenType = is_array($haystack[$i]) ? token_name($haystack[$i][0]) : $haystack[$i]; $tokenValue = is_array($haystack[$i]) ? $haystack[$i][1] : $haystack[$i]; //search only for whitespace if ($tokenType == 'T_WHITESPACE') { $content .= $tokenValue; } else { break; } } return $content; } /** * Test for ending brace * * @param array $haystack * @param int $position * @return bool */ protected function isEndingBrace($haystack, $position) { $count = count($haystack); //advance one position $position += 1; if ($position == $count) { return true; } for ($i = $position; $i < $count; $i++) { $tokenType = is_array($haystack[$i]) ? token_name($haystack[$i][0]) : $haystack[$i]; switch ($tokenType) { case 'T_FINAL': case 'T_ABSTRACT': case 'T_PUBLIC': case 'T_PROTECTED': case 'T_PRIVATE': case 'T_STATIC': return true; case 'T_FUNCTION': // If a function is encountered and that function is not a closure // then return true. otherwise the function is a closure, return false if ($this->isValidFunction($haystack, $i)) { return true; } return false; case '}': case ';': case 'T_BREAK': case 'T_CATCH': case 'T_DO': case 'T_ECHO': case 'T_ELSE': case 'T_ELSEIF': case 'T_EVAL': case 'T_EXIT': case 'T_FINALLY': case 'T_FOR': case 'T_FOREACH': case 'T_GOTO': case 'T_IF': case 'T_INCLUDE': case 'T_INCLUDE_ONCE': case 'T_PRINT': case 'T_STRING': case 'T_STRING_VARNAME': case 'T_THROW': case 'T_USE': case 'T_VARIABLE': case 'T_WHILE': case 'T_YIELD': return false; } } } /** * Test to see if current position is valid function or * closure. Returns true if it's a function and NOT a closure * * @param array $haystack * @param int $position * @param string $functionName * @return bool */ protected function isValidFunction($haystack, $position, $functionName = null) { $isValid = false; $count = count($haystack); for ($i = $position + 1; $i < $count; $i++) { $tokenType = is_array($haystack[$i]) ? token_name($haystack[$i][0]) : $haystack[$i]; $tokenValue = is_array($haystack[$i]) ? $haystack[$i][1] : $haystack[$i]; //check for occurrence of ( or if ($tokenType == 'T_STRING') { //check to see if function name is passed, if so validate against that if ($functionName !== null && $tokenValue != $functionName) { $isValid = false; break; } $isValid = true; break; } elseif ($tokenValue == '(') { break; } } return $isValid; } /** * @return string */ public function toString() { return parent::__toString(); } /** * @return string */ public function __toString() { return parent::__toString(); } } src/Reflection/ParameterReflection.php000064400000010456144760120040014075 0ustar00getName()); unset($phpReflection); return $laminasReflection; } /** * Get class reflection object * * @return null|ClassReflection */ #[ReturnTypeWillChange] public function getClass() { $phpReflectionType = parent::getType(); if ($phpReflectionType === null) { return null; } $laminasReflection = new ClassReflection($phpReflectionType->getName()); unset($phpReflectionType); return $laminasReflection; } /** * Get declaring function reflection object * * @return FunctionReflection|MethodReflection */ #[ReturnTypeWillChange] public function getDeclaringFunction() { $phpReflection = parent::getDeclaringFunction(); if ($phpReflection instanceof ReflectionMethod) { $laminasReflection = new MethodReflection($this->getDeclaringClass()->getName(), $phpReflection->getName()); } else { $laminasReflection = new FunctionReflection($phpReflection->getName()); } unset($phpReflection); return $laminasReflection; } /** * Get parameter type * * @return string|null */ public function detectType() { if ( method_exists($this, 'getType') && null !== ($type = $this->getType()) && $type->isBuiltin() ) { return $type->getName(); } if (null !== $type && $type->getName() === 'self') { return $this->getDeclaringClass()->getName(); } if (($class = $this->getClass()) instanceof ReflectionClass) { return $class->getName(); } $docBlock = $this->getDeclaringFunction()->getDocBlock(); if (! $docBlock instanceof DocBlockReflection) { return null; } /** @var ParamTag[] $params */ $params = $docBlock->getTags('param'); $paramTag = $params[$this->getPosition()] ?? null; $variableName = '$' . $this->getName(); if ($paramTag && ('' === $paramTag->getVariableName() || $variableName === $paramTag->getVariableName())) { return $paramTag->getTypes()[0] ?? ''; } foreach ($params as $param) { if ($param->getVariableName() === $variableName) { return $param->getTypes()[0] ?? ''; } } return null; } /** * @return string */ public function toString() { return parent::__toString(); } /** * @return string */ public function __toString() { return parent::__toString(); } /** @psalm-pure */ public function isPromoted(): bool { if (! method_exists(parent::class, 'isPromoted')) { return false; } return (bool) parent::isPromoted(); } public function isPublicPromoted(): bool { return $this->isPromoted() && $this->getDeclaringClass() ->getProperty($this->getName()) ->getModifiers() & ReflectionProperty::IS_PUBLIC; } public function isProtectedPromoted(): bool { return $this->isPromoted() && $this->getDeclaringClass() ->getProperty($this->getName()) ->getModifiers() & ReflectionProperty::IS_PROTECTED; } public function isPrivatePromoted(): bool { return $this->isPromoted() && $this->getDeclaringClass() ->getProperty($this->getName()) ->getModifiers() & ReflectionProperty::IS_PRIVATE; } } src/Reflection/PropertyReflection.php000064400000002313144760120040013772 0ustar00getName()); unset($phpReflection); return $laminasReflection; } /** * Get DocBlock comment * * @return string|false False if no DocBlock defined */ #[ReturnTypeWillChange] public function getDocComment() { return parent::getDocComment(); } /** * @return false|DocBlockReflection */ public function getDocBlock() { if (! ($docComment = $this->getDocComment())) { return false; } return new DocBlockReflection($docComment); } /** * @return string */ public function toString() { return $this->__toString(); } } src/Reflection/ReflectionInterface.php000064400000000377144760120040014056 0ustar00docComment = $docComment; } /** * @return string */ public function getShortDescription() { $this->scan(); return $this->shortDescription; } /** * @return string */ public function getLongDescription() { $this->scan(); return $this->longDescription; } /** * @return array */ public function getTags() { $this->scan(); return $this->tags; } /** * @return void */ protected function scan() { if ($this->isScanned) { return; } $mode = 1; $tokens = $this->tokenize(); $tagIndex = null; reset($tokens); SCANNER_TOP: $token = current($tokens); switch ($token[0]) { case 'DOCBLOCK_NEWLINE': if ($this->shortDescription != '' && $tagIndex === null) { $mode = 2; } else { $this->longDescription .= $token[1]; } goto SCANNER_CONTINUE; //goto no break needed case 'DOCBLOCK_WHITESPACE': case 'DOCBLOCK_TEXT': if ($tagIndex !== null) { $this->tags[$tagIndex]['value'] .= $this->tags[$tagIndex]['value'] == '' ? $token[1] : ' ' . $token[1]; goto SCANNER_CONTINUE; } elseif ($mode <= 2) { if ($mode == 1) { $this->shortDescription .= $token[1]; } else { $this->longDescription .= $token[1]; } goto SCANNER_CONTINUE; } //gotos no break needed case 'DOCBLOCK_TAG': array_push($this->tags, [ 'name' => $token[1], 'value' => '', ]); end($this->tags); $tagIndex = key($this->tags); $mode = 3; goto SCANNER_CONTINUE; //goto no break needed case 'DOCBLOCK_COMMENTEND': goto SCANNER_END; } SCANNER_CONTINUE: if (next($tokens) === false) { goto SCANNER_END; } goto SCANNER_TOP; SCANNER_END: $this->shortDescription = trim($this->shortDescription); $this->longDescription = trim($this->longDescription); $this->isScanned = true; } /** * @phpcs:disable Generic.Formatting.MultipleStatementAlignment.NotSame * @return array */ protected function tokenize() { static $CONTEXT_INSIDE_DOCBLOCK = 0x01; static $CONTEXT_INSIDE_ASTERISK = 0x02; $context = 0x00; $stream = $this->docComment; $streamIndex = null; $tokens = []; $tokenIndex = null; $currentChar = null; $currentWord = null; $currentLine = null; $MACRO_STREAM_ADVANCE_CHAR = function ($positionsForward = 1) use ( &$stream, &$streamIndex, &$currentChar, &$currentWord, &$currentLine ) { $positionsForward = $positionsForward > 0 ? $positionsForward : 1; $streamIndex = $streamIndex === null ? 0 : $streamIndex + $positionsForward; if (! isset($stream[$streamIndex])) { $currentChar = false; return false; } $currentChar = $stream[$streamIndex]; $matches = []; $currentLine = preg_match('#(.*?)\r?\n#', $stream, $matches, 0, $streamIndex) === 1 ? $matches[1] : substr($stream, $streamIndex); if ($currentChar === ' ') { $currentWord = preg_match('#( +)#', $currentLine, $matches) === 1 ? $matches[1] : $currentLine; } else { $currentWord = ($matches = strpos($currentLine, ' ')) !== false ? substr($currentLine, 0, $matches) : $currentLine; } return $currentChar; }; $MACRO_STREAM_ADVANCE_WORD = function () use (&$currentWord, &$MACRO_STREAM_ADVANCE_CHAR) { return $MACRO_STREAM_ADVANCE_CHAR(strlen($currentWord)); }; $MACRO_STREAM_ADVANCE_LINE = function () use (&$currentLine, &$MACRO_STREAM_ADVANCE_CHAR) { return $MACRO_STREAM_ADVANCE_CHAR(strlen($currentLine)); }; $MACRO_TOKEN_ADVANCE = function () use (&$tokenIndex, &$tokens) { $tokenIndex = $tokenIndex === null ? 0 : $tokenIndex + 1; $tokens[$tokenIndex] = ['DOCBLOCK_UNKNOWN', '']; }; $MACRO_TOKEN_SET_TYPE = function ($type) use (&$tokenIndex, &$tokens) { $tokens[$tokenIndex][0] = $type; }; $MACRO_TOKEN_APPEND_CHAR = function () use (&$currentChar, &$tokens, &$tokenIndex) { $tokens[$tokenIndex][1] .= $currentChar; }; $MACRO_TOKEN_APPEND_WORD = function () use (&$currentWord, &$tokens, &$tokenIndex) { $tokens[$tokenIndex][1] .= $currentWord; }; $MACRO_TOKEN_APPEND_WORD_PARTIAL = function ($length) use (&$currentWord, &$tokens, &$tokenIndex) { $tokens[$tokenIndex][1] .= substr($currentWord, 0, $length); }; $MACRO_TOKEN_APPEND_LINE = function () use (&$currentLine, &$tokens, &$tokenIndex) { $tokens[$tokenIndex][1] .= $currentLine; }; $MACRO_STREAM_ADVANCE_CHAR(); $MACRO_TOKEN_ADVANCE(); TOKENIZER_TOP: if ($context === 0x00 && $currentChar === '/' && $currentWord === '/**') { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_COMMENTSTART'); $MACRO_TOKEN_APPEND_WORD(); $MACRO_TOKEN_ADVANCE(); $context |= $CONTEXT_INSIDE_DOCBLOCK; $context |= $CONTEXT_INSIDE_ASTERISK; if ($MACRO_STREAM_ADVANCE_WORD() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } if ($context & $CONTEXT_INSIDE_DOCBLOCK && $currentWord === '*/') { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_COMMENTEND'); $MACRO_TOKEN_APPEND_WORD(); $MACRO_TOKEN_ADVANCE(); $context &= ~$CONTEXT_INSIDE_DOCBLOCK; if ($MACRO_STREAM_ADVANCE_WORD() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } if ($currentChar === ' ' || $currentChar === "\t") { $MACRO_TOKEN_SET_TYPE( $context & $CONTEXT_INSIDE_ASTERISK ? 'DOCBLOCK_WHITESPACE' : 'DOCBLOCK_WHITESPACE_INDENT' ); $MACRO_TOKEN_APPEND_WORD(); $MACRO_TOKEN_ADVANCE(); if ($MACRO_STREAM_ADVANCE_WORD() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } if ($currentChar === '*') { if (($context & $CONTEXT_INSIDE_DOCBLOCK) && ($context & $CONTEXT_INSIDE_ASTERISK)) { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_TEXT'); } else { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_ASTERISK'); $context |= $CONTEXT_INSIDE_ASTERISK; } $MACRO_TOKEN_APPEND_CHAR(); $MACRO_TOKEN_ADVANCE(); if ($MACRO_STREAM_ADVANCE_CHAR() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } if ($currentChar === '@') { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_TAG'); $MACRO_TOKEN_APPEND_WORD(); $MACRO_TOKEN_ADVANCE(); if ($MACRO_STREAM_ADVANCE_WORD() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } if ($currentChar === "\n") { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_NEWLINE'); $MACRO_TOKEN_APPEND_CHAR(); $MACRO_TOKEN_ADVANCE(); $context &= ~$CONTEXT_INSIDE_ASTERISK; if ($MACRO_STREAM_ADVANCE_CHAR() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } $MACRO_TOKEN_SET_TYPE('DOCBLOCK_TEXT'); $MACRO_TOKEN_APPEND_LINE(); $MACRO_TOKEN_ADVANCE(); if ($MACRO_STREAM_ADVANCE_LINE() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; TOKENIZER_END: array_pop($tokens); return $tokens; } }